使用Terraform为S3 VPC终端节点关联多路由表报错求助
问题:AWS S3 VPC终端节点无法关联多个路由表
我可以给AWS S3 VPC终端节点关联单个路由表,但关联多个时触发以下错误:
STDERR: Error: Invalid index on aws_vpc_endpoints/locals.tf line 30, in locals: 30: route_table_name = rtb[idx]} ] if endp.service_name == "s3" ]]) This value does not have any indices.
我们尝试通过locals中的endp_list和rtb_list整理VPC名称、子网名称、路由表名称等数据,相关Terraform代码如下:
变量定义
variable "vpc_endpoints" { type = list(object({ vpc_name = string vpc_cidr = list(string) service = list(object({ service_name = string subnet_names = optional(list(string)) route_table_names = optional (list(string)) })) })) }
变量值
VPC_Endpoints = [ { vpc_name = "TEST-VPC" vpc_cidr = ["X.X.X.X/X"] service = [ { service_name = "s3", route_table_names = ["Subnet1A", "Subnet1B"] subnet_names = [] } ] } ]
修复后的完整代码
data "aws_route_tables" "s3_list" { # 用VPC+服务+路由表名称生成唯一键,避免多个路由表共用同一数据源实例 for_each = { for endp in local.rtb_list : "${endp.vpc_name}-${endp.service_name}-${endp.route_table_name}" => endp if endp.service_name == "s3"} filter { name = "tag:Name" values = [each.value.route_table_name] } } locals{ endp_list = flatten([ for vpc in var.vpc_endpoints : [ for endp in vpc.service: { vpc_name = vpc.vpc_name, service_name = endp.service_name, subnet_names = endp.subnet_names, route_table_names = endp.route_table_names, }]]) # 修复索引错误:rtb是单个路由表名称字符串,直接使用即可 rtb_list = flatten([ for vpc in var.vpc_endpoints : [ for endp in vpc.service: [ for idx, rtb in endp.route_table_names: { vpc_name = vpc.vpc_name, service_name = endp.service_name, route_table_name = rtb} ] if endp.service_name == "s3" ]]) } resource "aws_vpc_endpoint" "s3" { for_each = { for endp in local.endp_list : "${endp.vpc_name}-${endp.service_name}" => endp if endp.service_name == "s3" } vpc_id = data.aws_vpc.vpc[each.value.vpc_name].id service_name = data.aws_vpc_endpoint_service.s3.service_name } resource "aws_vpc_endpoint_route_table_association" "s3_endpoint1_private" { # 用唯一键标识每个路由表关联 for_each = { for rtb in local.rtb_list : "${rtb.vpc_name}-${rtb.service_name}-${rtb.route_table_name}" => rtb if rtb.service_name == "s3" } vpc_endpoint_id = aws_vpc_endpoint.s3["${each.value.vpc_name}-${each.value.service_name}"].id # 从路由表数据源的ids列表中取第一个结果 route_table_id = data.aws_route_tables.s3_list[each.key].ids[0] }
错误原因与修复说明
- 索引访问错误:原
rtb_list中rtb[idx]是错误写法——rtb已经是route_table_names列表中的单个字符串元素,直接使用rtb即可获取路由表名称,无需通过索引访问。 - 路由表数据源键重复:原
data "aws_route_tables" "s3_list"的for_each键仅用VPC+服务会导致多个路由表共用同一个数据源实例,改为VPC+服务+路由表名称确保每个路由表对应唯一数据源。 - 关联资源的路由表ID引用:
aws_route_tables数据源返回的是ids列表,需通过ids[0]获取具体路由表ID;同时关联资源的for_each改用包含路由表名称的唯一键,避免索引冲突。
内容的提问来源于stack exchange,提问作者Swapnil
相关产品推荐
相关产品推荐

