1 00:00:00,450 --> 00:00:02,400 - [Raf] Hi there, I'm Raf. 2 00:00:02,400 --> 00:00:05,010 In the previous videos, Alana started the conversation 3 00:00:05,010 --> 00:00:06,520 about continuous integration, 4 00:00:06,520 --> 00:00:08,420 and the AWS Services you can use 5 00:00:08,420 --> 00:00:10,510 to leverage a way to develop something 6 00:00:10,510 --> 00:00:13,400 in a collaborative manner, from the source code 7 00:00:13,400 --> 00:00:15,480 to build and test. 8 00:00:15,480 --> 00:00:17,950 She also talked about CodePipeline, 9 00:00:17,950 --> 00:00:20,010 the AWS service that can be used 10 00:00:20,010 --> 00:00:22,660 to orchestrate your continuous integration workflow, 11 00:00:22,660 --> 00:00:25,150 stitching together in CodeCommit and CodeBuild, 12 00:00:25,150 --> 00:00:27,040 to automatically have the build done, 13 00:00:27,040 --> 00:00:30,740 and tested according to the pushes in the Git repository. 14 00:00:30,740 --> 00:00:33,840 In this video, I am going to talk about the next steps, 15 00:00:33,840 --> 00:00:36,190 to move your pipeline to the next level, 16 00:00:36,190 --> 00:00:39,580 with the usage of infrastructure as code. 17 00:00:39,580 --> 00:00:41,850 Logging in the AWS Management Console 18 00:00:41,850 --> 00:00:44,250 and manually provisioning your environments 19 00:00:44,250 --> 00:00:46,870 is not ideal due to many reasons. 20 00:00:46,870 --> 00:00:49,590 It gets easier if you are the only one managing 21 00:00:49,590 --> 00:00:52,260 a simple environment in your personal account, 22 00:00:52,260 --> 00:00:54,680 but as you start working professionally with it, 23 00:00:54,680 --> 00:00:56,290 as a part of our DevOps team, 24 00:00:56,290 --> 00:00:58,860 it rapidly becomes more challenging. 25 00:00:58,860 --> 00:01:01,650 Automation is key, and infrastructure as code 26 00:01:01,650 --> 00:01:04,490 is the process of managing and provisioning environments 27 00:01:04,490 --> 00:01:07,450 through code in a declarative way. 28 00:01:07,450 --> 00:01:10,290 Let me ask Alana something, and you will understand 29 00:01:10,290 --> 00:01:13,070 what I mean by using the word declarative here, 30 00:01:13,070 --> 00:01:15,970 in the infrastructure-as-code context. 31 00:01:15,970 --> 00:01:18,720 Alana, I have something to ask you. 32 00:01:18,720 --> 00:01:20,700 What do you do when you go to a coffee shop, 33 00:01:20,700 --> 00:01:22,450 looking for an espresso? 34 00:01:22,450 --> 00:01:24,950 Option A. You ask the cashier, 35 00:01:24,950 --> 00:01:27,217 I would like to have an espresso please, 36 00:01:27,217 --> 00:01:30,641 or option B. You start giving detailed instructions 37 00:01:30,641 --> 00:01:33,383 to the barista, in terms of what they should do 38 00:01:33,383 --> 00:01:35,247 in order to get your espresso. 39 00:01:35,247 --> 00:01:36,950 Like, you start giving instructions like, 40 00:01:36,950 --> 00:01:38,170 getting the coffee beans, 41 00:01:38,170 --> 00:01:40,890 grinding with a specific granularity, tamper, 42 00:01:40,890 --> 00:01:42,120 put in the portafilter, 43 00:01:42,120 --> 00:01:45,003 turn on the machine for 25 seconds, et cetera. 44 00:01:46,640 --> 00:01:48,814 - [Alana] Well, if the barista is capable of 45 00:01:48,814 --> 00:01:52,614 making an espresso, I would definitely prefer option A. 46 00:01:52,614 --> 00:01:54,240 - [Raf] So do I, right? 47 00:01:54,240 --> 00:01:56,790 That's what I mean by using infrastructure as code, 48 00:01:56,790 --> 00:01:58,980 in a declarative way. 49 00:01:58,980 --> 00:02:01,160 The reason why I am saying all of this, 50 00:02:01,160 --> 00:02:04,200 is because since you can interact with AWS services 51 00:02:04,200 --> 00:02:08,290 programmatically, by using the AWS SDKs or the AWS CLI, 52 00:02:08,290 --> 00:02:11,740 you can create your infrastructure through shell scripts, 53 00:02:11,740 --> 00:02:13,580 although it gives you more control, 54 00:02:13,580 --> 00:02:17,280 because you are exactly specifying the very fine details, 55 00:02:17,280 --> 00:02:18,320 of what you want. 56 00:02:18,320 --> 00:02:20,010 It is way less convenient, 57 00:02:20,010 --> 00:02:22,530 because you also need to concern with complexity, 58 00:02:22,530 --> 00:02:25,970 such as managing changes, auditing, rollbacks, 59 00:02:25,970 --> 00:02:28,670 in case of failures, infrastructure, consistency, 60 00:02:28,670 --> 00:02:29,803 and much more. 61 00:02:31,610 --> 00:02:33,880 AWS CloudFormation is a service 62 00:02:33,880 --> 00:02:36,030 that allows you to declare your infrastructure 63 00:02:36,030 --> 00:02:37,630 in a text file. 64 00:02:37,630 --> 00:02:40,230 In that file, you say what you want, 65 00:02:40,230 --> 00:02:41,550 pass it to the service, 66 00:02:41,550 --> 00:02:43,300 and CloudFormation brews the coffee, 67 00:02:43,300 --> 00:02:45,840 I mean, the environment, for you. 68 00:02:45,840 --> 00:02:49,400 This file can be authored in JSON or YAML. 69 00:02:49,400 --> 00:02:50,950 Once you input a file 70 00:02:50,950 --> 00:02:53,400 and ask CloudFormation to create a stack, 71 00:02:53,400 --> 00:02:56,300 CloudFormation starts creating the infrastructure for you. 72 00:02:57,140 --> 00:02:58,870 In the CloudFormation nomenclature, 73 00:02:58,870 --> 00:03:00,960 we call that file a template, 74 00:03:00,960 --> 00:03:03,453 and infrastructure components, a stack. 75 00:03:04,700 --> 00:03:07,790 So, a template is something you define, 76 00:03:07,790 --> 00:03:11,900 and a stack is infrastructure that actually gets created. 77 00:03:11,900 --> 00:03:15,320 This is what a CloudFormation template looks like. 78 00:03:15,320 --> 00:03:17,490 The Resources part is where you declare 79 00:03:17,490 --> 00:03:19,940 what AWS services you want. 80 00:03:19,940 --> 00:03:21,960 If you want to create an S3 bucket, 81 00:03:21,960 --> 00:03:26,153 you can declare a resource of the type, AWS::S3::Bucket. 82 00:03:27,030 --> 00:03:28,470 The CloudFormation documentation 83 00:03:28,470 --> 00:03:30,760 has a list of the supported properties 84 00:03:30,760 --> 00:03:34,320 for every single AWS service that supports CloudFormation, 85 00:03:34,320 --> 00:03:36,123 which has almost every service. 86 00:03:37,060 --> 00:03:38,397 This is the documentation page 87 00:03:38,397 --> 00:03:41,530 for the resource AWS::S3::Bucket. 88 00:03:41,530 --> 00:03:45,480 I prefer using YAML because it's simple for me to read, 89 00:03:45,480 --> 00:03:47,810 and you can see that a bucket can be created 90 00:03:47,810 --> 00:03:50,833 simply by specifying the bucket name as a property. 91 00:03:52,190 --> 00:03:54,448 All right, a CloudFormation template 92 00:03:54,448 --> 00:03:58,100 can be as simple as that, just creating a bucket. 93 00:03:58,100 --> 00:03:59,740 Pretty simple. 94 00:03:59,740 --> 00:04:01,960 You can submit that to CloudFormation, 95 00:04:01,960 --> 00:04:04,630 and ask it to create a stack out of it. 96 00:04:04,630 --> 00:04:07,100 Once the stack finishes with no errors, 97 00:04:07,100 --> 00:04:08,780 you will have the bucket created, 98 00:04:08,780 --> 00:04:10,653 as declared in the template. 99 00:04:11,730 --> 00:04:14,560 Now, here comes one of the coolest part. 100 00:04:14,560 --> 00:04:16,750 What if, in addition to that S3 bucket, 101 00:04:16,750 --> 00:04:20,120 you also want to have a DynamoDB table? 102 00:04:20,120 --> 00:04:22,778 Pretty simple, you just edit the template, 103 00:04:22,778 --> 00:04:25,811 add the resource, AWS::DynamoDB::Table, 104 00:04:25,811 --> 00:04:28,070 and submit it again to CloudFormation. 105 00:04:28,070 --> 00:04:31,453 But this time, you will do an update stack operation. 106 00:04:32,790 --> 00:04:34,680 Update stacks are awesome. 107 00:04:34,680 --> 00:04:36,980 CloudFormation receives the updates from the template, 108 00:04:36,980 --> 00:04:39,570 and says: now, in addition to the bucket, 109 00:04:39,570 --> 00:04:41,550 the user wants a DynamoDB table. 110 00:04:41,550 --> 00:04:43,450 Let me create it, and voila. 111 00:04:43,450 --> 00:04:45,800 It updates the infrastructure for you. 112 00:04:45,800 --> 00:04:47,810 Same thing with deletions. 113 00:04:47,810 --> 00:04:50,340 If you want to remove something from your infrastructure, 114 00:04:50,340 --> 00:04:53,590 you can remove from the template and do an update stack. 115 00:04:53,590 --> 00:04:55,620 CloudFormation will calculate the delta, 116 00:04:55,620 --> 00:04:57,330 and make the infrastructure match 117 00:04:57,330 --> 00:04:59,123 what is desired on the template. 118 00:05:00,400 --> 00:05:03,830 - [Alana] But Raf, S3 buckets and DynamoDB tables 119 00:05:03,830 --> 00:05:06,380 may contain data from your users. 120 00:05:06,380 --> 00:05:07,700 What if you want to delete a stack, 121 00:05:07,700 --> 00:05:10,500 but retain some of the resources? 122 00:05:10,500 --> 00:05:11,700 Because when you delete a stack, 123 00:05:11,700 --> 00:05:13,741 CloudFormation will erase all the resources 124 00:05:13,741 --> 00:05:15,981 associated with the stack, 125 00:05:15,981 --> 00:05:17,770 and sometimes you want to erase some resources, 126 00:05:17,770 --> 00:05:19,713 but not others, right? 127 00:05:21,350 --> 00:05:22,420 - [Raf] That's right. 128 00:05:22,420 --> 00:05:24,530 When you delete a stack, CloudFormation 129 00:05:24,530 --> 00:05:27,730 erases every resource defined on that stack. 130 00:05:27,730 --> 00:05:29,720 And that's why some of the resources 131 00:05:29,720 --> 00:05:32,763 allow you to define an action when you delete this stack. 132 00:05:33,850 --> 00:05:37,490 For example, this S3 bucket has a deletion policy 133 00:05:37,490 --> 00:05:39,470 defined as Retain, 134 00:05:39,470 --> 00:05:41,550 which will make CloudFormation reserve 135 00:05:41,550 --> 00:05:44,910 that specific resource upon stack deletion. 136 00:05:44,910 --> 00:05:47,500 The usage of this is actually a best practice 137 00:05:47,500 --> 00:05:48,990 every time you define a resource 138 00:05:48,990 --> 00:05:52,670 that will be used as a database, like an RDS instance, 139 00:05:52,670 --> 00:05:55,563 an Elasticsearch cluster, or a DynamoDB table. 140 00:05:56,820 --> 00:05:58,880 CloudFormation is very powerful. 141 00:05:58,880 --> 00:06:02,680 We could spend hours and hours talking about its features, 142 00:06:02,680 --> 00:06:05,150 but we have to move on in our DevOps journey. 143 00:06:05,150 --> 00:06:07,300 So I strongly recommend you taking a look 144 00:06:07,300 --> 00:06:09,650 at the CloudFormation documentation. 145 00:06:09,650 --> 00:06:11,620 Having the ability to write a template 146 00:06:11,620 --> 00:06:14,703 and have the infrastructure created is super powerful. 147 00:06:15,990 --> 00:06:19,170 Since we are talking about having a CI/CD pipeline, 148 00:06:19,170 --> 00:06:20,980 you can have CloudFormation templates, 149 00:06:20,980 --> 00:06:22,600 in a CodeCommit repository, 150 00:06:22,600 --> 00:06:25,259 and whenever you do a push with a change, 151 00:06:25,259 --> 00:06:27,650 CodePipeline orchestrates the environment change 152 00:06:27,650 --> 00:06:31,170 by executing an update stack as part of the deployment. 153 00:06:31,170 --> 00:06:33,140 When we start doing this practice, 154 00:06:33,140 --> 00:06:36,090 we have developers operating the infrastructure, 155 00:06:36,090 --> 00:06:39,410 and this is actually where the word DevOps come from, 156 00:06:39,410 --> 00:06:41,870 developers who also operate. 157 00:06:41,870 --> 00:06:44,270 And because developers are good with code, 158 00:06:44,270 --> 00:06:46,680 when we talk about infrastructure as code, 159 00:06:46,680 --> 00:06:47,980 developers are the expert.