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
相关产品推荐
相关产品推荐

