|
| 1 | +# VPC Module |
| 2 | + |
| 3 | +Here is the main page of the [Terraform Registry](https://registry.terraform.io/). We've already gone into the Providers section, so now let's go into the Modules section. If we look to the left, we can filter by Provider for the modules that we want. |
| 4 | + |
| 5 | +The module we actually want is the vpc module, which happens to be the top module here. So let's go ahead and click on that module. Within this module, I want to point out a few things. It has a basic set of instructions on how to use the module. It also provides the source code for the module on GitHub. So if you want to view what's actually in the module, you can click through on that link and view it yourself. Scrolling down a little bit, we have a README section, which describes how to potentially use this module. And then it also gives us a list of inputs that are accepted by the module, output values that are given by the module, any dependencies and the resources that would be created by the module. A lot of this is dependent on the inputs you give the module. |
| 6 | + |
| 7 | +We're going to be setting up a fairly basic VPC, so we can simply copy this example and paste it into our configuration and then make some simple updates. Let's do that now. |
| 8 | + |
| 9 | +```ini |
| 10 | +# copy from terraform.io |
| 11 | +module "vpc" { |
| 12 | + source = "terraform-aws-modules/vpc/aws" |
| 13 | + |
| 14 | + name = "my-vpc" |
| 15 | + cidr = "10.0.0.0/16" |
| 16 | + |
| 17 | + azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"] |
| 18 | + private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] |
| 19 | + public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] |
| 20 | + |
| 21 | + enable_nat_gateway = true |
| 22 | + enable_vpn_gateway = true |
| 23 | + |
| 24 | + tags = { |
| 25 | + Terraform = "true" |
| 26 | + Environment = "dev" |
| 27 | + } |
| 28 | +} |
| 29 | + |
| 30 | +``` |
| 31 | + |
| 32 | +* Update `network.tf` |
| 33 | + |
| 34 | +```ini |
| 35 | +module "vpc" { |
| 36 | + source = "terraform-aws-modules/vpc/aws" |
| 37 | + |
| 38 | + name = "my-vpc" |
| 39 | + cidr = "10.0.0.0/16" |
| 40 | + |
| 41 | + azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"] |
| 42 | + private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] |
| 43 | + public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] |
| 44 | + |
| 45 | + enable_nat_gateway = true |
| 46 | + enable_vpn_gateway = true |
| 47 | + |
| 48 | + tags = { |
| 49 | + Terraform = "true" |
| 50 | + Environment = "dev" |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | + |
| 55 | +################################################################################## |
| 56 | +# DATA |
| 57 | +################################################################################## |
| 58 | + |
| 59 | +``` |
| 60 | + |
| 61 | +And, we are going to be replacing a bunch of resources with this. We're going to be replacing the vpc, the internet_gateway, the subnets, the route_table, and the route_table_associations, all with this module. That's a lot of resources that we no longer have to manage. |
| 62 | + |
| 63 | +Let's scroll back up to the top and paste in the module example. Since this module is from the Terraform Registry, we should definitely add a version argument to pin it to a specific version. This way, if the module is updated in a way that breaks our configuration, we can test it in a development environment before upgrading to the newest version of the module. |
| 64 | + |
| 65 | +```diff |
| 66 | +module "vpc" { |
| 67 | + source = "terraform-aws-modules/vpc/aws" |
| 68 | ++ version = "=5.5.1" |
| 69 | + |
| 70 | + name = "my-vpc" |
| 71 | + cidr = "10.0.0.0/16" |
| 72 | + |
| 73 | +``` |
| 74 | + |
| 75 | +If we go back to the browser, we can see the current version is 5.4.0. So let's go ahead and pin it to 5.4.0 for now. We'll set the version = to 5.5.1, and this way it will only use that version until we change this argument. |
| 76 | + |
| 77 | +Okay, now we need to update some of the values that are used for the arguments here. We'll first delete the name argument since we'll be submitting that through our tags. |
| 78 | + |
| 79 | +```diff |
| 80 | +module "vpc" { |
| 81 | + source = "terraform-aws-modules/vpc/aws" |
| 82 | + version = "=5.5.1" |
| 83 | + |
| 84 | +- name = "my-vpc" |
| 85 | + cidr = "10.0.0.0/16" |
| 86 | +``` |
| 87 | + |
| 88 | + |
| 89 | +Next, we'll update the cidr block to use our variable. |
| 90 | + |
| 91 | +```diff |
| 92 | +module "vpc" { |
| 93 | + source = "terraform-aws-modules/vpc/aws" |
| 94 | + version = "=5.4.0" |
| 95 | + |
| 96 | +- cidr = "10.0.0.0/16" |
| 97 | ++ cidr = var.vpc_cidr_block |
| 98 | +``` |
| 99 | + |
| 100 | +For the availability zones argument, we want to give it a list of availability zone names that's equal to the number of subnets that we're currently using. To do that, we can use the slice function to slice off a list of names from the availability zones data source. Let's see how we do that. |
| 101 | + |
| 102 | +```diff |
| 103 | +module "vpc" { |
| 104 | + source = "terraform-aws-modules/vpc/aws" |
| 105 | + version = "=5.5.1" |
| 106 | + |
| 107 | + cidr = var.aws_vpc_cidr_block |
| 108 | + |
| 109 | +- azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"] |
| 110 | ++ azs = slice(data.aws_availability_zones.available.names, 0, (var.vpc_subnet_count)) |
| 111 | + private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] |
| 112 | + public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] |
| 113 | + |
| 114 | +``` |
| 115 | + |
| 116 | +The `slice` function takes a list as input and then slices off a portion of that list for use. We'll specify the data source aws_availability_zones.names. |
| 117 | + |
| 118 | +The next argument is the starting index for the slice. We'll start at the first element in the names list. The last argument is the ending index of our slice, and it is not inclusive, so it won't include that element in our list. We'll set that to var.vpc_subnet_count. So when our subnet count is 2, it will return 2 availability zone names and it will already be in a list format. |
| 119 | + |
| 120 | +Okay, for the private_subnets, we don't have any private subnets, so we can go ahead and delete the private_subnets. |
| 121 | + |
| 122 | +```diff |
| 123 | +module "vpc" { |
| 124 | + source = "terraform-aws-modules/vpc/aws" |
| 125 | + version = "=5.5.1" |
| 126 | + |
| 127 | + cidr = var.aws_vpc_cidr_block |
| 128 | + |
| 129 | + azs = slice(data.aws_availability_zones.available.names, 0, (var.vpc_subnet_count)) |
| 130 | +- private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] |
| 131 | + public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] |
| 132 | +``` |
| 133 | + |
| 134 | +For the public_subnets, we are going to need to calculate a list of public subnet CIDR ranges for our public subnets. Let's look at how we've done this already. If we scroll down to our subnets, we compute the CIDR block using the cidrsubnet function and the count.index since we're creating our subnets and accounts. We're no longer generating our subnets in account, so we need an alternate way to generate this list of CIDR subnets. |
| 135 | + |
| 136 | +The way that we'll do that is with a for expression. I briefly mentioned for expressions in the previous module, now it's time to dig into those a little more deeply. |
0 commit comments