1 00:00:06,541 --> 00:00:08,910 - [Instructor] Here we'll review infrastructure as code 2 00:00:08,910 --> 00:00:12,003 with AWS CloudFormation. 3 00:00:12,003 --> 00:00:14,434 One of the most powerful things, 4 00:00:14,434 --> 00:00:16,063 and I think one of the things that 5 00:00:16,063 --> 00:00:20,282 really sets Amazon Web Services apart from other providers, 6 00:00:20,282 --> 00:00:24,153 is the ability to think of our infrastructure as code 7 00:00:24,153 --> 00:00:26,646 to configure our infrastructure 8 00:00:26,646 --> 00:00:30,249 by writing not only scripts, 9 00:00:30,249 --> 00:00:33,734 but writing things like CloudFormation templates. 10 00:00:33,734 --> 00:00:38,507 So, CloudFormation is a solution to a particular problem, 11 00:00:38,507 --> 00:00:40,969 and that is that our architectures 12 00:00:40,969 --> 00:00:42,710 can often be very complex. 13 00:00:42,710 --> 00:00:45,002 There are often a lot of moving parts 14 00:00:45,002 --> 00:00:46,693 when you really zoom out and look, 15 00:00:46,693 --> 00:00:50,008 and you'll see that we have virtual private clouds, 16 00:00:50,008 --> 00:00:52,376 we have subnets and route tables 17 00:00:52,376 --> 00:00:54,418 and network access control lists, 18 00:00:54,418 --> 00:00:57,785 security groups, EC2 instances of various types 19 00:00:57,785 --> 00:01:00,410 and various sizes doing various different jobs, 20 00:01:00,410 --> 00:01:02,911 we have databases and DynamoDB tables. 21 00:01:02,911 --> 00:01:04,320 The list goes on. 22 00:01:04,320 --> 00:01:07,335 There are so many resources that need to be created 23 00:01:07,335 --> 00:01:11,502 and managed, and doing these manually are challenging 24 00:01:13,513 --> 00:01:15,606 because if we architect something, 25 00:01:15,606 --> 00:01:17,696 if we draw it out in a diagram, 26 00:01:17,696 --> 00:01:20,682 we have to know that it's reliable. 27 00:01:20,682 --> 00:01:22,954 We have to know that it was created 28 00:01:22,954 --> 00:01:25,538 exactly the way that we designed it. 29 00:01:25,538 --> 00:01:29,046 And then, of course, comes the issue of reproducibility. 30 00:01:29,046 --> 00:01:32,194 If we want to take that environment, 31 00:01:32,194 --> 00:01:33,957 that particular architecture 32 00:01:33,957 --> 00:01:38,127 and create it in a development, a testing, 33 00:01:38,127 --> 00:01:40,228 a staging, a production environment, 34 00:01:40,228 --> 00:01:42,414 we're looking at doing that manually not once 35 00:01:42,414 --> 00:01:44,652 but two, three, four times or more. 36 00:01:44,652 --> 00:01:48,639 What if we wanted to take that architecture 37 00:01:48,639 --> 00:01:50,653 and roll it out to multiple regions 38 00:01:50,653 --> 00:01:53,396 so that we can serve a broader audience. 39 00:01:53,396 --> 00:01:55,093 Again, it's one thing to do it once, 40 00:01:55,093 --> 00:01:58,802 it's quite another to do it two, three, four or more times. 41 00:01:58,802 --> 00:02:01,736 And then, of course, comes the issue of documentation. 42 00:02:01,736 --> 00:02:05,903 By having all of this handled by a template, by a script, 43 00:02:07,184 --> 00:02:09,096 then the template or script becomes 44 00:02:09,096 --> 00:02:12,055 somewhat self-documenting. 45 00:02:12,055 --> 00:02:17,021 Now, yes, we can do these things with just scripts. 46 00:02:17,021 --> 00:02:19,323 We could do them with Bash shell scripts, 47 00:02:19,323 --> 00:02:21,701 leveraging the Amazon command line tools. 48 00:02:21,701 --> 00:02:24,068 We could to them with a programming language 49 00:02:24,068 --> 00:02:27,876 such as Python, leveraging the boto libraries. 50 00:02:27,876 --> 00:02:29,642 But the challenges with scripts 51 00:02:29,642 --> 00:02:32,787 could be dependencies and parallelization. 52 00:02:32,787 --> 00:02:36,320 We need to know that certain resources have to come first. 53 00:02:36,320 --> 00:02:39,765 Before you launch an EC2 instance into a VPC, 54 00:02:39,765 --> 00:02:42,040 you first have to create a subnet; 55 00:02:42,040 --> 00:02:43,442 and before you create a subnet, 56 00:02:43,442 --> 00:02:45,097 you have to create the VPC. 57 00:02:45,097 --> 00:02:49,169 So your scripts need to know the appropriate order 58 00:02:49,169 --> 00:02:52,172 in which things need to be created. 59 00:02:52,172 --> 00:02:53,859 So the solution to all of that, 60 00:02:53,859 --> 00:02:57,692 the solution to the challenges of a manual process, 61 00:02:57,692 --> 00:03:00,199 the challenges of human error factors, 62 00:03:00,199 --> 00:03:03,490 the solution to the challenges with scripts 63 00:03:03,490 --> 00:03:06,740 is to automate with AWS CloudFormation. 64 00:03:07,607 --> 00:03:10,547 CloudFormation gives us 65 00:03:10,547 --> 00:03:12,879 the ability to write what we call templates, 66 00:03:12,879 --> 00:03:16,246 which are just JSON-formatted text files 67 00:03:16,246 --> 00:03:20,462 that we can and should put into source control. 68 00:03:20,462 --> 00:03:25,134 We then upload those to the CloudFormation Engine, 69 00:03:25,134 --> 00:03:28,445 which is responsible for processing that template 70 00:03:28,445 --> 00:03:32,948 and creating and/or updating or deleting resources. 71 00:03:32,948 --> 00:03:36,021 The CloudFormation Engine inherently knows 72 00:03:36,021 --> 00:03:38,621 the order in which things should be built. 73 00:03:38,621 --> 00:03:42,560 It already knows that it should build the VPC first 74 00:03:42,560 --> 00:03:44,289 before it builds the subnet, 75 00:03:44,289 --> 00:03:45,895 before it launches the EC2 instance. 76 00:03:45,895 --> 00:03:48,215 It just knows a lot of those things. 77 00:03:48,215 --> 00:03:51,402 We don't have to worry about that order. 78 00:03:51,402 --> 00:03:54,561 But in cases where it get ambiguous, 79 00:03:54,561 --> 00:03:58,093 such as launching a database in an EC2 instance, 80 00:03:58,093 --> 00:04:01,334 we do have control over the order. 81 00:04:01,334 --> 00:04:05,501 Once we upload a template to the CloudFormation Engine, 82 00:04:07,358 --> 00:04:11,373 and the CloudFormation Engine has created these resources, 83 00:04:11,373 --> 00:04:14,814 we can manage the collection of those resources 84 00:04:14,814 --> 00:04:17,523 under what we call the stack; 85 00:04:17,523 --> 00:04:20,801 that is, the larger umbrella of all of those resources. 86 00:04:20,801 --> 00:04:23,904 So let's say that we have 87 00:04:23,904 --> 00:04:27,754 a very complex architecture with VPCs, subnets, 88 00:04:27,754 --> 00:04:32,162 EC2 instances, load balancers, and so on and so forth. 89 00:04:32,162 --> 00:04:34,685 If we reach a point where we don't 90 00:04:34,685 --> 00:04:37,560 need that infrastructure anymore, 91 00:04:37,560 --> 00:04:40,982 then we can just go in and delete the stack, 92 00:04:40,982 --> 00:04:42,340 and by deleting the stack, 93 00:04:42,340 --> 00:04:44,767 we then delete all of those resources. 94 00:04:44,767 --> 00:04:46,126 That's a whole lot easier 95 00:04:46,126 --> 00:04:49,762 than going in and manually picking through your environment 96 00:04:49,762 --> 00:04:51,264 and worrying whether or not 97 00:04:51,264 --> 00:04:54,799 you're deleting the right thing versus the wrong thing. 98 00:04:54,799 --> 00:04:57,342 So, with CloudFormation, 99 00:04:57,342 --> 00:05:01,323 we have what we would consider declarative programming. 100 00:05:01,323 --> 00:05:03,775 Imperative programming is concerned 101 00:05:03,775 --> 00:05:05,767 with the exact order of things. 102 00:05:05,767 --> 00:05:08,619 You're saying do this step, then do that and do that, 103 00:05:08,619 --> 00:05:10,246 you're actually telling it what to do 104 00:05:10,246 --> 00:05:11,634 and how to do it. 105 00:05:11,634 --> 00:05:13,196 With declarative programming, 106 00:05:13,196 --> 00:05:16,717 we're just declaring the resources that we want, 107 00:05:16,717 --> 00:05:19,732 the ways in which we want those resources connected, 108 00:05:19,732 --> 00:05:22,880 and we allow the CloudFormation Engine 109 00:05:22,880 --> 00:05:26,231 to worry about how those get built 110 00:05:26,231 --> 00:05:28,377 and in what order those get built. 111 00:05:28,377 --> 00:05:30,394 And again, these templates, 112 00:05:30,394 --> 00:05:32,438 because they are just JSON text files, 113 00:05:32,438 --> 00:05:35,363 they should be stored in source control, 114 00:05:35,363 --> 00:05:36,978 and I can speak from personal experience 115 00:05:36,978 --> 00:05:40,317 that having your CloudFormation templates 116 00:05:40,317 --> 00:05:43,594 under source control not only makes working with a team 117 00:05:43,594 --> 00:05:44,767 a whole lot easier, 118 00:05:44,767 --> 00:05:47,086 it makes rolling back to a previous version 119 00:05:47,086 --> 00:05:47,980 a whole lot easier, 120 00:05:47,980 --> 00:05:49,538 it makes it a predictable place 121 00:05:49,538 --> 00:05:52,925 to know where you can find that particular template. 122 00:05:52,925 --> 00:05:56,801 With CloudFormation, we can nest our templates. 123 00:05:56,801 --> 00:05:59,862 We can put one template inside of another one, 124 00:05:59,862 --> 00:06:02,720 and we can write that template once 125 00:06:02,720 --> 00:06:05,761 and then deploy it to numerous applications. 126 00:06:05,761 --> 00:06:09,118 Perhaps we have an architecture that we want to mirror 127 00:06:09,118 --> 00:06:12,452 across development, testing, staging 128 00:06:12,452 --> 00:06:14,110 and production environments. 129 00:06:14,110 --> 00:06:16,100 And so we can write that template once 130 00:06:16,100 --> 00:06:19,476 and deploy it many times. 131 00:06:19,476 --> 00:06:21,775 Now, another nice thing about CloudFormation 132 00:06:21,775 --> 00:06:25,340 is that it does not impose any particular model 133 00:06:25,340 --> 00:06:27,025 for development and operations. 134 00:06:27,025 --> 00:06:29,403 It just gives us the absolute flexibility 135 00:06:29,403 --> 00:06:33,320 to create our architectures the way we see fit. 136 00:06:35,386 --> 00:06:38,762 Within a template, we will declare certain things 137 00:06:38,762 --> 00:06:40,409 such as parameters 138 00:06:40,409 --> 00:06:43,251 or what we could also describe as variables. 139 00:06:43,251 --> 00:06:46,962 We'll describe the resources that we want to create, 140 00:06:46,962 --> 00:06:50,212 such as VPCs and EC2 and RDS instances. 141 00:06:51,596 --> 00:06:54,812 We can also create what we call mappings. 142 00:06:54,812 --> 00:06:56,919 These are another form of variable 143 00:06:56,919 --> 00:07:01,228 that help us map one value to another value. 144 00:07:01,228 --> 00:07:02,743 And then, of course, we can control 145 00:07:02,743 --> 00:07:04,937 the output of that template as well. 146 00:07:04,937 --> 00:07:09,477 So, perhaps we want to create a load balancer 147 00:07:09,477 --> 00:07:11,919 and then, from that, once that's created, 148 00:07:11,919 --> 00:07:13,880 we want to get some of the attributes 149 00:07:13,880 --> 00:07:16,963 of that load balancer back as output. 150 00:07:18,256 --> 00:07:20,432 So let's take a look at an example template. 151 00:07:20,432 --> 00:07:22,850 Again, this JSON, as you can see 152 00:07:22,850 --> 00:07:25,859 by the curly braces and the key value pairs 153 00:07:25,859 --> 00:07:27,155 that we see here. 154 00:07:27,155 --> 00:07:31,173 One parameter might be the CIDR range, 155 00:07:31,173 --> 00:07:34,125 so, at the time we launched this particular template, 156 00:07:34,125 --> 00:07:37,415 any parameters that we have listed here, 157 00:07:37,415 --> 00:07:42,363 this right here, Cidr would be name of that parameter. 158 00:07:42,363 --> 00:07:45,780 When we upload this into the AWS console, 159 00:07:48,220 --> 00:07:50,611 we will be presented with a text field 160 00:07:50,611 --> 00:07:53,278 with this particular text, Cidr, 161 00:07:54,162 --> 00:07:56,068 off to the left as the label, 162 00:07:56,068 --> 00:07:59,247 and it will give us a place to type in a value, 163 00:07:59,247 --> 00:08:03,594 and that particular text box will be prepopulated 164 00:08:03,594 --> 00:08:06,844 with this value here, with the default. 165 00:08:07,787 --> 00:08:11,429 And so, we would use this parameter, 166 00:08:11,429 --> 00:08:13,982 you'll notice here, we're going to use this parameter later 167 00:08:13,982 --> 00:08:16,980 as a reference in our resources. 168 00:08:16,980 --> 00:08:19,559 Our resources, again, are the very things 169 00:08:19,559 --> 00:08:23,704 that we want CloudFormation to create for us. 170 00:08:23,704 --> 00:08:26,461 In this example, we're asking CloudFormation 171 00:08:26,461 --> 00:08:30,044 to create a VPC, and within its properties, 172 00:08:31,915 --> 00:08:35,501 we're going to say that the Cidr block of that VPC 173 00:08:35,501 --> 00:08:38,577 should be pulled or referenced 174 00:08:38,577 --> 00:08:42,831 to the Cidr parameter that specified up here. 175 00:08:42,831 --> 00:08:47,196 So that gives us the ability to, 176 00:08:47,196 --> 00:08:50,613 instead of hard-coding our IP range here, 177 00:08:51,473 --> 00:08:54,300 it allows that particular template to be flexible 178 00:08:54,300 --> 00:08:58,211 so that we can launch the same exact infrastructure, 179 00:08:58,211 --> 00:09:01,914 perhaps into multiple CIDR ranges. 180 00:09:01,914 --> 00:09:04,646 Perhaps we have a load-balanced application 181 00:09:04,646 --> 00:09:08,633 that needs to serve different applications, 182 00:09:08,633 --> 00:09:11,800 so each one gets their own CIDR range. 183 00:09:13,460 --> 00:09:17,624 So this is just a little bit of an example 184 00:09:17,624 --> 00:09:20,224 of the possibilities with CloudFormation. 185 00:09:20,224 --> 00:09:22,645 These templates can get incredibly complex, 186 00:09:22,645 --> 00:09:26,114 but it makes creating complex infrastructures 187 00:09:26,114 --> 00:09:28,136 so much easier by allowing 188 00:09:28,136 --> 00:09:32,081 one service to handle all of the details 189 00:09:32,081 --> 00:09:34,638 of the creation of these resources for you. 190 00:09:34,638 --> 00:09:38,638 So that is AWS CloudFormation.