Terraform嵌套循环批量创建多VPC关联子网实现方法
问题原因
当前配置无法完成子网和VPC关联的核心问题有两点:
subnets变量的对象结构没有标记子网所属的VPC,无法建立映射关系- 现有
subnets默认值存在配置错误:最后一个UZ的公网B子网错误使用了RU-Public-B作为key,会覆盖前一个同key的RU子网配置,同时该子网CIDR和UZ-Public-A重复,本身定义无效。
实现方案
Terraform的for_each不支持直接嵌套循环,处理这种多资源关联场景的核心思路是:先给资源建立明确的映射键,再通过键索引已经创建的父资源,不需要特殊嵌套语法。
第一步:修正subnets变量
给子网对象新增vpc_key字段,值和var.vpcs中的键名一一对应,同时修复原有配置的错误:
variable "subnets" { type = map(object({ vpc_key = string # 新增:标记子网所属VPC的键,和var.vpcs的key对应 cidr = string az = string tags = map(string) })) default = { "RU-Public-A" = { vpc_key = "RU" az = "us-east-1a" cidr = "10.0.1.0/24" tags = { Name = "RU-Public-A" } } "RU-Public-B" = { vpc_key = "RU" az = "us-east-1b" cidr = "10.0.2.0/24" tags = { Name = "RU-Public-B" } } "UZ-Public-A" = { vpc_key = "UZ" az = "us-east-1a" cidr = "192.168.1.0/24" tags = { Name = "UZ-Public-A" } } "UZ-Public-B" = { # 修复原重复key问题 vpc_key = "UZ" az = "us-east-1b" cidr = "192.168.2.0/24" # 修复原重复CIDR问题 tags = { Name = "UZ-Public-B" } } } }
第二步:补全公网子网资源块
直接遍历所有子网,通过vpc_key索引已经创建的VPC资源拿到对应VPC ID即可完成关联:
resource "aws_subnet" "public" { for_each = var.subnets vpc_id = aws_vpc.main[each.value.vpc_key].id cidr_block = each.value.cidr availability_zone = each.value.az map_public_ip_on_launch = true # 公网子网必须开启,否则实例默认不分配公网IP tags = each.value.tags }
第三步(可选):补充公网路由配置
仅创建子网和IGW无法让子网获得公网通信能力,需要补充公网路由表并关联子网:
# 每个VPC创建独立公网路由表 resource "aws_route_table" "public" { for_each = aws_vpc.main vpc_id = each.value.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main[each.key].id } tags = { Name = "${each.key}-Public-RT" } } # 关联所有公网子网到对应VPC的公网路由表 resource "aws_route_table_association" "public" { for_each = aws_subnet.public subnet_id = each.value.id route_table_id = aws_route_table.public[each.value.vpc_key].id }
注意事项
不建议通过CIDR网段包含关系自动匹配所属VPC,这种方式在网段重叠时会出现关联错误,生产环境下显式声明关联关系的可维护性和容错率更高。
配置完成后执行terraform plan即可验证所有子网和VPC的关联关系是否正确。
内容的提问来源于stack exchange,提问作者Sergey
相关产品推荐
相关产品推荐

