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

遍历Terraform Locals未触发基础设施变更问题排查

问题与解决

问题背景

我的Terraform locals定义如下:

locals {
  preprocessed = {
    "first" = {
      tags = {
        name = "test"
        env  = "dev"
      }
      users = [
        "Admin",
        "DataEng"
      ]
      group_parameters = [
        {
          name         = "rds.logical_replication"
          value        = "1"
          apply_method = "pending-reboot"
        }
      ]
    }
  
  processed = {
        for instance, settings in local.preprocessed : instance => {
          tags = settings.tags
          user_roles = [
            for role in settings.admin_user_roles : 
              "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${role}"
            ]
          group_parameters = settings.group_parameters
       }
     }
 }

通过terraform console验证,预期的processed结果应为:

processed = {
    "first" = {
      "group_parameters" = [
        {
          "apply_method" = "pending-reboot"
          "name"         = "rds.logical_replication"
          "value"        = "1"
        }
      ]
      "tags" = {
        "env"    = "dev"
        "name"   = "test"
      }
      "user_roles" = [
        "arn:aws:iam::123456789123:role/Admin",
        "arn:aws:iam::123456789123:role/DataEng"
      ]
    }
  }

但使用该processed遍历创建KMS密钥模块时:

module "kms_key" {
  for_each = local.processed

  source                     = "git@github.com:xyz/kms.git?ref=v1.0"
  external_access_principals = each.value["user_roles"]
  key_alias                  = each.key
  key_description            = "key to encrypt ${each.key} instance"
  tags                       = each.key.tags
}

执行terraform plan/apply时输出No changes. Your infrastructure matches the configuration.,无资源创建;但将local.processed替换为静态的预期结果时,Terraform能正常触发创建。

问题原因与修复

1. 字段引用错误:settings.admin_user_roles不存在

在processed的user_roles生成逻辑中,你引用了settings.admin_user_roles,但preprocessed里对应的字段是users,而非admin_user_roles。这会导致user_roles生成空列表,如果KMS模块对external_access_principals的空值有跳过逻辑(比如没有符合条件的主体则不创建资源),就会出现无变更的情况。

修复代码:

user_roles = [
  for role in settings.users : 
    "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${role}"
]

2. 模块参数引用错误:each.key.tags无效

模块调用中,each.key是processed的键(字符串"first"),字符串没有tags属性,正确的引用应该是each.value.tags。这个错误可能被模块的可选参数逻辑忽略,但叠加第一个错误会加剧异常。

修复后的模块调用:

module "kms_key" {
  for_each = local.processed

  source                     = "git@github.com:xyz/kms.git?ref=v1.0"
  external_access_principals = each.value["user_roles"]
  key_alias                  = each.key
  key_description            = "key to encrypt ${each.key} instance"
  tags                       = each.value.tags
}

3. 验证方式

在terraform console中直接执行local.processed,查看实际生成的user_roles是否为空列表,即可确认第一个问题的存在——你之前验证时可能手动修改了字段名,才得到了预期结果,但实际代码未修正。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 00:35:16