Using terraform-0.7.7. I'm following, more or less, the Best Practices repo, the AWS part:
https://github.com/hashicorp/best-practices/tree/master/terraform
I am trying to come up with a general template for building VPCs. The idea is to have a network
module with several sub-modules (vpc, private_subnet, etc), and just plug into it different variables from terraform.tfvars files, in order to build different environments.
Let's say in the .tfvars file for one environment I have a list of availability zones, and another list with the IP blocks for the private subnets:
azs = "us-west-2a,us-west-2b,us-west-2c"
private_subnets = "10.XXX.1.0/24,10.XXX.2.0/24,10.XXX.3.0/24"
The network/private_subnets module will happily create subnets, route tables, and associations based on those lists:
resource "aws_subnet" "private" {
vpc_id = "${var.vpc_id}"
cidr_block = "${element(split(",", var.cidrs), count.index)}"
availability_zone = "${element(split(",", var.azs), count.index)}"
count = "${length(split(",", var.cidrs))}"
tags { Name = "${var.name}-${element(split(",", var.azs), count.index)}-private" }
lifecycle { create_before_destroy = true }
}
resource "aws_route_table" "private" {
vpc_id = "${var.vpc_id}"
count = "${length(split(",", var.cidrs))}"
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = "${element(split(",", var.nat_gateway_ids), count.index)}"
}
tags { Name = "${var.name}-${element(split(",", var.azs), count.index)}-private" }
lifecycle { create_before_destroy = true }
}
resource "aws_route_table_association" "private" {
count = "${length(split(",", var.cidrs))}"
subnet_id = "${element(aws_subnet.private.*.id, count.index)}"
route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
lifecycle { create_before_destroy = true }
}
That works well. For each environment, I have different azs
and private_subnets
lists, and the VPC is created correctly. The NAT gateways are created prior to that in a different module. I have one NAT gateway, one private subnet, and one private routing table, per AZ.
But now I'm trying to create VPC peering connections in the same way.
peer_vpc_ids = "vpc-XXXXXXXX, vpc-YYYYYYYY"
peer_vpc_blocks = "10.XXX.0.0/16, 10.YYY.0.0/16"
So now I need to write Terraform code that goes into the private route tables and adds routes for each VPC peering connection.
The problem is, I need to iterate by two variables: the list of AZs, and the list of peering connections, and Terraform does not seem to allow that. AFAICT, you cannot do nested loops in Terraform.
Am I missing something? Is there a better way to solve this problem?
Of course I could write by hand some custom spaghetti code that would build the VPC no matter what, but the goal here is to keep the code composable and maintainable, and separate the logic from the attributes.