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

Terraform模板循环移除IAM信任策略最后元素逗号的问题

解决Terraform生成IAM信任策略时JSON末尾逗号问题

环境信息

❯ terraform version
Terraform v1.6.3
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v5.29.0

问题

通过Terraform构建AWS IAM信任策略时,使用templatefile函数生成策略内容,循环生成的Statement数组最后一个元素末尾会保留逗号,导致JSON格式无效,无法导入AWS IAM。

尝试两种if条件写法移除逗号均触发模板语法错误:

  • 第一种报错:Invalid template directive; 需以模板指令关键字开头
  • 第二种报错:Extra characters in if marker; 标记中存在多余字符

调整后执行terraform plan,输出中最后一个元素仍带有逗号,需解决JSON格式合法性问题。

现有代码及输出

模板文件(template.tpl)

{    "Statement": [        %{ for oidc in oidcs ~}        {                    "${oidc}:aud": "sts.amazon.com",                    "${oidc}:sub": "system:serviceaccount:${sa}"        },        %{ endfor ~}    ]}

Terraform代码

locals {
  backend_config_content = templatefile("${path.module}/json/template.tpl", {
    sa     = "kube-system:ebs-csi-controller-sa",
    account = "804616344559",
    oidcs = [        "id/4ECE95AF53127CE866BA",         "id/9173553CA62864"        ]
  })
}

output "generated_trust_policy" {
  value = local.backend_config_content
}

Terraform Plan输出

❯ terraform plan
Changes to Outputs:
  + iam = jsonencode(
        {
          + Statement = [
              + {
                  + "id/4ECE95AF53127CE866BA:aud" = "sts.amazon.com"
                  + "id/4ECE95AF53127CE866BA:sub" = "system:serviceaccount:kube-system:ebs-csi-controller-sa"
                },
              + {
                  + "id/9173553CA62864:aud" = "sts.amazon.com"
                  + "id/9173553CA62864:sub" = "system:serviceaccount:kube-system:ebs-csi-controller-sa"
                },
            ]
        }
    )

解决方法

方法1:用jsonencode直接生成(推荐)

放弃手写JSON模板,用HCL结构构建策略,再通过jsonencode自动转换为合法JSON,彻底避免手动处理逗号的问题:

locals {
  sa = "kube-system:ebs-csi-controller-sa"
  oidcs = ["id/4ECE95AF53127CE866BA", "id/9173553CA62864"]

  trust_policy = jsonencode({
    Statement = [
      for oidc in local.oidcs : {
        "${oidc}:aud" = "sts.amazon.com"
        "${oidc}:sub" = "system:serviceaccount:${local.sa}"
      }
    ]
  })
}

output "generated_trust_policy" {
  value = local.trust_policy
}

方法2:修正模板循环逻辑

若必须使用模板文件,可在循环中判断当前元素是否为最后一个,仅在前序元素后添加逗号:

修改后的模板文件:

{
  "Statement": [
    %{ for idx, oidc in oidcs ~}
    {
      "${oidc}:aud": "sts.amazon.com",
      "${oidc}:sub": "system:serviceaccount:${sa}"
    }%{ if idx != length(oidcs)-1 },%{ endif ~}
    %{ endfor ~}
  ]
}

说明:通过idx获取循环索引,length(oidcs)-1对应最后一个元素的索引,仅当当前元素不是最后一个时才添加逗号;~符号用于控制空白字符,避免生成多余的空格或换行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:35:32