Terraform创建AWS IAM策略报错:Policy document不应指定Principal
问题解决:MalformedPolicyDocument 错误处理
错误原因
你遇到的MalformedPolicyDocument: Policy document should not specify a principal错误,核心是混淆了IAM身份策略和S3 Bucket策略的写法:
- 若创建的是要附加到IAM组的
aws_iam_policy(身份策略),这类策略不需要也不能写principals块——策略的应用对象就是这个IAM组本身,Principal是隐含的。 - 只有直接绑定到S3桶的Bucket策略,才需要通过
principals指定允许/拒绝的身份。
两种修正方案
方案1:给IAM组附加身份策略(推荐)
直接创建IAM策略并绑定到目标组,默认拒绝其他用户访问(IAM权限模型为默认拒绝):
data "aws_iam_policy_document" "s3_admin_access" { statement { sid = "AllowGroupAAccess" effect = "Allow" actions = [ "s3:GetObject", "s3:ListBucket" ] resources = local.s3_etl_bucket_array } } resource "aws_iam_policy" "s3_admin_access" { name = "${local.csi}-s3_admin_access" path = "/" policy = data.aws_iam_policy_document.s3_admin_access.json } # 将策略绑定到目标IAM组 resource "aws_iam_group_policy_attachment" "s3_admin_attach" { group = aws_iam_group.iam_group_team["admin-team"].name policy_arn = aws_iam_policy.s3_admin_access.arn }
方案2:配置S3 Bucket策略
如果必须在桶层面直接控制权限,要改用aws_s3_bucket_policy资源,此时principals是合法的:
data "aws_iam_policy_document" "s3_bucket_policy" { statement { sid = "AllowGroupAAccess" effect = "Allow" actions = [ "s3:GetObject", "s3:ListBucket" ] resources = local.s3_etl_bucket_array principals { type = "AWS" identifiers = [aws_iam_group.iam_group_team["admin-team"].arn] } } statement { sid = "DenyAllOtherUsers" effect = "Deny" actions = [ "s3:*" ] resources = local.s3_etl_bucket_array principals { type = "AWS" identifiers = ["*"] } condition { test = "StringNotEquals" variable = "aws:PrincipalArn" values = [aws_iam_group.iam_group_team["admin-team"].arn] } } } # 将策略绑定到目标S3桶 resource "aws_s3_bucket_policy" "etl_bucket_policy" { bucket = local.s3_etl_bucket_name # 替换为你的桶名变量 policy = data.aws_iam_policy_document.s3_bucket_policy.json }
关键注意点
- IAM身份策略(附加到用户/组/角色):无
principals字段,权限仅作用于绑定的身份。 - S3 Bucket策略(绑定到桶):必须包含
principals字段,作用于所有访问该桶的身份。
内容的提问来源于stack exchange,提问作者Kaysss
相关产品推荐
相关产品推荐

