如何在Terraform中按可用区获取唯一AWS子网ID解决TGW附件报错
解决Transit Gateway VPC挂载时每个可用区子网数量超限问题
原代码与报错信息
挂载资源配置
resource "aws_ec2_transit_gateway_vpc_attachment" "vpc_live" { subnet_ids = toset(data.aws_subnets.vpc_live.ids) transit_gateway_id = var.tgw_id vpc_id = var.vpc_id }
子网数据源配置
data "aws_subnets" "vpc_live" { filter { name = "vpc-id" values = [var.vpc_id] } }
执行报错
Error: updating EC2 Transit Gateway VPC Attachment (tgw-attach-xxxxxxxxxxxxxxx): InvalidParameterValue: AddSubnets values count greater than region availability zones │ status code: 400, request id: dnc3c5d-8927-029c-9fd5-311c3c5b5046 │ │ with aws_ec2_transit_gateway_vpc_attachment.vpc_live, │ on main.tf line 7, in resource "aws_ec2_transit_gateway_vpc_attachment" "vpc_live": │ 7: resource "aws_ec2_transit_gateway_vpc_attachment" "vpc_live" {
报错原因
Transit Gateway要求每个可用区(AZ)仅能关联一个子网,当前aws_subnets数据源会返回指定VPC下的所有子网,若部分AZ存在多个子网,就会触发该报错。
解决方案
通过Terraform的数据源与本地值处理,实现每个AZ仅保留一个子网ID:
# 原子网数据源保留 data "aws_subnets" "vpc_live" { filter { name = "vpc-id" values = [var.vpc_id] } } # 批量获取每个子网的可用区信息 data "aws_subnet" "vpc_live_subnets" { for_each = data.aws_subnets.vpc_live.ids id = each.value } # 按可用区分组,每个AZ仅保留一个子网ID locals { # 以AZ为键,自动覆盖同AZ下的重复子网,最终每个AZ对应一个子网ID subnet_per_az = { for subnet in data.aws_subnet.vpc_live_subnets : subnet.availability_zone => subnet.id } # 提取所有AZ对应的子网ID selected_subnet_ids = values(local.subnet_per_az) } # 调整挂载资源的子网ID引用 resource "aws_ec2_transit_gateway_vpc_attachment" "vpc_live" { subnet_ids = toset(local.selected_subnet_ids) transit_gateway_id = var.tgw_id vpc_id = var.vpc_id }
逻辑说明
- 通过
aws_subnet数据源批量获取每个子网的可用区属性; - 利用
for表达式创建以可用区为键的映射,同AZ下的子网会自动覆盖,确保每个AZ仅保留最后一个遍历到的子网ID(若需指定优先级,可先对子网ID排序后再处理); - 提取映射中的所有子网ID,作为Transit Gateway挂载的参数。
内容的提问来源于stack exchange,提问作者Tajinder
相关产品推荐
相关产品推荐

