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

Terraform创建AWS IAM角色策略出现MalformedPolicyDocument错误求助

问题根因分析
  • 你遇到的MalformedPolicyDocument: The policy failed legacy parsing报错并不是原生JSON格式有问题,而是AWS IAM的legacy解析器对策略动态插值后的内容校验不通过,核心触发点有两个:
  1. 你当前手写heredoc内嵌插值变量的方式,插值后如果变量返回值包含特殊字符、或者索引越界返回空值,会直接导致策略结构异常,普通JSON校验工具只能校验静态文本,无法检测插值后的实际输出
  2. IAM legacy解析器对单元素数组的兼容性较差,你代码中第一句Statement的"Resource": ["*"]是单元素数组,legacy解析器大概率无法识别,要求改为字符串格式"Resource": "*"
修复方案

临时修复(直接改现有代码)

修改两处内容即可:

  1. 把第一句Statement的单元素Resource数组改为字符串
  2. 确认aws_subnet.private.*.id的返回值最少有2个,避免element取索引1时报空值
    修改后的代码如下:
policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateNetworkInterface",
        "ec2:DescribeDhcpOptions",
        "ec2:DescribeNetworkInterfaces",
        "ec2:DeleteNetworkInterface",
        "ec2:DescribeSubnets",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeVpcs"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateNetworkInterfacePermission"
      ],
      "Resource": [
        "arn:aws:ec2:${var.REGION}:network-interface/*"
      ],
      "Condition": {
        "StringEquals": {
          "ec2:Subnet": [
            "${element(aws_subnet.private.*.id, 0)}",
            "${element(aws_subnet.private.*.id, 1)}"
          ],
          "ec2:AuthorizedService": "codebuild.amazonaws.com"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:*"
      ],
      "Resource": [
        "${aws_s3_bucket.codebuild.arn}",
        "${aws_s3_bucket.codebuild.arn}/*"
      ]
    }
  ]
}
POLICY

最优修复(推荐)

使用Terraform官方提供的aws_iam_policy_document数据源生成策略,自动处理JSON转义和语法兼容性,完全规避legacy解析错误,示例代码如下:

data "aws_iam_policy_document" "codebuild_policy" {
  statement {
    effect = "Allow"
    actions = [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents"
    ]
    resources = ["*"]
  }

  statement {
    effect = "Allow"
    actions = [
      "ec2:CreateNetworkInterface",
      "ec2:DescribeDhcpOptions",
      "ec2:DescribeNetworkInterfaces",
      "ec2:DeleteNetworkInterface",
      "ec2:DescribeSubnets",
      "ec2:DescribeSecurityGroups",
      "ec2:DescribeVpcs"
    ]
    resources = ["*"]
  }

  statement {
    effect = "Allow"
    actions = ["ec2:CreateNetworkInterfacePermission"]
    resources = ["arn:aws:ec2:${var.REGION}:network-interface/*"]
    condition {
      test     = "StringEquals"
      variable = "ec2:Subnet"
      values   = aws_subnet.private.*.id
    }
    condition {
      test     = "StringEquals"
      variable = "ec2:AuthorizedService"
      values   = ["codebuild.amazonaws.com"]
    }
  }

  statement {
    effect = "Allow"
    actions = ["s3:*"]
    resources = [
      aws_s3_bucket.codebuild.arn,
      "${aws_s3_bucket.codebuild.arn}/*"
    ]
  }
}

# 引用生成的策略
policy = data.aws_iam_policy_document.codebuild_policy.json
验证方法

修改完成后执行terraform plan,查看输出的policy字段是否符合预期,确认没有空值或者格式错误后再执行terraform apply。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:54:04