Terraform创建AWS IAM策略失败:策略文档格式错误
问题描述
尝试通过Terraform模块为多个ECR仓库创建AWS IAM策略,terraform plan执行无异常,但terraform apply时返回以下错误:
Error: error creating IAM policy ecr-repo-user-policy: MalformedPolicyDocument: Syntax errors in policy.
使用AWS控制台创建内容完全一致的策略可正常生效,尝试调整关键字大小写、增删逗号后问题仍未解决。
相关代码及输出如下:
Terraform模块调用
module "cocos-ecr-all-repo-policy" { count = (data.aws_region.current.name == "eu-central-1" ? 1 : 0) source = "./modules/ecr-policies/ecr-all-repo-policy" account_id = data.aws_caller_identity.current.account_id }
原始模块代码
variable "account_id" { type = string description = "AWS account id" } resource "aws_iam_policy" "iam-policy" { name = "ecr-repo-user-policy" description = "IAM policy for ecr users" tags = { Creator = "terraform" } policy = jsonencode({ Version = "2012-10-17" statement = [ { sid = "EcrRepositoryAccess" effect = "Allow" action = [ "ecr:DescribeImages", "ecr:ListTagsForResource", "ecr:ListImages", "ecr:PutImage", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability", "ecr:BatchDeleteImage", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart", "ecr:CompleteLayerUpload", ] resources = [ "arn:aws:ecr:*:${var.account_id}:repository/repo1/*", "arn:aws:ecr:*:${var.account_id}:repository/repo2/*", ] }, { sid = "EcrToken" effect = "Allow" actions = [ "ecr:GetAuthorizationToken", ] resources = [ "*", ] } ] }) }
控制台可正常生效的策略
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "ecr:DescribeImages", "ecr:ListTagsForResource", "ecr:ListImages", "ecr:PutImage", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart", "ecr:CompleteLayerUpload" ], "Resource": [ "arn:aws:ecr:*:<AWS account id>:repository/repo1/*", "arn:aws:ecr:*:<AWS account id>:repository/repo2/*" ] }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": "ecr:GetAuthorizationToken", "Resource": "*" } ] }
问题根源
AWS IAM策略的JSON关键字严格区分大小写,必须遵循官方规定的驼峰命名格式。原始代码中存在多处关键字大小写错误:
- 顶级键
statement应为Statement(首字母大写) - Statement对象内的键:
sid→Sideffect→Effectaction/actions→Action(无论单个或多个操作,键名统一使用单数Action)resources→Resource(无论单个或多个资源,键名统一使用单数Resource)
Terraform的jsonencode会保留原始键名的大小写,但AWS策略引擎无法识别这些不符合规范的关键字,因此抛出格式错误。
修正后的模块代码
variable "account_id" { type = string description = "AWS account id" } resource "aws_iam_policy" "iam-policy" { name = "ecr-repo-user-policy" description = "IAM policy for ecr users" tags = { Creator = "terraform" } policy = jsonencode({ Version = "2012-10-17" Statement = [ { Sid = "EcrRepositoryAccess" Effect = "Allow" Action = [ "ecr:DescribeImages", "ecr:ListTagsForResource", "ecr:ListImages", "ecr:PutImage", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability", "ecr:BatchDeleteImage", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart", "ecr:CompleteLayerUpload", ] Resource = [ "arn:aws:ecr:*:${var.account_id}:repository/repo1/*", "arn:aws:ecr:*:${var.account_id}:repository/repo2/*", ] }, { Sid = "EcrToken" Effect = "Allow" Action = [ "ecr:GetAuthorizationToken", ] Resource = [ "*", ] } ] }) }
验证说明
修正后,生成的策略JSON结构与AWS控制台的规范格式完全一致,执行terraform apply即可正常创建IAM策略。
内容的提问来源于stack exchange,提问作者klk2ptx
相关产品推荐
相关产品推荐

