New to Terraform and trying to create the following VPC from Adrian Cantril's class using the DRY method.
I can get the first 4 subnets created but when I try to repeat it, it duplicates it per AZ giving me an error.
I have tried a few other things that created 1 subnet per AZ, e.g. 10.16.0.0/20 in AZ A, 10.16.16.0 /20 in AZ B, etc..
Below is a snippet of the code I am using.
variable "vpc_cidr" {
type = string
default = "10.16.0.0/16"
}
resource "aws_subnet" "private_subnets-az-a" {
count = 4
vpc_id = aws_vpc.vpc.id
cidr_block = cidrsubnet(var.vpc_cidr, 4, count.index)
availability_zone = data.aws_availability_zones.available.names[0]
}
resource "aws_subnet" "private_subnets-az-b" {
count = 4
vpc_id = aws_vpc.vpc.id
cidr_block = cidrsubnet(var.vpc_cidr, 4, count.index)
availability_zone = data.aws_availability_zones.available.names[1]
This should be pretty DRY:
locals {
region = "us-east-1"
subnets = {
for i, v in setproduct(["a", "b", "c"], ["reserved", "db", "app", "web"]) :
"${local.region}${v[0]}-${v[1]}" =>
{
az = "${local.region}${v[0]}"
cidr = cidrsubnet("10.16.0.0/16", 4, i)
}
}
}
resource "aws_subnet" "this" {
for_each = local.subnets
vpc_id = aws_vpc.vpc.id
cidr_block = each.value.cidr
availability_zone = each.value.az
}
This will create 12 subnets as per the diagram.
locals.subnets
looks like this:
subnets = {
"us-east-1a-reserved" = {
"az" = "us-east-1a"
"cidr" = "10.16.0.0/20"
}
"us-east-1a-db" = {
"az" = "us-east-1a"
"cidr" = "10.16.16.0/20"
}
"us-east-1a-app" = {
"az" = "us-east-1a"
"cidr" = "10.16.32.0/20"
}
"us-east-1a-web" = {
"az" = "us-east-1a"
"cidr" = "10.16.48.0/20"
}
"us-east-1b-reserved" = {
"az" = "us-east-1b"
"cidr" = "10.16.64.0/20"
}
// ... and so on
}
This for_each
approach is more usable than the count
variants because you can access the created subnets as follows: aws_subnet.this["us-east-1a-reserved"].arn
as opposed to aws_subnet.this[3].arn
.
See setproduct and for expressions to understand what's going on in locals.subnets
.
On a related note, it's a good idea to try to create a VPC and subnets from scratch when you are learning, but if you go to production, I'd recommend using this Terraform VPC module - https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest.