Terraform能否通过数据源获取VPC中未关联互联网网关的私有子网?
Terraform自动识别私有子网并关联中转网关方案
问题1:预先不明确私有子网时,如何拉取并关联中转网关
完全可以实现,核心是通过路由表的路由规则特征自动识别私有子网——私有子网的典型特征是没有指向互联网网关(IGW)的默认路由(0.0.0.0/0)。以下是具体实现步骤和代码:
1. 扫描目标VPC和子网
先获取需要扫描的所有VPC,再拉取每个VPC下的所有子网:
# 获取目标VPC(可通过标签过滤,去掉tags可获取所有VPC) data "aws_vpcs" "target_vpcs" { tags = { Environment = "Production" } } # 获取每个VPC下的所有子网 data "aws_subnets" "per_vpc" { for_each = data.aws_vpcs.target_vpcs.ids vpc_id = each.value } # 获取每个VPC的主路由表(处理子网使用主路由表的场景) data "aws_vpc" "per_vpc" { for_each = data.aws_vpcs.target_vpcs.ids id = each.value } # 获取每个VPC关联的互联网网关 data "aws_internet_gateways" "per_vpc" { for_each = data.aws_vpcs.target_vpcs.ids vpc_id = each.value }
2. 获取子网对应的路由表
覆盖子网使用自定义路由表或VPC主路由表的场景:
# 获取每个子网关联的路由表 data "aws_route_table" "per_subnet" { for_each = toset(flatten([for vpc_subnets in data.aws_subnets.per_vpc : vpc_subnets.ids])) subnet_id = each.value } # 获取每个VPC的主路由表 data "aws_route_table" "main_per_vpc" { for_each = data.aws_vpcs.target_vpcs.ids route_table_id = data.aws_vpc.per_vpc[each.value].main_route_table_id }
3. 过滤出私有子网
通过检查路由表是否存在指向IGW的默认路由,自动筛选私有子网:
locals { private_subnets = merge([ for vpc_id, vpc in data.aws_vpc.per_vpc : { for subnet_id in data.aws_subnets.per_vpc[vpc_id].ids : subnet_id => subnet_id # 判断子网使用的是自定义路由表还是主路由表,再检查路由规则 if let rt = (data.aws_route_table.per_subnet[subnet_id].id == vpc.main_route_table_id) ? data.aws_route_table.main_per_vpc[vpc_id] : data.aws_route_table.per_subnet[subnet_id]; # 确认没有0.0.0.0/0指向IGW的路由 !anytrue([ for route in rt.routes : route.destination_cidr_block == "0.0.0.0/0" && contains(data.aws_internet_gateways.per_vpc[vpc_id].ids, route.gateway_id) ]) } ]...) }
4. 关联私有子网到中转网关
用for_each遍历筛选出的私有子网,自动创建中转网关关联:
# 定义中转网关(如果还未创建) resource "aws_transit_gateway" "main" { description = "Main Transit Gateway" } # 关联私有子网到中转网关 resource "aws_transit_gateway_vpc_attachment" "private_subnet_attach" { for_each = local.private_subnets vpc_id = data.aws_subnet[each.value].vpc_id subnet_ids = [each.value] transit_gateway_id = aws_transit_gateway.main.id tags = { Name = "TGW-Attachment-${each.value}" } }
问题2:找出VPC中所有未关联互联网网关的子网
本质上和私有子网判断逻辑一致——没有指向IGW的默认路由的子网,就是未关联互联网网关的子网。上面定义的local.private_subnets已经筛选出了这类子网。
如果需要单独输出这些子网的信息,可以添加:
output "unassociated_igw_subnets" { description = "Subnets without internet gateway association" value = local.private_subnets }
内容的提问来源于stack exchange,提问作者e-on
相关产品推荐
相关产品推荐

