使用terraform-0.7.7 . 我或多或少地关注最佳实践回购,AWS部分:
https://github.com/hashicorp/best-practices/tree/master/terraform
我试图想出一个用于构建VPC的通用模板 . 我们的想法是拥有一个带有多个子模块的 network
模块(vpc,private_subnet等),并且只需从terraform.tfvars文件中插入不同的变量,以构建不同的环境 .
假设在一个环境的.tfvars文件中我有一个可用区列表,另一个列表包含私有子网的IP块:
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"
network / private_subnets模块将根据这些列表愉快地创建子网,路由表和关联:
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 }
}
这很好用 . 对于每个环境,我有不同的 azs
和 private_subnets
列表,并且正确创建了VPC . NAT网关在此之前在不同的模块中创建 . 每个AZ我有一个NAT网关,一个私有子网和一个私有路由表 .
但现在我正在尝试以相同的方式创建VPC对等连接 .
peer_vpc_ids = "vpc-XXXXXXXX, vpc-YYYYYYYY"
peer_vpc_blocks = "10.XXX.0.0/16, 10.YYY.0.0/16"
所以现在我需要编写进入私有路由表的Terraform代码,并为每个VPC对等连接添加路由 .
问题是,我需要迭代两个变量:AZ列表和对等连接列表,而Terraform似乎不允许这样做 . AFAICT,你不能在Terraform中做嵌套循环 .
我错过了什么吗?有没有更好的方法来解决这个问题?
当然,我可以手工编写一些自定义意大利面条代码,无论如何构建VPC,但这里的目标是保持代码可组合和可维护,并将逻辑与属性分开 .
1 回答
你可以通过
element
插值方法的一些数学来实现这个目的:具体来说,
element(var.vpc_blocks,floor(count.index / length(var.vpc_ids))
调用将使每个var.vpc_ids
值的VPC块递增1 .