如何在Terraform中从map提取去重可用区列表并创建对应NAT网关
实现方案
你可以通过Terraform的locals做数据预处理,先按可用区(AZ)分组公网子网并去重,再基于去重后的AZ列表创建EIP和NAT网关即可,具体配置如下:
步骤1:添加本地值预处理子网数据
先定义本地值生成「AZ对应公网子网」的映射,自动完成AZ去重,每个AZ取一个公网子网用于部署NAT网关:
locals { # 按AZ分组所有公网子网,自动去重AZ,每个AZ保留第一个公网子网 az_to_public_subnet = { for az, subnets in groupby([for subnet_key, subnet_obj in aws_subnet.public-subnets : subnet_obj.availability_zone => subnet_obj]) : az => subnets[0] } }
步骤2:调整EIP资源(可选,按AZ创建避免多余EIP浪费)
如果你的公网子网可能存在同AZ多子网的情况,建议把EIP的遍历对象修改为上面的AZ映射,保证每个AZ只创建1个EIP:
resource "aws_eip" "ip-nats" { for_each = local.az_to_public_subnet # EIP创建依赖IGW存在的规则保留 depends_on = [aws_internet_gateway.igw] tags = { Name = "nat-eip-${each.key}" } }
步骤3:创建NAT网关资源
直接遍历AZ映射创建NAT网关,每个AZ对应1个,参数自动关联对应EIP和子网:
resource "aws_nat_gateway" "az_nat" { for_each = local.az_to_public_subnet allocation_id = aws_eip.ip-nats[each.key].id subnet_id = each.value.id tags = { Name = "nat-gw-${each.key}" } }
配置说明
groupby函数会自动按AZ把公网子网分组,天然实现AZ去重,不需要额外写去重逻辑- 每个AZ的NAT网关会部署在该AZ的第一个公网子网上,自动关联对应AZ的EIP
- 如果后续
var.public_subnets新增AZ的子网,会自动在新AZ创建对应NAT网关,不需要修改逻辑代码
内容的提问来源于stack exchange,提问作者user2650277
相关产品推荐
相关产品推荐

