Using For_Each in a Terraform Module with Azure VNets and Bastion Host

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we create a terraform module that deploys a v-net with multiple subnets and a bastion host [Music] this is another video in the series on terraform and azure we looked at an example of passing variables and outputs between modules in the last video we used a very simple resource deployment for the modules in this video we're going to do a more complex module we'll create a new v-net with a bastion host before we get started please like subscribe and share with a friend your support is greatly appreciated also check out the new membership option with the join button and my courses on udemy.com the link is below before we dig into this i have to let you in on something i spent way too much time on a problem way more than i'd like to admit it was actually referencing an instance of a subnet for the bastion config you'll see that coming up i almost rage tweeted because i couldn't find the solution but instead i stepped away for the evening and when i came back i realized that i had simply missed uh the some double quotes in the configuration file so the lesson learned we all make mistakes i sometimes have a hard time figuring this stuff out sometimes the best thing to do is step away for a while and don't give up just take a breather and check it again the next day and i suggest not angry tweeting at least waiting a while before you do i'm glad i didn't send out any angry tweets i probably would have had to apologize or at least recall them back to it the module will create deploys of v-net subnets and an azure bastion host to make this module reusable the module needs one important feature it has to accept any number of subnets for example we may need two subnets for one project and five for the other many of the v-net examples for terraform have hard-coded subnets a for each loop is used to achieve this there are two similar looping options in terraform one is count and the other is four each a resource block represents one object but if we need multiple versions of a similar object it would be repetitive to create a new resource block for each count as an argument that represents a number terraform will create however many instances of the count when we're dealing with multiple objects such as multiple storage accounts we can use the index to identify individual instances of that object use count if the instances of the resource are almost identical that's not the case with azure subnets a subnet needs a distinct name and ip address prefix for subnets we'll use a for each loop for each doesn't rely on an index it uses arguments where the value is mapped to a set of strings a map in terraform is a key value pair for example name equals subnet 1 and address prefix equals 10.100.0.0.24 a set of strings is a list of string values such as red green and blue the following example uses a map of the subnet names and ip address prefixes to build a subnet once the subnet is created we use a for expression to output the ids of each new subnet the best way to see how this works is to jump into vs code and create the module this example will skip over some of the terraform basic stuff covered in previous videos if something doesn't make sense go back to the playlist and check out the previous videos the link will be above and below let's get started in vs code here we are in vs code as i said earlier i'm skipping over some of the basics covered in the last videos the link to the playlist is below if you need to review also the code used for this example is available on github the link is below create a new folder called v-net and bastion host and in there create the files main.tf variables.tf outputs.tf and readme.md open main.tf and let's add the requirements provider and azure rm provider block don't forget to add the features argument to the provider block next let's add the resource group block we need to update the variables open variables.tf and create the variables for the resource group we'll add the resource group name the location and we're going to add tags it's a good idea to always use tags during deployments notice how the tag value is a map using multiple key value pairs let's go back to main.tf and we'll update the variables for the resource group let's do the same for the virtual network we'll add the resource block we need to create variables for the virtual network name and address space we already have the location resource group name and tags so let's go back to variables.tf here we'll add the variables for the vnet name and v-net address space we'll go back to main.tf and we'll update the name and the address space to reflect the new variables let's add the block for the subnets next and here we have the resource group name and the virtual network name already but we need the names of the subnets and the address prefixes this one is different we want to add any number of subnets so let's start by going to the variables.tf file will create a new variable with the local name subnets the type is map and the value is any now we'll add our defaults add subnet one and we're gonna supply two key value pairs here name the name is subnet1 next we'll add the address prefixes the prefix will be in square brackets that indicates it could be a list of values we'll only have one address prefix for subnet repeat these steps for two more subnets there they are with a little bit better formatting if you ever need to quickly format a document you can type control shift p type format and select format document or you could also do shift alt f one last item we're creating an azure bastion host next a bastion host requires its own subnet the subnet space has to be a slash 26 or larger and the name has to be azure bastion subnet the azure bastion service will dynamically manage the network security groups on that subnet that's why it needs its own so let's add that next now we have our map of subnet name and address prefixes click save and let's go back to the main.tf we're going to modify the azure subnet resource block a little bit first we're going to start the resource block arguments with a 4-h statement so now it's asking for each what we want it for each subnet so we'll enter var.subnets next is the name here's where we're going to use the subnet map the value of name is each dot value and then we enter name in square brackets the address prefix value is each dot value followed by address prefixes in square brackets this tells terraform to loop through all values in var.subnet and use the name and address prefix we provided for the value of each instance that's the basics of a for each resource loop next we'll create the public ip for the bastion host a bastion host doesn't need a public ip but we'll add it for this example we're going to use the bastion host name with pubip appended to the end for the public ip name let's create the bastion host name in our variables file we'll go back to main.tf and we'll update the name we covered this in a previous video but we're basically telling it to use the value of var dot bastion host underscore name and append public ipa to the end and that will give us the public ip address name for the bastion host public p address the public i p address has to be static and a standard ip those values are hard coded let's create the bastion host next the azure rm resource provider doesn't have the latest configuration for a bastion host there are two skus available for azure bastion basic and standard the provider only provisions the basic sku the bastion hosts resources fairly straightforward until we get to the ip configuration first notice the public ip address id this indicates it needs the id of the public id address not just the resource we'll do that by adding dot id to the end of the value next is the id for the subnet we could try to add azure rm underscore subnet dot subnet dot id but that won't work because the subnets were created with a for each block and there are four different ids we need to supply the id for the bastion subnet let's go back to variables.tf the local name for the bastion subnet is bastion underscore subnet let's go back to main.tf we can specify the subnet instance by supplying the local name of the subnet in square brackets after subnet it'll be better to show you now the subnet id points to a specific instance of a subnet we're almost done we still need to define outputs for this example we'll output the subnet ids of each of the newly created subnets let's save this file and go to outputs start an output block with the local name azure underscore subnet underscore id we'll add a value we'll put it in curly brackets and now we'll add the expression we're doing this because there are four different instances of subnet ids we'll use a four expression to output the value for each of those four subnets so we'll start that expression with four id and keys var.subnets that's followed by a colon id and then an equal and greater than sign that's just a separator because var.subnets is a map we need to have the separator between them after that we'll add azure rm underscore subnet dot subnet here we'll specify the id in the loop so it will return the specific subnet id and we'll end with id because we want to return the subnet ids don't forget to add a description this expression cycles through each value of var.subnet and uses that to return the subnet id the subnet and subnet id will display when deployed next we may want to connect to the bastion host by its public ip address at some point we can return that information with a second outlook block save the file before we deploy let's finish the readme file this is best practices when creating reusable modules let's save all the files and open up the terminal from here we'll run terraform in it and terraform plan that looks good notice at the bottom we'll have outputs once we apply let's apply this will take a few minutes to finish i'll pause here and come back once it's done there they are all the resources have been added and we have the subnet ids of the new subnet and public ip of the bastion host i hope this helps you understand for each loops and how to use them when creating terraform modules please don't forget to like subscribe and share with a friend thanks for watching
Info
Channel: Travis Roberts
Views: 12,557
Rating: undefined out of 5
Keywords: For_each, for each, Modules, outputs, outputs.tf, terraform outputs, terraform modules, Terraform.tfvars, variables, terraform variables, terraform var, Azure, Azure CLI, IaC Terraform, Terraform Registry, VSCode, Terraform for Azure, registry, .tf, HashiCorp, workdlow, Terraform Resource, .terraform, Terraform Write, Terraform Plan, Terraform Apply, Terraform Destroy, main.tf, terraform tutorial, terraform training, Terraform Examples
Id: RsDgtUZAugA
Channel Id: undefined
Length: 15min 5sec (905 seconds)
Published: Sun Dec 26 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.