Learn Terraform (and AWS) by Building a Dev Environment – Full Course for Beginners

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Learn how to use TerraForm with AWS.  In this course from Derrick Morgan,   you will realize within a few minutes of  watching how amazing Derek is as an instructor.   Hello, and welcome to the build a development  environment with AWS and TerraForm resume   foundations project. So a resume foundations  project is a short project that is tailored   to cover the important aspects of a technology in  order to help you build the foundations necessary   to build your own projects and apply them to your  resumes. So let's take a look at what you're going   to find in the course. In this two hour project  centered around TerraForm. You're going to use   VS code and deploy an AWS EC two instance, along  with the VPC, Internet Gateway security groups,   et cetera, that will serve as a remote development  environment that you can log into directly from   VS code will utilize several TerraForm tools  and functions such as TerraForm, state format,   replace console variables, conditionals, file,  template file, and more. We'll also use AWS user   data and a local exec provisioner to bootstrap the  EC two instance and add its connection information   to your VS code SSH configuration file,  allowing you to modify it for your own projects.   Since we'll make heavy use of documentation  and highlight the process behind developing   a brand new TerraForm deployment,  you'll have the skills you need to   dive deeper into TerraForm and add this  extremely in demand skill to your resume.   So what are you waiting for, sign up today.  And don't forget to terraform apply yourself.   So let's start out right here in the AWS  console. And let's go to I am. Now as you   can see I've recently visited but just in case  you haven't, you can just search right up here   in the search bar. Let's click on  that. And now let's click on Users.   Now within users, you may see a lot more  information here I've actually hidden   most of mine, let's go ahead and create  a new user. So we'll click on Add Users.   And for the user name, feel free to use whatever  you'd like. I'm just going to call it VS code.   And now I'm going to choose  access key programmatic access,   we're not bothering with a password, this is not  going to be a user that logs into the console.   So go ahead and click that in next permissions.  Now as you can see, I've got a group of admins,   you can of course, create a new group, or you  can just attach the policies directly. And I'm   going to do that just click on Attach existing  policies directly click on administrator access,   and then click next tax. Now feel free to tag  it if you'd like to, I'm not going to bother.   The next review, we've got right here our user  name programmatic access, and administrator   access. Go ahead and click on Create user.  And right here, you'll see that you've got   your access key ID and your secret access key.  Go ahead and download that CSV. As you can see,   I've already installed Visual Studio code it was a  pretty straightforward process, I am on a Windows   machine. But this of course will also work on a  Mac or Linux. So go ahead and first things first,   let's get the AWS extension installed. So  click on the extensions icon here on the left,   and then search for AWS. And once you've done  that, we've got this AWS toolkit here, go ahead   and click Install. Looks like everything installed  fine. So I'm going to go ahead and close this pane   and close this tab. And then I'm going  to click on this little AWS icon.   As you can see, we've got connect to AWS  right here. But before we can do that,   we need to get some credentials installed.  So head up to View and command palette.   Then as you can see, I've searched for this  before, but if you need to get to it, you can   type AWS and then start typing create credentials  profile, just like so. And then open that. And   as you can see here, I've got a credentials  profile called VS code. If yours looks different,   make sure that you get this looking the same if  you want to follow along in the course exactly.   But of course if you don't or you're comfortable  making simple modifications, you can name this   whatever you'd like. But what we need to do  is populate this AWS access key ID In secret   access key. So go ahead and open your credentials  file and paste this information in. Just like so.   Alright, and once you've done that, go ahead  and Ctrl S to Save this file, you should not   have this white dot that was up here before, then  close this tab, and then click on Connect to AWS.   And you should see your profile right here.  If not, you can obviously type profile VS code   if you need to, and just click on that, and  default region of US East one, I actually don't   want that region, I'm going to use a different  one. But whichever region you choose, you can   choose that here, I'm just going to say no. And  I'm going to add US west to that's the region I   typically use in my courses, because there's so  much default stuff that goes on in US East one,   I just prefer to stick with us West too, but it  is totally up to you. So once you've done that,   you can go ahead and minimize that. And then  open the extensions panel again, let's go   ahead and add something that will give us a little  TerraForm syntax highlighting, let's go ahead and   type in TerraForm. And as you can see, there is an  official TerraForm extension here, it's rated 2.5.   It is pretty buggy, it might be better now that  you're watching this video, feel free to choose   this one if you'd like. But I'm actually going to  use this one here, it's just got a higher rating.   And it's been pretty consistent for me. So I'm  going to install this one, just like so. Alright,   and I'm going to close that tab and close my  extensions. So now that we've got our extensions   installed, let's go ahead and create our working  directory. So I'm going to go ahead and click on   Open folder. And I'm just going to set mine up in  the Documents directory, feel free to set this up   wherever you'd like of course, just like so.  And then I'm going to create a new directory.   And I'm just going to call it TerraForm. Just like  so. All right, and I'm going to open that and hit   select folder, just like so. Alright, so now we  have a working directory, we've got our extensions   installed, everything is ready to start the  course. Now it's a fairly straightforward build,   we're going to cut it down to the bare necessities  because you don't need much for your development   environment, the more resources we add, the  more can go wrong. So let's just make sure   that we keep it as small as possible. And then  of course, as you develop new requirements,   you can build out your environment to meet your  needs from there. So what we're going to do   is we're going to use VS code on our terminal.  And then we're going to use the TerraForm   configuration files, providers variables, main  terraform.tf VARs, which of course, we will be   explaining all of these throughout the course.  And then we've got a configuration file here   that's going to configure VS code based on the IP  and other information of our developer node. And   we've got our user data that's going to bootstrap  that node. Now in AWS, we will build out a VPC,   we're going to build out an Internet Gateway,  public route table, a security group, a public   subnet, and an EC two instance. So all of this  together will form our developer environment. And   once we're done, after all of these files have  been processed, and everything is good to go,   your VS code terminal will have access directly to  this EC two node to deploy a remote SSH session,   which will allow you to have file and SSH access  to your EC two node to run whatever you need. So   that's a very high level overview. Let's go ahead  and get building. So here I am in the AWS provider   documentation within TerraForm. And a provider is  basically used by TerraForm to interface with the   API of whatever infrastructure you're trying to  build. So in this case, you're trying to build AWS   infrastructure. So you use the AWS provider, if  you're using GCP, or Azure, or VMware or whatever   else you will use their respective providers. So  as you can see, it's pretty straightforward. Since   we've already provided credentials, we don't need  to provide those within the provider block here.   If you scroll down, you can see there's actually  lots of ways to add these credentials. But again,   we already have a profile. So all we need to  do is access the shared credentials file, just   like this. So let's go ahead and we'll keep it  fairly simple. I'm just going to copy this here.   And then within our TerraForm directory here,  which we created Earlier are going to create a   new file. And let's call this providers.tf. Just  like so. And we'll paste that in. Now I'm actually   going to remove this version block here, because  you may be in the distant future, and not on   version three anymore. So again, I'm going to just  remove that and let you download whatever version   is current. Now after that, we need to add our  provider block, that is the required providers   block. And that provides configuration that  TerraForm needs to know about. But the provider   block itself provides the information needed to  access AWS specifically. So if you scroll down   here, you can actually see that we have some usage  examples. And we have one right here with shared   credentials file already here for us. So let's  go ahead and just copy this one. And I'm going to   paste that right here. Now again, typically,  I type all of this out. But since this is a   very quick course, I want to make sure it is as  streamlined as possible for you. So here, I'm just   going to remove this. And I'm just going to add  that little squiggly right there to indicate the   home directory, dot AWS slash credentials. Because  that's where our credentials file is stored.   Now, if you've moved it, of course, you'll want to  change this. But this is actually the default for   Windows and Mac. So you should be good to go. Now  for the profile, remember, that was named VS code.   And the region is US West two. So this is  what you should have here for the provider.   Again, if the documentation did not provide  this exactly, of course, just copy it from   here. All right. So now that that's done, let's  go ahead and run a TerraForm init to initialize   this and connect to AWS to ensure everything  works out. So I'm going to click on terminal   and new terminal just like so.  Let's go ahead and I'm going to   pull this up a little bit, clear this screen.  And let's go ahead and run TerraForm init.   All right, TerraForm has been successfully  initialized. As you can see, we've   got hashey Corp, AWS version 3.7 1.0. At least  that's my version, your version is different,   that is perfectly fine. Also, you  can see that TerraForm has created a   lock file TerraForm lock dot HCl. And what that's  going to do is ensure that the version is frozen.   Again, you can change this if you'd like. And  this should be the current version you're using.   But this is something you might want to keep  in your GitHub or git lab or wherever you're   storing your code repository so that you can  ensure that every time you run this code, it   always uses the same version of the provider, and  you have a much lower risk of having some sort of   issue with an upgrade. So it looks like everything  is all nice. And initialized. As you can see here,   I can do this drop down. And you can actually  see the provider which for Windows is an exe.   And for Linux and Mac, you'll actually see another  binary there. But this is compiled and you're not   going to go digging through it. As you can see  here the VPC is actually pretty straightforward.   You basically specify the resource, this  being the actual resource, as you can see,   AWS VPC, this is a static value that cannot be  changed. If you change this, you're not going   to deploy a VPC. Now after that, we've got the  name for this VPC, which in this case is main,   we can name it, whatever it is, we want. This is  a logical name that only TerraForm knows about.   So this isn't going to show up in AWS anywhere.  So again, make sure you understand that, but   this is how we will reference this VPC in future  lessons. And then we just provide a cider block.   Now there are also lots of other options that  you can specify here. As you can see, it gets   pretty complicated. If you go down to the argument  reference, you can see that we have a lot of stuff   here we can use, such as enabled DNS support,  which defaults to true in enabled DNS host names,   which defaults to false. So let's go ahead and  let's utilize this to create a VPC, we're going   to bring my VS code back over here. And I'm going  to create a new file and we're going to call that   main.tf. So I'll create a new file main.tf  Just like so make sure that it is in the proper   directory here and you didn't accidentally  add it within the TerraForm directory here.   And we've got that up. Now, the way these TF  files are processed is they're processed as if   they're all the same file. So if you have 20,  TF files in here, all with different resources,   they're all going to be processed Test as if  they're the same file. So keep that in mind.   You can split up your code, however makes sense  to you, you can have a compute.tf networking.tf,   whatever you'd like. It's all processed the  same as long as it's in the same directory.   So let's go ahead and create this VPC  resource. So I'm going to type resource,   AWS VPC, just like so. So this, of course,  is specifying that I want a resource, or here   I wanted a provider. Here, I want a resource. Now  once again, let's name this VPC. I'm going to name   it MTC for more than certified VPC just like so.  And then I'm going to use some curly braces here.   This will wrap our entire resource that  I want to specify that cider block.   And in my case, I'm going to do 10.123 dot 0.0  slash 16. If you've taken my other courses,   you've probably seen this cider block before.  Now under that, let's say I want to enable   DNS host names. As you remember, DNS host names  defaults to false. So if I want to enable this,   I need to make sure that I add  it. So I'll go ahead and enable   DNS host names equals true just like so. And if  I wanted to, I can also say enable DNS support   equals true. Now we don't have to because this is  assumed, however, depending on your development   team, you might want to ensure that this is  explicitly mentioned, your team may not understand   what's default for your VPC. And it might be  very helpful to be very explicit and specify some   things that default is true as true just to ensure  that when it's easy to modify, and to your team   knows that this is enabled, again, not required,  but it's something you might want to do. Now under   that, we're going to specify some tags. And I just  want a name for it. And I'm just going to name   it Dev, just like so. So I know that this is my  dev VPC whenever I go searching alright, and as   you can see, I've got my two curly braces  here. One is to enclose these tags, and one   is to enclose this resource. So that's all I need  there. Let's go ahead and run a TerraForm plan,   just like so. And what this is going to do  is let us know what we're trying to build.   Just like so as you can see we've got all of  these new pieces that are going to be created.   Within our VPC resource, we're going to have our  cider block and Arn will be created which we won't   know until we actually apply it in the same with  a lot of this other information such as the ID   we will not know until we apply it. Now as you can  see we've got these green plus marks that means   that these are all being added. So that all looks  good. We've got one actual resource AWS, VPC dot,   MTC VPC to add. So what we want to do next is  apply we'll run a TerraForm apply, just like so.   And as you can see, it basically runs another  plan, and then asks us to confirm and to confirm,   I'm going to type yes, scroll this up a  little bit, and our VPC is being created.   All right, perfect. Our apply is now complete.  So if we go over here to our AWS pane,   I'm going to click no here I do not need us  East one right now because I am in US West.   I'm then going to click on Resources. And as you  can see, I've actually got some resources already   shown here that's from a previous installation.  If you click on this little sprocket type AWS   colon colon EC two colon colon VPC, you can also  search for VPC, you can see that that's been   added, go ahead and checkmark that and click OK.  To ensure that resources added, then if you click   on it, you'll see our brand new VPC is here. So  there's our cider block, our default network ACL   default security group, it looks like  everything is here enable DNS host names is true   enabled DNS support is true, we're going to take  a slight detour from building to dive into the   TerraForm state a bit. So we better understand  how information about our deployment is stored   for TerraForm. To use. This is probably one of the  most important concepts with TerraForm. So make   sure you read over the documentation a good bit  if you really want to understand how things work.   But essentially, we're just going to take a  look here and see exactly what is stored in   our state as we deploy resources. As you  can see, there's a lot here in the docs.   And we're going to explore several pieces  of this as we build our infrastructure.   So here we are right here after we have now  deployed our fresh new VPC. As you remember,   in our AWS resources pane here, you can see all  of this wonderful information about our VPC. Now,   another way we can see what we've deployed, is  to head into our Explorer. And right here, our   terraform.tf state file. As you can see, we have  a lot of the same information default network ACL   default route, table ID, security group ID, the  VPC ID there. As you can see, all of that is here,   VPC ID, default network, ACLs, security group,  etc. Now, it's formatted a little bit differently.   But it's, for the most part, the same information.  And this was all pulled right from the   AWS API. So now typically, you're not going to  want to traverse this tf state manually as it   will normally be stored somewhere off site,  whether it's in TerraForm, cloud or in AWS,   or somewhere else. So we have several  different tools, we can use command line tools   to access the state. So let's take a look at  TerraForm state list just like so. As you can see,   we only have one piece and our state one resource  that MTC VPC that we deployed. So if I want to see   that information within that VPC, I can run  a TerraForm state show, AWS VPC dot MTC VPC,   as you can see shown right here, I hit ENTER  on that. We have all of the same information.   So we've got information here from our API,  we've got information here within our state,   the state file specifically. But this  is all the same information. It's just   formatted a little bit differently.  Now you can output as JSON and   really manipulate that output. But we're not  going to dive into that right now. All right. And   of course, if you want to see the entire state,  all you have to do is just type TerraForm show.   So keep that in mind. TerraForm state  show requires you to insert a resource.   Now TerraForm show is just going to show  you everything that you've got, which of   course can be massive if you have a very large  environment. So those are the basics of our state,   and the information that's being stored within it.  There are a lot of commands that you can use to   manipulate that state to refresh it to migrate it.  But we're not going to dive into that right now.   But just know, it'll be very beneficial to you.  If you dive into the documentation a little bit,   and just read all about state as it is the  most important feature within TerraForm.   We're going to check out a command almost as fun  to use this TerraForm apply, but much more fun   to say. And that command is TerraForm destroy.  So TerraForm destroy is pretty straightforward.   Basically, it's going to destroy anything that  we have created. And as you can see here, you can   actually run a TerraForm apply dash destroy.  But we typically just use TerraForm destroy,   there's not a lot else going on here that  you need to really worry about, you can run   a TerraForm plan in destroy mode, which will tell  you what happens when you destroy. So that can be   fairly useful if you need to test something out.  But for the most part, we're just going to run   this TerraForm destroy. So let's do that. Let's  knock out this VPC that we created completely   delete everything we have applied. So just run  TerraForm destroy. And then we can just use a dash   auto approve if we don't want that confirmation  dialog, again, useful in automation. Probably   wouldn't use this in production. If you're typing  it yourself though. Let's go ahead and run that.   Alright, right, the destruction is complete,  everything is gone. So that's really all you   need to know there. So go ahead and reapply  it as we're going to need this VPC for pretty   much the remainder of the course. So TerraForm  apply, auto approve, just like so. All right,   all set. We're back to where we left off. You saw  how easy that was. This is one of the great things   about TerraForm infrastructure just comes and goes  as you need it. We're going to deploy a subnet to   which we can deploy our future EC two instance.  As you can see here in the docs, it's pretty   straightforward. Although there are a few more  options, we're going to want to add one of them   and if you scroll down here is To map public IP  on launch, default is false. We want to make sure   that our instance receives a public IP address  whenever we launch into the subnet, so we want   to ensure we add that so let's go ahead and get  started. All right, so right here under my VPC,   we're going to add another resource. And that  resource is AWS underscore subnet. Just like so.   And then let's go ahead and name it. I'll just use  MTC underscore public underscore subnet, just like   so. And you don't always have to add a prefix like  this. Although I've been doing it for so long. If   I did not add this prefix, this course would be  way too long due to all the errors I've made. So   for consistency sake, I'm just going to keep this  MTC prefix on all of my resources. All right, so   let's go ahead and open and close those resource  braces. And what we need to do is provide a VPC   ID now as you remember, when we ran our TerraForm  state list, we've got a list of our resources.   And this is how we want to access this VPC  resource. So what we're going to do is AWS   VPC dot, MTC underscore VPC, which again, matches  this as well. And since this is another resource,   it's like a variable, it's not a string, so you're  not going to quote this. This is a reference to a   resource, so you don't need to add quotes. And  then what we need to do is just specify an ID.   So if I do the TerraForm, state show, AWS, VPC  dot, MTC, VPC, just like so we can see that it has   an ID attribute. And that's the ID that we need  for our subnets. So we just specify that.id Right   there. And that's how you're going to reference  most of the resources that you have to reference   from other resources. So next, we  need to provide our cider block.   And that's going to equal 10.123. And I'm just  going to say, dot 1.0, slash 24, which, of course,   is one of the subnets within this slash 16. And  then after that, we're going to add our map,   public IP on launch, that's a long one there,  equals true and since this is a Boolean, it's   also not quoted. And then we need to provide an  availability zone, just like so. And that'll be US   West. And we're just going to use to a or at least  I am, because I know a is probably good to go.   There are ways to use what are called data  sources to ensure that this is always correct,   especially if you're using multiple availability  zones. But we're not going to dive into that now.   But feel free, of course, to research that if you  are curious. So next up, we're going to add tags.   And that name equals Dev. Public, we'll just  go with that. So the VPC, we just named Dev.   And we'll just name this here as dev public  so that we know that it's a public subnet.   Again, map public IP on launch equals true  is a good reason for us to want to make sure   we label it correctly. So we don't accidentally  put sensitive resources in this subnet, which of   course, could cause a security nightmare. Alright,  so that's all we have to do for this subnet. Let's   go ahead and run our TerraForm plan. All right,  we've got one resource to add. So that's good   and AWS subnet is going to get added. As you can  see, everything we have specified is listed here.   And of course, certain things like the ID are  known after apply. So let's go ahead and run   a TerraForm apply. And then I'm just going to add  auto approve, you're not always going to do this.   But if you're running a plan first, it's usually  pretty safe to go ahead and just auto approve it,   and not have to type that yes, every single  time. This especially is useful in automation.   So I'll go ahead and run this. All right,  one added, everything looks successful.   So I'll go ahead and click on this sprocket  next to resources, which again is in the AWS   pane. And I'll go ahead and type subnet. As  you can see, we actually do not have subnets   available. This is a limitation of this AWS  plugin, so we're not going to worry about it.   But it looks like that subnet creation was  successful. And of course, you can always go into   the AWS console to verify we are going to give  our resources a way to the internet by creating an   Internet Gateway. We will then introduce TerraForm  format to clean up our code a little bit.   So let's get started. As you can see here, the  Internet Gateway is pretty straightforward. It's   actually a really simple resource to deploy.  We've got a few attributes here. These are the   things that will be exported. within our  state, and these are the arguments VPC ID   tags and default tags. So let's just go ahead and  knock this out. Alright, so here we are. Let's   go ahead and scroll down a little bit under  our subnet, and we will add a new resource.   AWS Internet Gateway just like so. And we'll  call that the MTC Internet Gateway. All right,   and then I will open and close my braces. Let's  add that VPC ID. And remember how we access   this VPC AWS, VPC dot, MTC vpc.id. Just like so in  fact, I can even copy this to save a little bit of   time, and just paste it in. And then just for the  heck of it, I'm gonna go ahead and add some tags.   And we'll give it a name of DEV Igw, just like  so. So we've got our dev VPC, our dev public,   and our dev Igw. So once we've done that, that's  literally all we've got to do. But let's go ahead   and introduce that fun new command. If you go  ahead and run a TerraForm, FMT, just like so   what that just did was that corrected any type  of inconsistencies we've got in formatting,   as you can see, main.tf and providers.tf,  or both corrected. Now, unfortunately,   I was not scrolled up. But as you can see, now  all of our equal signs are lined up perfectly.   So it made some very minor formatting  changes, but it looks a whole lot better.   So that's great. And if you want to  see it in action, just go ahead and   move that a little bit. Run the command again.  And as you can see, it automatically corrects.   Alright, so let's go ahead and deploy this brand  new Internet Gateway. Go ahead and run TerraForm   plan, just like so. All right one to add. As you  can see, we've got our Internet Gateway that's   going to get added. So let's go ahead and run  a TerraForm apply. Auto approve, just like so.   Okay, apply complete, everything looks  good. Let's click on our AWS pane. And   let's see if we can access this resource.  Just go ahead and type internet. Haha,   AWS Internet Gateway, we've got it. So  let's go ahead and check that and select   OK. And if I expand my resources here, and  take a look under EC two Internet Gateway,   we'll see we've got two. So if I  click on the one with the longer ID   we can see right here that  we've got our Internet Gateway.   With the proper tag, we're going to create a  route table to route traffic from our subnet   to our Internet Gateway. All right, here I am  in the docks. And as you can see, there's a   note here. And basically, you can use a standalone  route resource. Or you can define routes in line.   Now in this case, they have the routes defined  in line just like so we're going to do it a   little bit differently, we're actually going to  use a route resource, which as you can see here   is also fairly straightforward. And we'll  walk through this here shortly. So let's   head back over to our route table. As you  can see, all we basically need is the VPC ID,   and then we'll provide some tax. So let's go ahead  and do that. So I'll open my main.tf. Once again,   scroll down some, let's go ahead and create  that resource AWS route table, just like so.   MTC public R T, just keep  it from getting too long,   and open and close our resource braces. And within  here we need to provide that VPC ID again. And   as always, I'll just copy this and paste it  right there. And then we'll add some tags.   Name equals Dev, public AR T, just  like so. So now that we've done that,   once again, remember, we then need to add the AWS  route, which is right here. And basically we need   to specify a route table ID, destination cider  block. And in our case in Internet Gateway, so   let's go ahead and do that. So we'll create that  resource AWS route just like so. default route is   what we'll call it. This is a default route, of  course for all traffic to get to the internet.   Open and close those resource braces, route table  ID equals and we're going to need to Use the AWS   route table in TC public RT AWS route, table  dot MTC public RT. And once again, all we need   to specify is the ID, it's asking for an ID.  And pretty much universally, all AWS resources   are going to have this ID attribute. So then we  need a destination cider block, just like so.   And that's going to be 0.0 dot 0.0 slash  zero, which means all IP addresses will   head for this internet gateway. And then again,  that Gateway ID is now going to be AWS Internet   Gateway just like so. Dot MTC and as you can  see, VS code is providing me some nice little   hints. So I'm just going to hit Tab, Internet  gateway.id. Just like so if we scroll up,   we can see TC Internet Gateway right here.  All right, perfect. That's all we need to add.   So let's go ahead and I'm going to scroll this  up. Let's go ahead and run that TerraForm plan.   And we should have two resources to add this time.  Perfect to to add, we've got our route table.   And we've got our route. So that's great. Let's go  ahead and run our TerraForm apply, auto approve.   And everything was applied successfully. Let's  go ahead and click on the little sprocket   next to resources and see what we have to  offer. So what we've deployed is a route table.   AWS EC to route table great. And then I actually  do not see a route that we want to use. So we're   just going to take a look at the route table. All  right, here it is. It's going to be one of these   dev public route table. Perfect. We're going to  bridge the gap between our route table and our   subnet by providing a route table association.  So let's go ahead and get started. As you   can see here in the docs, the AWS route table  association is actually pretty straightforward.   Basically, we just need to access  our subnet and our route table ID.   And just specify both of those in an association.  So let's go ahead and knock that out. All right,   so I'm gonna go ahead and scroll  down under this route here, resource   and AWS route, table Association,  probably one of the longer resource names,   MTC public, and I'll just call it an a sock  there and open and close my resource braces,   we need to provide our subnet id. In  that we just scroll up and take a look.   AWS subnet, MTC public subnet and then once  again, we just need to provide the ID of that.   So AWS subnet auto complete that dot MTC  scroll down here public subnet remove   some typing and potential for errors.id. Just  like so. So that's all we've got to do there.   Then we need to provide a route table ID in that  once again, we can just copy right from here.   And paste in. All right. So that is  literally it. Let's go ahead and save.   And then I'm also going to run another  TerraForm FMT just to clean things up,   look at that much more beautiful. All right. And  then let's go ahead and run our TerraForm plan.   Perfect One to add our route table Association.  And we'll run a TerraForm apply, auto approve.   All right, that is all set and all done. And  if we want to see that association and some   of the other things we've created, we can't  access those from the resources. So of course,   we can always go to the console  here. We can access the VPC area   and the route tables. We've got our dev public  RT right here. Take a look at our subnet   associations. And there it is. Our dev public  subnet is associated with this route table,   we're going to add a very important resource  to our deployment, the security group.   So here we are on the documentation, as you can  see here is an illustration of the usage of a   security group. Now in this case, they've actually  defined the ingress and egress in law Live,   which is perfectly fine. Now you can specify  them separately, as you can see by this note,   as a security group rule resource just like we did  with a route resource. But this is perfectly fine.   Now in your organization, you may find a benefit  to adding separate resources. But in our case,   this will work perfectly. So as you can see here,  the egress actually allows egress to everything   on any protocol, that's zero to zero. And then  the protocol is negative one, which means UDP,   TCP, ICMP, etc. Any protocol, you need to use  negative one, we'll cover it now the ingress only   allows port 443. But we actually want to allow  everything, we're just going to ensure that we   hard code this IP to our own IP, so that we don't  allow someone to compromise that our instance. So   let's go ahead and get started. Now, sometimes, I  might actually choose to just copy this and paste   it into my IDE, and then modify from there to  simplify things. But since this documentation   may have changed by the time you watch this, we're  going to type it out manually. So let's go ahead   and start that. We're going to add our resource  like always, AWS security group, just like so.   And let's just name that MTC SG for right now,  we'll open and close those resource braces,   we'll create a name. That's dev S G.  Sounds good to me. Now, keep in mind,   we don't need a tag here, because the security  groups actually have a name attribute. So there's   no point in having to tag it, you of course, could  tag it for other organizational reasons. But as   far as the name goes, this is perfectly fine.  After that, we need to provide a description   dev security group sounds great to  me, we then need to provide a VPC ID,   which we've used many, many times, I'm  actually going to just scroll up, copy this   and paste it down here just like  so. And then we need to provide   our ingress and egress. So let's go ahead  and add our ingress here. From Port,   make sure you have that underscore there  from Port equals zero to port equals zero   protocol equals, in quotes here negative one,  this is presented like a string TerraForm is   not going to honor this negative right here, this  dash. So make sure you specify this as a string.   And then cider blocks equals now I'm just going  to put in 0.0 dot 0.0 slash zero. Because I don't   want to show everyone my IP address. Make sure  you only add your own IP address here. So you   can go to what's my IP or somewhere else to find  your IP address. And then that will be something   something something something slash 32. That slash  32 indicates you want to use only this address.   But again, I'm just going to put anything  for right now. And I'll be sure to destroy   my infrastructure that has this open port and  replace it with my own later. Now as you notice,   this is cider blocks with an S which  indicates that it expects a list.   Now these brackets allow you to enter lists. So if  you had multiple IPs, you could put a comma here   and specify another one after that. But we only  need one. All right, so our ingress is taken care   of. Now let's set up our egress. gonna slide this  down a little bit, there we go. egress from Port   equals zero to four equals zero. Protocol, once  again equals negative one, insider blocks. In this   case, I'm going to allow whatever goes into  this subnet to access anything so you won't   put your IP address here. You will make sure you  allow it to access the open Internet. All right,   perfect. So that's all we need to do there.  Let's run a TerraForm FMT to clean that up. There   we go. Beautiful. Then let's go ahead and run a  TerraForm plan and make sure everything works out.   Slide that up. Okay, one to add like we expected.  Looks like everything looks good here from Port   zero protocol, negative one to port zero. Perfect.  Let's go ahead and run that. TerraForm apply,   auto approve. All right, all complete.  Let's scroll over to our AWS console.   I will click on Security Groups   Go ahead and refresh that page  here is our dev s g. by open that,   click on Edit inbound rules, we can see all  traffic is allowed on all protocols, all ports,   custom source, and again in my case is 0.0  dot 0.0 slash zero. All right, perfect.   We're almost to the deployment of our EC two  instance. But first, we need to provide the   AMI from which we want to deploy. To do this,  we can utilize what's called a data source.   A data source is basically just a query of  the AWS API to receive information needed to   deploy a resource. In this case, we need an AMI ID  based on some filters we're going to provide. So   let's get started. So if I head over here to my  data source documents here for the AWS AMI, you   can see an example, data AWS Ami. And of course  data basically is like the resource keyword we've   been using, we're just using data. Now AWS AMI  is the name of this data source. And of course,   this needs to stay the same no matter what. And  then this here can be whatever you want to name   it. Now we'll be using most recent, and we'll be  using some filters as well. Now one thing we have   to make sure is that we have the correct owner.  Now one way to do that is to use AWS Marketplace.   But in our case, we're going to be a little more  specific, let's take a look at how to get the   owner ID we need. So if I head into the management  console here, going to type EC two up at the top.   Going to open that, if I go to instances and  Launch Instance, let's take a look. I'm just   going to type Ubuntu here. And I'm going to deploy  Ubuntu server 1804. That's what I've used in my   other courses. And I'm just going to stick to  that for now. 2004 should work perfectly fine.   And whatever it is you want, you can choose. But  in our case, we're just going to use this 1804.   So what I'm going to do is copy this AMI ID  because an owner ID is not provided here, which is   a little annoying. And then I'm going to head back  to my EC to console. And I'm going to click on   AMI under images. And right there, make sure you  have public images chosen and enter that AMI ID.   And here is our owner. So go ahead and copy that  you're going to need it here shortly. Alright, so   once we have that, let's head back over and start  coding this thing out. Let me drop this a little   give us some room. So now what I'm going to do  is actually create a new file for this. And we're   going to call it data sources.tf. So I'll  just create a new file, and data sources.tf,   just like so. And this will just keep things  a little cleaner. So we'll use data, AWS AMI,   and we'll just call it our server  AMI or whatever you want to call it,   we want to specify most recent equals true.  And then we provide the owners. Now the owners,   as you can see is plural. So we're actually going  to use brackets, which makes it a list. Go ahead   and paste that owner ID that we got into here. And  of course, if there are other owners, you could   but in this case, we just need that owner ID. All  right, now that we have provided our owners here,   let's go ahead and provide a filter to get the  correct Ami. So if I type filter, just like so,   name equals, and we're going to filter on  name, I know this looks a little confusing,   but the filter name is actually name and then  values equals and once again, this is plural,   so make sure it's in brackets. Ubuntu slash  images, slash HV M dash S S D slash Ubuntu   bionic dash 18 dot o four dash AMD 64. Make  sure you have the right architecture there.   Dash server Dash. And then what we're going  to do since there's usually a date here,   and we're just going to pull the most recent no  matter what, we're just going to add an asterisk.   So instead of the date that we would use here,  we use an asterisk so that any date will qualify.   So if I just head right back over here and take  a look, you can see. Basically all we're doing is   just putting an asterisk instead of this date, but  everything else is exactly the same. All right,   so perfect. So that's actually all we  need to do. Go ahead and save this file.   And then let's go ahead and run a TerraForm  apply TerraForm apply auto approved just like so.   All right, great. So now that is applied. So  if I open my terraform.tf state right here,   again, you would usually use a TerraForm show.  But this is a little bit easier for this.   We can scroll down under resources. And  you can actually see we have instances,   even though we don't have any EC two instances  actually deployed, there's still an instances   section that contains this AMI data source.  And if you look down, you can actually see,   we've got an image ID right here, which actually  does not match here. And there's a reason for   that. And that is, if you look at the date, 2021  1129, the date of this one is actually 2022 0104.   So this is actually a newer instance than  what is in the console, which is why that   AMI doesn't match. And for our purposes, that's  perfectly fine, we're going to create a key pair,   and then create a TerraForm resource that  utilizes this key pair. This will be used   by the EC two instance resource we create  so that we can SSH into it later. So let's   get started. All right, I'm gonna first highlight  my main.tf here, and then I'm gonna go ahead and   create that key pair. So to do that, and yes,  I am on Windows, Windows actually does have an   SSH utility. So I'm going to run the same commands  that I would run on OSX or Linux, SSH dash key Gen   dash t. And we will use a more secure key than  the typical RSA we use, let's use Ed 25519,   and hit Enter. Now we're going  to rename this key pair here,   I'm just going to copy this instead of retyping.  It basically everything before the ID EDI 25519.   And I'm going to paste that in. And then we're  just going to name this MTC key, or at least I am,   name it, whatever you want here, just make sure  you reference it properly throughout the rest   of the course. And I'll hit enter, we're not  going to bother with a passphrase. All right,   perfect. It looks like everything is good to  go. Just going to run an LS tilde slash dot   SSH here. And that shows me that directory. And  MTC key is there an empty C key dot pub, which   is what we'll use for our key resource. So now  let's take a look at the Docs as we usually do.   Resource AWS key pair, as you see, we basically  need to specify a resource, AWS key pair and the   name that wherever we need to, we'll give it a  name. And then we will provide the public key.   Now we could just copy and paste the public key  from our file. But that looks very, very messy.   So what we're going to do is use a TerraForm  function, we're going to use the file function.   So all we have to do is utilize file and then  enter the path to our key. And what that will   allow us to do is specify the key just like  this only much shorter by just passing in a   path instead of the full public key. So let's go  ahead and do that. So we'll start with a resource.   AWS key pair just like so after that, I'm just  going to call it MTC off, open and close those   resource braces. Key name, I'm going to go ahead  and call that MTC key just to keep things simple.   And then we need to pass in that public key.  And to do that, we're going to utilize the file   function. And we'll quote this and I'll use  that tilde slash dot SSH slash MTC key dot pub.   And again, I'm on Windows, but these commands  should all pretty much line up and be the same.   So I'm going to go ahead and save that. Gonna run  a TerraForm plan. Make sure everything looks good.   I'll scroll up here a little bit. All right,  perfect. So the key pair will be created looks   like everything past those initial checks. So I'll  run a TerraForm apply, auto approve, just like so.   All right, apply complete. So if I take  a look over here and my AWS resources,   we can see if this is one that is available for  us, so I'll just type in key. Unfortunately,   key pair does not appear to be one that we can see  right here from this screen. So we'll just head   back into the EC two console. I'll click on key  pairs. And there it is. MTC key type EDI, 25519.   Everything looks great. We're going to  finally deploy our E See to instance,   it won't have anything installed on it yet. But  we'll at least get it scaffolded and deployed.   So let's get started. All right, we take a look  at our docks here, the resource is actually called   AWS instance, as you can see, in the basic  example, it's using an AMI lookup, which looks   very similar to what we have used before. As you  can see, it's got the owner, it's got everything   else here. Of course, we already saw how to get  the owner ID ourself, so that's great. And then   basically, we just need to provide that AMI and  you reference that by using the data keyword,   dot AWS underscore AMI dot Ubuntu ID. So do keep  that in mind where typically with a resource,   we would just use AWS vpc.my vpc.id, for instance,  but with a data source, you need to pin that   with the word data. And then we'll just  provide a few more arguments. As you can see,   there are a lot of arguments for the EC two  instance. So let's go ahead and start coding   this thing out. All right, so what I'm going  to do, let's scroll this down a little bit. And   let's add our resource. AWS instance, just like  so I'll just call this dev node, just like so   open and close those resource braces, we need to  provide an instance type first. And to keep this   in the free tier, we will use a T two dot  micro Of course, you can scale that up,   but that might cost you some money. And then  we need to provide our Ami. So as you remember,   the AMI in our data source here is data dot AWS  AMI dot server AMI data dot AWS underscore AMI   dot server AMI, just like so. And then  we just need to add ID to the end.   And then let's add some tags. We'll just give it  a name equals, and we'll call it dev dash node,   just like so. Now after that, we need to provide  our key name, which of course we created recently.   And what we're going to use is AWS key pair,  which of course we just created right here,   dot MTC underscore off.id. Once  again, now I see that this says key   name and not necessarily ID, but the ID  is perfectly fine. Here the ID will work.   Now if you take a look by just running TerraForm  state show AWS key pair dot MTC underscore off   we can see there actually is a key name.  So if you want to be more explicit,   you can absolutely use key name ID is just a force  of habit. It's something that I do frequently.   As you can see, it is the same for both. So  both works perfectly fine. But just know you   can use key underscore name if you want to be more  explicit. Alright, so now that we've done that,   let's go ahead and give this EC  two instance a security group   VPC Security Group IDs. You see this s here,  which means you guessed it, we need to use   brackets. And I'm just going to do AWS underscore  security and tab there to autofill. That dot   MTC underscore s g. Right there.id. And  of course, if you have multiple you can   use comma separation to provide multiple security  groups. And then we just need a subnet id.   So that's going to be AWS subnet dot MTC  underscore public subnet just like so.id.   Then if we want to resize the default size of the  drive on this instance, we can provide root block   device just like so. And you can actually up this  we can say volume, size equals you could say we'll   just say 10. We'll keep it in the free tier, which  gives you 16. So we'll just say volume size equals   10, which is larger than the eight that they give  you by default. All right, so that actually is   all we need to add for our instance for now.  Let's go ahead and run our TerraForm plan.   All right. As you can see, we've got a lot of  attributes there. But everything looks good to go.   But actually don't bother applying yet. We're  going to go ahead and come on back to the next   lesson and add some user data before we apply this  instance. So we don't have to wait for it and then   just re destroy it. We're going to utilize user  data to bootstrap our instance and install the   doc per engine. This will allow us to have an  easy to instance deployed with Docker ready   to go for all of our development needs. So let's  get started. Now the first thing I'm going to do   is just clean up this AWS instance a  little bit, I'm going to cut this out.   And I'm just going to take everything that's not  in a block, and place it together. So this will   make things look a little more streamlined. So as  you can see, we've got all of our arguments here,   followed by the tags block, and the root device  block. And just to be consistent, I'm actually   going to cut out this root device block and put it  above the tags block since almost everywhere, we   finish the resource with tags. All right, perfect.  So that looks a lot better. So now let's add this   user data. First thing I want to do is create  the user data file. So I'll create a new file.   And let's just call it user data dot  tpl. Now, this TPL actually stands for   template. We're not using this as a template  right now. But just in case in the future,   you decide to use it as a template you can  and we'll take a look at templating here   in the coming lessons. Alright, so go ahead and  take that script I have provided in this lesson,   and paste that in. Now this script, as you can see  is going to update apt, it's going to install some   dependencies, it's going to download the Docker  GPG key, it's going to add the Docker repository   update once again, install Docker, and then  it's going to add Ubuntu to the Docker group,   allowing you to run Docker commands as the  Ubuntu user. I know that was a little quick,   feel free to reach out if you have any  questions. So now that we've got this in,   it's in our user data dot tpl script, and I  have saved it and this is in our root directory.   Let's head back to our main.tf. And let's go  ahead and add this user data to our resource.   So what I'll do is just add user underscore data  equals, and we're just going to use the file   function here. And in quotes, once again,  user data dot tpl. So what this is going   to do is extract the contents from our user  data dot tpl file and use that to bootstrap   our instance. So Perfect, let's go ahead and see  if everything works. Let's run a TerraForm plan.   All right one to add. As you can see,  we've got our EC two instance here,   everything's looking pretty good. As you can  see, our user data is hashed here. So if this   user data were to change, it actually would change  that hash and indicate that we need to redeploy   our instance. So that's really, really  useful. So now let's go ahead and apply   TerraForm apply, auto approve, just like  so. Now, this is going to take a little bit,   so feel free to pause, and then come on  back whenever your instance is deployed.   All right, as you can see, the apply is complete,  I'm going to head into my PC to console,   just like so. And as you can see, it's running.  And I've actually had a few dead ones here.   But this new one is running, but it's still  initializing. So go ahead and pause the video once   again, hit refresh a few times, and come on back  whenever the status check is green. All right,   so now everything is green, we've got to have  two checks past perfect. So now let's SSH into   the instance. First of all, I need that IP  address, so we can definitely just copy it   from right here. But another way, of course, is to  use our TerraForm state. So if we do a TerraForm   state list, just like so we then see our  instance right here, I'm just going to copy that.   Then I'm going to do a TerraForm state  show and hit that instance right there.   And here's all of the information we can get it  if I scroll up a little bit, I've got the public   IP address right here. Perfect. So now what I'm  going to do is just do it SSH dash i. Then if   you're on Linux or Windows, you can use the tilde  slash dot SSH slash MTC key or whatever you name   that key. Now, if I hit tab that will actually  correct it for Windows users, but it doesn't   matter. It works either way. And then I'm just  going to use my Ubuntu username at that public IP   address. And hit Enter. Type yes, and bam we are  in the instance now. So if I run a Docker version.   As you can see, we now have Docker installed and  the instance is running, we're going to take a   look at the configuration we're going to have  to create to allow VS code to connect to our   EC two instance. So first of all, if you haven't  already, head over to the extensions, and go ahead   and search for SSH. And you should see this remote  SSH app here. Go ahead and install that extension.   Just like so. Alright, perfect. So now that  we've done that, we can go ahead and head   back to the Explorer. And first thing I want  to do is take a look at some example config   files. So you should have a file now at  your home slash dot SSH slash config.   So if I do cat, SSH config, just like so. I  can see here that I already have two entries.   Of course, this is something I've done before.  And what we need is we need to provide a host,   a host name, which happened to be the same here  and the user that we're going to use to log in.   So what we need to do is provide the IP address  of our instance, on both of these host areas host   and host name. And then we'll utilize Ubuntu for  the user. So how are we going to do that? What   we're going to do is we're going to use template  files. And we'll take a look into that very soon.   But first, let's create the files. So go ahead  and create a file based on your operating system.   Whether you're on Windows, or Linux or Mac,  Linux and Mac can both use the same script,   Windows is going to be different. So I'm  going to create both in this lesson. First,   I'm just going to create windows dash SSH config  dot tpl, just like so. And if you're on Windows,   go ahead and grab that script, copy it, and paste  it in. So basically what this is doing, and you   will need to replace your username here. Mine,  of course is Derek yours probably isn't Derek,   but you might be go ahead and replace that. And  then this is going to add the host host name user   and an identity file, which we didn't see before.  But we do require to our config. Now what we do   is we actually specify the host name, the  user and identity file from our main.tf.   And we're going to take a look at how to do  that in the coming lessons. So go ahead and   save this file if your windows. And if you're  Linux, let's go ahead and create that one.   So again, you can call this Mac if  you want, I'm just going to call   Linux SSH config for our file name. And this  will serve for either Mac or Linux. And for that,   go ahead and copy the script and paste it in. And  what we've got here is we're actually catting into   home dot SSH slash config. And then we've got the  host host name, host name, user and identity file,   just as we did before. So go ahead and save that  file. If you're Linux, you can also provide both   if you utilize both platforms like I do,  we're going to utilize a provisioner to   configure the VS code on our local terminal  to be able to SSH into our EC two instance.   Now a provisioner is not something you want to  use for every deployment. Unlike other resources,   a provisioner success or failure will not  be recorded or managed by TerraForm state.   So if something goes wrong, that's just too bad.  There's no rollback or any other way to manage it   other than just running it again. While this  is not good for configuring remote instances,   it's perfectly fine. For something like this, all  we're going to be doing is adding information to   a config file on our local terminal. This is a  lightweight operation that doesn't affect the   overall success of the deployment if something  were to go wrong. So with that being said,   let's get started. First, we'll take a look over  here at the provisioner documents. As you can see,   provisioners are a last resort. Generally  speaking, you're going to want to use   user data which of course we do Ansible or  packer, or chef or something else some other   configuration management tool. If there's some  sort of configuration we need to do on a remote   instance. But once again, on our situation,  it's perfectly fine. And we can use the local   exec provisioner to allow us to configure local  machines and run local commands. As you can see,   basically we're running a provisioner  and in this case a Local exec provisioner   within an AWS instance, resource provisioners are  always run within another resource. This could be   something called a null resource also. But we're  not going to look into that right now. Now another   thing we're going to use is this self object here,  which basically allows us to access this instance,   and access information. So if we need a  private IP, or public IP, or whatever,   we're able to access that right here, using  this self attribute. Now, something else you   might notice, we've got this dollar sign, and  braces here, that is interpolation syntax. And   basically what that means is this is going to be  replaced by whatever it is we're trying to use.   So we've got a string here. But this here will be  replaced by the private IP of this AWS instance.   And you may have remembered that in our previous  scripts, so let's go ahead and just get to work.   So right over here, once again, we can take a  look at our configuration files. And once again,   remember these here, the same syntax, these are  going to be replaced by the host name, the user   identity file, whatever we need to pass in. So  let's go ahead and start typing our provisioner.   Gonna go to the bottom of our instance resource  here, we're going to type provisioner. Just like   so. And then local dash exec, we've been using  underscores a lot throughout this script, as you   remember, but this provisioner uses a dash make  sure you remember that this is a dash or a hyphen,   and not an underscore. This is a mistake I've made  many, many times open and close that provisioner   block. Next up, we provide our command. Now  this command is actually going to be run   from these files here. And to run these  files and pass in the variables necessary,   we won't use the file function, we'll use what's  called the template file function. So we take a   look at the template file function here, you can  see that basically, you pass in VARs, after you   pass in the path. So for instance, you can take a  look at here template file. And then this here is   the path which is using this interpolation syntax  and path dot module, which is a built in variable   and then you use a comma. And then within an  object here with these curly braces, you pass   in the variables that you need to pass in. So  let's go ahead and do that. So for the path,   in my case, since I'm on a Windows machine, I'm  just going to use quotes windows, dash SSH dash   config dot tpl, just like so if you're on Linux  or Mac, you'll use the Linux version. And then   after that, we need to pass in our variables.  So I'll add a comma here, then open and close   some curly braces, and we will pass in these  variables, I'm actually going to indent this.   First up, we need our host name. Remember, we had  to pass in a host name there. And that host name   is going to be self dot public underscore IP.  Remember, we have a public IP attribute for our   instance that we used before, whenever we SSH into  it. So we can just use self dot public IP here   to access that after that, we need to provide the  user and that's going to be Ubuntu because that   is the EC two instance username that we have.  After that we need to provide an identity file.   So that identity file is  going to be our private key.   And the private key is located we'll just  use a tilde here slash dot SSH slash and TC   key just like so. Alright, so that is all of the  variables we need to pass in. And then after that,   we need to pass in an interpreter. Now the  interpreter basically just tells our provisioner   what it needs to use to run this script. Now it  defaults to bash so you don't necessarily need   to add this for that, but we will just to be sure,  so I'm going to add interpreter, just like so.   Equals, and since I'm on Windows, we're going  to use PowerShell and then we need to pass in   the next command which is dash command. Now if you  are on Linux, and do not put both of these here,   I'm just using this as an example.  For interpreter. You're going to use   bash, and we'll have a comma here. And then  dash c is the interpreter you'll use for Linux.   But again, I'm on Windows so I'm going to  delete that and keep this here. Alright,   so once you've done that, that is everything  We need to do and this will hopefully   create our instance. And it will replace the  hostname with self dot public IP the user with   Ubuntu and the identity file with this key  here. So let's go ahead and give it a shot.   Now the first thing we need to do is we need  to run a TerraForm plan. Pull this up some. Now   as you can see, we've got no changes here. That's  because the provisioner does not affect our state,   it doesn't read that there's a provisioner there,  and it's not going to change anything just because   we added one, we're going to redeploy our EC two  instance. And finally see if everything works. So   hopefully, when we redeploy this instance, this  provisioner is going to run add the information   required to our configuration file and allow us to  SSH into the instance without any issues. So let's   go ahead and give it a shot. So first up, once  again, I'm just going to run that TerraForm plan.   And as you can see no changes, which means that  this provisioner is not going to run because   TerraForm hasn't detected anything different.  Once again, it does not detect provisioners   as differences in the state. So it's not going  to trigger a run. So let's go ahead and take a   look at a way that we can trigger that run. First  up, I'm just going to run a TerraForm state list   again. And of course, we've got our AWS instance  dot dev node, go ahead and highlight that and   copy it. And then what we want to do is use a new  command we haven't used or at least a new flag,   we've used TerraForm apply a lot. But now what  we're going to use is a dash replace. Now this   used to be known as TerraForm tanked, which  would actually cause a resource to be replaced   on the next run. But now instead, we just use dash  replace, I'll go ahead and paste in this instance,   dot dev node here. And let's hit enter. All right,  as you can see, we are refreshing the state.   Okay, now we've got one to destroy, and  one to add. So it is removing and replacing   our instance. And once that happens, it should run  our local exec replacing the content in our config   file with what we need. And allowing us to SSH  into our instance from VS code. So let's go ahead   and type yes, and pause this video. Come  on back whenever it's done. Of course,   you might want to hop into the EC to console. And  once the instance shows up, is running and has to   have to complete and green. Go ahead and come  on back. And we'll see if everything worked.   All right, all of my checks are passed here.  Let's go ahead and bring our editor back over.   And this is now the moment of truth. First  things first, I'm just going to Cat my SSH config   file. And this is a really good sign. Look at  that it looks like our provisioner did exactly   what we asked it to it added the IP address the  host name, our user and the identity file to   our config file. So now that that's happened,  let's head up to View command palette. And let's   just type in SSH right here. And as you can  see remote SSH connect to host click on that.   And hey, check that out. So we've already got  our IP address ready to go. Let's click on it   opens a new window. This is a Linux host.  Again, we're on Windows terminal or I am but   it's a Linux host. So Choose Linux here.  Yes, we are sure we'd like to continue.   Looks like everything is setting up  downloading installing VS code server.   All right, let's open a terminal terminal new  terminal. Bam check that out. And if we run Docker   Docker is nice and installed. Once again we can  do a Docker dash dash version. So now we have a   perfectly good development environment ready to go  you can open up folders on the remote. Once again   home Ubuntu is a remote folder. So if I run that  I am now in a fully remote terminal. Go ahead,   I can hit trustees authors. Bam, perfect.  So this is really, really cool. We're going   to start optimizing our script and making it more  dynamic by adding variables. So let's get started.   Now, so far, we've hard coded pretty much  everything. So now it's time to modify that   to give us some flexibility. So that we can adjust  things easily without having to fish through every   single attribute here. And instead being able  to go to one file and modify what we need there,   for instance, probably one of the things we're  going to modify the most is the type of OS we're   using. So since for instance, I use Mac, Windows  and Linux quite frequently, there's a good chance,   I'm going to want to be able to modify  which type of instance I'm using on the fly.   So let's go ahead and take a look at that. Now  first of all, what I want to do is I want to use   interpolation syntax to specify a variable here.  Now, basically, that variable will be calculated   whenever we apply our script. So I'm going to use  interpolation syntax, which I've mentioned before,   and basically that's going to be $1 sign  in two curly braces, just like that.   So whatever happens here is going to be  calculated dynamically whenever we run our script.   So let's go ahead and name this variable,  we'll call it var dot host underscore OS.   So anywhere we need a variable, you  specify it with var dot variable name,   just like so. So now if I choose windows,  then it will be Windows dash, SSH dash config,   Linux, Linux, dash SSH dash config, just like so.  So now what we need to do is we need to initialize   this variable and specify that, hey, we've got  a variable that we're going to need to define.   And to do that, we can either do it here in  line in the main.tf, or what I prefer to do,   and most everyone is to create a new file for  it. So I'm going to create a variables.tf file.   Once again, it's analyzed just like any other  TF file, it's all run at the same time. But this   will just make sure that it's easier to find our  variables when we need them. Now, you can take a   look here at the input variables, documentation,  declaring an input variable is actually fairly   straightforward, you use the variable, variable  name, and then within braces, you give it a type.   And you can also give it a default. Now the type  is not necessarily required, but it is strongly   recommended. So that your other DevOps coworkers  don't lose their minds trying to figure out what   type of variable is expected. So let's head back  over here, and let's go ahead and build this.   So it's going to be a variable, once again, post  underscore OLS, then we'll use our curly braces.   And we'll just provide a type and that  type equals string. We're not going   to bother with a default yet, but we'll  get to it. So now that we've done that,   let's actually go ahead and perform a TerraForm  destroy, auto approve. And as you can see here,   it's actually asking for this variable  to be defined now. So keep that in mind.   Anytime you add a new variable, any destroy,  apply, or plan operation is going to require   that you define those variables. And we'll look  at other ways to define them so that we don't   have it popping up every time here from the  command line. But for right now, we can just   define it dynamically. So let's just go ahead and  I'm gonna say windows if you're on Mac, or Linux,   specify Linux, but again, nothing really matters  now, because nothing is running. So go ahead and   destroy this infrastructure. Pause the video and  come on back whenever it's destroyed. All right,   so everything is destroyed here. In just to  illustrate, once again, if I run a TerraForm plan,   it is going to ask me for that variable. So if I  type that in, then the plan will run. So keep that   in mind. Again, if you have variables that are not  set, a plan, apply or destroy is going to ask for   those variables. So if you're in automation that  can break your automation, we've now seen how to   initialize a variable and how to define it at the  command line. But as we saw, that is not a great   way to define variables when an automation as it  requires Dynamic Input, which is the opposite of   automated. So in this lesson, we're going to  look at a few other ways to define variables,   and which of those ways take precedence over the  others. So let's get started. So first of all,   let's take a look at the docs again, and if  you scroll a good bit down, you can kind of see   like we've got default values, custom validation  rules. We've got a lot here that's actually   really good information. But what we really want  to see is if you scroll all All the way down,   you can see variable definition precedents.  So basically environment variables   are processed last. So as we go down this list,  these are processed in front of the other. So   environment variables are processed last. So if  you have an environment variables set, but then   you define a variable in terraform.tf VARs, which  we're going to look at, then terraform.tf. VARs,   is the variable we're going to use. And then  you've got terraform.tf, fires dot JSON, which   not too many people use, but you can use  it in automation, it does help sometimes,   you've then got auto.tf, vars, and auto that  TFR is dot JSON, which are used in TerraForm.   Cloud quite frequently. And then you can specify  a VAR and var file option on the command line.   But this isn't like a dynamic definition.  It's not like it asks you for the definition   and you type it, you just add this dash var  switch, and then you provide the definition.   And we will look at that. So let's  go ahead and just take a look,   what we're going to do is run the TerraForm  console. And this is a really good tool that will   help you work with certain functions and play with  different values and things like that, that you   might need to experiment with before you deploy.  So if you run TerraForm console, let's just take   a look. As you can see, it did not ask us for a  variable. So if I run var dot host underscore OS   can see it's known after apply. So until we  actually apply and specify that variable,   then our TerraForm console has no idea what that  host OS variable is. So I'm going to go ahead   and type exit to get out of the console. And what  I'm going to do first is just add a default here,   so go ahead and add default equals, and then  specify your host, which again, mine is Windows,   yours might be Linux. So now let's go ahead and  run a TerraForm console. It was run var dot host   underscore OS. There you go. So now it is  processed it basically TerraForm console   has looked at all of our configuration files and  saw that we have a default of Windows. So that's   awesome. All right, so I'm gonna get out of the  console once again. Now what I'm going to do is   I'm going to create a new file, and we're going  to call that TerraForm dot t f bars, just like so.   Now, this is the default name for our variable  definition file. So here, all we need to do is   define the variable. So host OS equals windows.  Or you know what, I'm just going to type Linux,   since we're not running this right now. So now  let's run a TerraForm console, just like so.   And let's run var dot host OS. Now it's  Linux, as you can see TerraForm, that TF VARs   takes precedence over a default variable set  within the variables.tf. Alright, so that's great.   So now I'm going to get out of the console again.  Now let's say we have I don't know a Unix System,   or we want a different script that only  works with OSX. And we want to specify that   now if we still have these two files, how are we  going to override this value? Now that we have   it defined in TerraForm dot TFRs? Well, there are  a few ways to do that. And one way is to specify   the variable in line with our command. So if  I run TerraForm, console, dash var equals,   and we'll just say host, os equals in Unix,  just like so. Now, var dot host, underscore OS   is Unix. So if you need to override everything  that you have specified in any file anywhere,   you specify it right here in line,  and again, this could be a TerraForm.   Apply or TerraForm plan that you specify this  VAR for in this will override any other files   that you've got. So now let's take a look at  one more scenario. I'm going to exit once again.   Let's say that we have a dev dot TFRs. Now what  matters is the TFR is not necessarily the word in   front. However, TerraForm is going to process  anything in TerraForm, that TFRs by default,   so if you have a dev dot, TFR, and let's say  that was host OS equals OSX, just like so,   we run a TerraForm console. And then we run Varta  host OS. As you can see, it's still Linux, not   OSX. So if we want to pass in this file, we just  need to run TerraForm console. Dash var dash file   equals dev.tf VARS. Just like so. And now let's  take a look Farda host underscore OLS is now OSX.   Perfect. So now we've seen most of the ways  that TerraForm will process variables and the   precedents it uses to decide which variable to  use. So now that we've managed to choose our SSH   config file dynamically based on the definition  of our host OS variable, we now need to make our   interpreter dynamic. Unfortunately, this isn't  as simple as interpolation syntax replacements.   So we need to look at a better way, we're going  to utilize conditional expressions to choose   the interpreter we need dynamically based on the  definition of the host OS variable. So let's get   started. So what I mean by interpreter, of course,  is this interpreter here, the one that determines   what interpreter is going to be used to interpret  our SSH config script. And if it's Windows,   it's PowerShell. And if it's Linux, it's bash,  and as you can see, we can't just replace it   like we did up here. That was very simple. And  of course, there are ways we could define this.   But you know what, since we know that it's  only one or the other based on the host OS,   I don't want to create a new variable just to  do this, I'd much rather just continue using   the same host OS variable. So if you take a look  at conditionals, here, conditional expressions,   you can see basically, you provide a condition  question mark, and then you see the true value,   or the false value. So if host OS is Windows,  the true value would be PowerShell. And the   false value could be bash, for instance. So let's  go ahead and just hop in and take a look at what   this looks like. So I'm going to run the TerraForm  console. And we're going to pass in a variable   definition. Of course, we haven't defined all over  the place up here in our files, but we're just   going to define it right here in line, instead of  messing with those files right now. So var equals   host underscore OS equals windows. For me  anyway, and enter. Let's verify var dot host OS,   Windows perfect. So what we want to do is say  if var dot host OS equals and we're using two   equal signs here, because we're not setting  this we are checking for equality windows,   then first we'll just say PowerShell. And  of course, this isn't the interpreter,   we'll use exactly, but just for the sake of  using this now, this will be easier. Or bash,   just like so. As you can see, we got  PowerShell. Now if var dot host OS   is Linux, and we run this same exact command  again, PowerShell. Bash, then we get bash. So   that's pretty straightforward. So what we want  is we actually want this command in the other   command, which of course, I've also provided,  and we're going to use those instead of just   PowerShell and bash. So we'll say var dot host OS  is Windows, then what we want is in brackets here   PowerShell comma, dash command, just like so  and close that bracket. Or if it's not windows,   if this is false, then we just use bash,  comma dash c, just like so. Let's hit Enter.   And perfect even though the formatting is a  little wonky there, this will be perfectly fine.   So go ahead and just copy this directly Ctrl C,  that and for interpreter, I'm just going to paste   that in just like so. And that's all we have to  do. So let's go ahead and exit the console there.   And let's go up to our terraform.tf  VARS. Make sure that is set to your OS.   I'm gonna go ahead and change this to Windows  since that is the OS I'm using variables.tf.   The default is Windows, which is fine because  terraform.tf Ours is going to override it anyway.   So if that's different, that is perfectly  fine, but you may want to change this as well.   And then once again, with that our main TF,  everything looks good. So let's go ahead and run   a TerraForm plan. All right, everything looks like  it went through fine. So let's go ahead and apply   it TerraForm apply, auto approve, and hopefully  by the time our instance is fully initialized,   we will be able to SSH into it just like we were  able to before so go ahead and run this TerraForm   apply, pause the video and come on back whenever  your EC two instance is all green. All right,   everything has come back just fine. We're  running in all green. So let's go ahead and see   if this new IP address is available for SSH. I'll  actually take a quick peek three 4.219 for this   one. So I will click on View command palette,  I've already got remote, SSH ready to go.   And there it is 342219224 6.58.  Let's go ahead and see if it works.   This is a Linux machine, I  would like to continue Yes.   And everything is looking absolutely fantastic. We  once again, have our development environment all   ready to go. But this time, it's dynamic. Based on  the host OS that we're using, we're going to add a   nice little convenience feature to our script. By  utilizing outputs to display information we need,   as you well know, we've been manually finding the  public IP address of our instances to verify them.   Well, that is incredibly inefficient.  So let's go ahead and add an output to   make this a little easier. So as you can see,  we've got output values here. And basically,   it's incredibly simple to do. So this, of course,  is how to access a private IP, well, we're just   going to access the public IP. As you can see,  we've got a lot of other features as well,   such as the ability to mark an output sensitive  so that it doesn't show up on the command line,   you've also got a depends on feature as well,  we're not going to dive into that. But we are   just going to go ahead and access that public IP  of our instance. So if you run TerraForm console,   you can then access all those attributes  of our instance and kind of play with them   to see what output we're going to get. As  you remember, it is AWS instance dev node.   So if we just type AWS underscore instance, dot  dev underscore node, dot public underscore IP,   there it is. So that's very, very simple. And as  you know, you can use TerraForm, show or TerraForm   state show to get all of these attributes  that you could use for outputs. So if I get   out of this console, and run a TerraForm, state  show, and of course, we'll just use once again,   AWS instance, dot dev node, just like so we can  see all of the possibilities that we can use to   output. As you can see, we get output instance  types, and here is public IP. So that's what we   did, we just accessed that. So let's go ahead  and create this output, what we're going to do   is just create a new file output.tf. Once again,  you could add it to our main.tf. But we just want   to clean things up a little. So output. Here,  we'll just call this dev IP, open and close   those braces, value equals AWS instance, dot dev  underscore node dot public IP, just like so that's   all we have to do. Now to access this output, we  may not want to destroy our entire deployment,   just because we added an output, what we can do  is just run a TerraForm, apply dash refresh only.   And that's basically just going to consider this  output and add it to the state so that we can get   to it, just like so as you can see, we've got  changes to outputs. So that's perfect. So let's   go ahead and run this. Apply complete. That's it.  And then we can run TerraForm output. Just like so   to see our output once again. And this is very,  very useful in automation. Now, if we take a look   in our TF state, scroll all the way to the top,  we can see our outputs are right here. So it's   very easy to see what we need to see. So outputs  are incredibly useful. And there's a whole lot you   can do. You can get very creative with what types  of output you get. But for our purposes, all we   need to know is that IP address which matches  the one that we use to SSH into that instance.
Info
Channel: freeCodeCamp.org
Views: 234,918
Rating: undefined out of 5
Keywords:
Id: iRaai1IBlB0
Channel Id: undefined
Length: 99min 14sec (5954 seconds)
Published: Mon Apr 11 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.