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

Terraform使用for_each调用IAM策略数据源时JSON策略无效问题排查

问题

在aws_ssoadmin_permission_set_inline_policy资源中,尝试用for_each遍历本地变量permission_sets_name中的名称,对应引用同名的aws_iam_policy_document数据源。但用format函数拼接data.aws_iam_policy_document.%s.json时,Terraform提示“inline_policy包含无效JSON策略”;直接硬编码数据源名称(如data.aws_iam_policy_document.emobg-sso-billing-admin.json)则能正常运行。

相关代码:

data "aws_iam_policy_document" "emobg-sso-billing-admin" {
  statement {
    sid    = "VisualEditor0"
    effect = "Allow"
    actions = [
      "aws-marketplace:*",
      "aws-portal:*",
      "budgets:*"
    ]
    resources = [
      "*",
    ]
  }
}

data "aws_iam_policy_document" "emobg-sso-billing-audit" {
  statement {
    sid    = "VisualEditor0"
    effect = "Allow"
    actions = [
      "support:*",
      "tag:*",
      "s3:*"
    ]
    resources = [
      "*",
    ]
  }
}

resource "aws_ssoadmin_permission_set" "emobg" {
  for_each = toset(local.permission_sets_name)

  name             = each.key
  description      = each.key
  instance_arn     = local.sso_instance_arn
  session_duration = local.session_duration
}

resource "aws_ssoadmin_permission_set_inline_policy" "emobg" {
  for_each           = toset(local.permission_sets_name)

  inline_policy      = format("data.aws_iam_policy_document.%s.json", each.key) # <-- 不生效
#  inline_policy      = data.aws_iam_policy_document.emobg-sso-billing-admin.json # <-- 生效
  instance_arn       = local.sso_instance_arn
  permission_set_arn = aws_ssoadmin_permission_set.emobg[each.key].arn
}

locals {
  session_duration    = "PT8H"

  permission_sets_name = [
    "emobg-sso-billing-admin",
    "emobg-sso-billing-audit",
  ]
}

错误信息:

2022-11-01T01:19:43.923+0100 [ERROR] vertex "aws_ssoadmin_permission_set_inline_policy.emobg[\"emobg-sso-billing-admin\"]" error: "inline_policy" contains an invalid JSON policy
2022-11-01T01:19:43.923+0100 [ERROR] vertex "aws_ssoadmin_permission_set_inline_policy.emobg (expand)" error: "inline_policy" contains an invalid JSON policy
╷
│ Error: "inline_policy" contains an invalid JSON policy
│
│   with aws_ssoadmin_permission_set_inline_policy.emobg["emobg-sso-billing-admin"],
│   on permission_set.tf line 13, in resource "aws_ssoadmin_permission_set_inline_policy" "emobg":
│   13:   inline_policy      = format("data.aws_iam_policy_document.%s.json", each.value)

疑惑:逻辑上两种方式应该一致,为何JSON策略会无效?

解决方法

你用format函数生成的是字符串字面量(比如"data.aws_iam_policy_document.emobg-sso-billing-admin.json"),而不是Terraform对数据源属性的引用。Terraform会把这个字符串直接当作JSON策略内容,显然这不是合法的JSON,所以报错。

要动态引用同名的数据源属性,需要用Terraform的动态索引语法,直接通过数据源的索引访问:

修正后的代码

修改aws_ssoadmin_permission_set_inline_policy中的inline_policy字段:

resource "aws_ssoadmin_permission_set_inline_policy" "emobg" {
  for_each           = toset(local.permission_sets_name)

  inline_policy      = data.aws_iam_policy_document[each.key].json # 正确的动态引用方式
  instance_arn       = local.sso_instance_arn
  permission_set_arn = aws_ssoadmin_permission_set.emobg[each.key].arn
}

原理说明

  • Terraform中,当资源/数据源的名称是动态值时,不能用.拼接字符串来引用,而要通过[动态键]的索引语法访问。
  • data.aws_iam_policy_document[each.key]会找到名称匹配each.key的数据源实例,再访问其.json属性,得到真正的JSON策略内容,这样就能被Terraform正确识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:00:59