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

Terraform创建IAM Policy报MalformedPolicyDocument错误求助

Terraform创建IAM Policy报错但CLI成功的原因与解决方法

问题描述

我使用Terraform代码创建IAM Policy时,执行terraform apply触发错误:

Error: creating IAM Policy autoscale-policy: MalformedPolicyDocument: The policy failed legacy parsing

但使用AWS CLI提交完全相同的策略内容却能成功创建IAM Policy。请问两者存在什么差异?为何会出现该错误?

Terraform代码

terraform {
    required_providers {
        aws = {
            source  = "hashicorp/aws"
            version = "~> 4.52.0"
        }
    }
}

provider "aws" {
    region = "us-west-2"
}

resource "aws_iam_policy" "autoscale_policy" {
    name        = "autoscale-policy"
    description = "EBS Autoscaling Policy"
    policy = <<EOT
{
    "Version": "2012-10-17",
    "Statement": {
        "Action": [
            "ec2:AttachVolume",
            "ec2:DescribeVolumeStatus",
            "ec2:DescribeVolumes",
            "ec2:ModifyInstanceAttribute",
            "ec2:DescribeVolumeAttribute",
            "ec2:CreateVolume",
            "ec2:DeleteVolume",
            "ec2:CreateTags",
            "kms:Decrypt",
            "kms:CreateGrant",
            "kms:Encrypt",
            "kms:ReEncrypt*",
            "kms:GenerateDataKey*",
            "kms:DescribeKey"
        ],
        "Resource": "*",
        "Effect": "Allow"
    }
}
EOT
}

AWS CLI命令

aws iam create-policy \
    --policy-name TestPolicy \
    --policy-document \
'{
  "Version": "2012-10-17",
  "Statement": {
    "Action": [
        "ec2:AttachVolume",
        "ec2:DescribeVolumeStatus",
        "ec2:DescribeVolumes",
        "ec2:ModifyInstanceAttribute",
        "ec2:DescribeVolumeAttribute",
        "ec2:CreateVolume",
        "ec2:DeleteVolume",
        "ec2:CreateTags",
        "kms:Decrypt",
        "kms:CreateGrant",
        "kms:Encrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
    ],
    "Resource": "*",
    "Effect": "Allow"
  }
}'

原因分析

  • Terraform的AWS Provider默认启用旧版IAM策略解析校验,而AWS CLI默认使用新版解析逻辑。
  • IAM策略的标准规范中,Statement字段必须是数组格式(用[]包裹),即使只有一条语句。AWS新版解析逻辑兼容单个对象格式的Statement,但Terraform Provider严格遵循旧版解析规则,因此触发格式错误。

解决方案

将策略中的Statement从单个对象修改为数组格式,即使只有一条语句也要用[]包裹。修改后的Terraform策略内容如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ec2:AttachVolume",
                "ec2:DescribeVolumeStatus",
                "ec2:DescribeVolumes",
                "ec2:ModifyInstanceAttribute",
                "ec2:DescribeVolumeAttribute",
                "ec2:CreateVolume",
                "ec2:DeleteVolume",
                "ec2:CreateTags",
                "kms:Decrypt",
                "kms:CreateGrant",
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

补充说明

虽然AWS当前允许Statement为单个对象,但为了兼容所有工具(包括Terraform),建议始终使用数组格式定义Statement,这也是IAM策略的标准写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:35:16