You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform报错‘无法访问对象列表属性’:for_each资源属性访问问题

Terraform 解决“无法访问对象列表属性”问题

问题场景

使用for_each = toset(local.domains[*].domain_name)创建aws_apigatewayv2_domain_name资源后,尝试为每个域名实例创建对应的aws_route53_record和aws_api_gateway_base_path_mapping时,出现「无法访问对象列表上的属性」错误,且希望避免通过索引访问资源实例,直接迭代关联。

错误原因

  1. domain_name_configuration是嵌套块,Terraform会将其解析为列表类型(即使只定义了一个配置块),直接访问.domain_name_configuration.target_domain_name会因为列表未指定索引而报错。
  2. aws_apigatewayv2_domain_name.api_gateway是一个映射对象(键为域名字符串),不是列表,不能用[*]展开操作符,原代码中for_each = aws_apigatewayv2_domain_name.api_gateway[*].domain_name属于用法错误。

修复方案

1. 修复aws_route53_record资源

  • 保持for_each与域名集合一致,访问domain_name_configuration时添加索引[0](每个域名仅对应一个配置);
  • 直接通过each.key关联对应的域名实例。

2. 修复aws_api_gateway_base_path_mapping资源

  • 直接迭代aws_apigatewayv2_domain_name.api_gateway实例,无需再转换字符串集合,通过each.value直接获取实例属性。

修复后完整代码

resource "aws_apigatewayv2_domain_name" "api_gateway" {
  for_each = toset(local.domains[*].domain_name)

  domain_name = each.value

  domain_name_configuration {
    certificate_arn = var.certificate_arn == null ? aws_acm_certificate.cert[0].arn : var.certificate_arn
    endpoint_type   = "REGIONAL"
    security_policy = "TLS_1_2"
  }
}

resource "aws_route53_record" "api_gateway" {
  for_each = toset(local.domains[*].domain_name)

  name    = each.value
  type    = "A"
  zone_id = local.domain_to_hosted_zone[each.value]

  alias {
    name                   = aws_apigatewayv2_domain_name.api_gateway[each.key].domain_name_configuration[0].target_domain_name
    zone_id                = aws_apigatewayv2_domain_name.api_gateway[each.key].domain_name_configuration[0].hosted_zone_id
    evaluate_target_health = false
  }
}

resource "aws_api_gateway_base_path_mapping" "api_gateway" {
  # 直接迭代已创建的域名实例,无需重复处理字符串集合
  for_each = aws_apigatewayv2_domain_name.api_gateway

  api_id      = var.api_gateway_id
  stage_name  = var.api_gateway_stage
  domain_name = each.value.domain_name
}

关键说明

  • 对于嵌套块(如domain_name_configuration),Terraform始终将其视为列表,必须通过索引(如[0])访问单个元素的属性;
  • 当需要关联通过for_each创建的资源时,优先直接迭代资源实例(如aws_apigatewayv2_domain_name.api_gateway),这样可以直接获取实例的所有属性,避免字符串匹配的冗余和错误;
  • each.key对应for_each集合的键(此处为域名),each.value对应资源实例本身(当for_each直接引用资源映射时)。

内容的提问来源于stack exchange,提问作者Shuzheng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:54:51