Terraform部署S3桶策略遇MalformedPolicy错误:Principal配置问题
问题描述
尝试使用以下Terraform代码部署S3桶,期望通过桶策略授予跨账号特定EC2实例S3的GetObject和PutObject权限:
resource "aws_s3_bucket" "bucket" { bucket = var.s3_bucket_name } resource "aws_s3_bucket_policy" "bucket_policy" { bucket = aws_s3_bucket.bucket.id policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Sid": "CrossAccountEC2Access", "Effect": "Allow", "Principal": { "Service": [ "arn:aws:ec2:us-east-1:account_id:instance/instance_id" ] }, "Action": ["s3:GetObject", "s3:PutObject"], "Resource": "arn:aws:s3:::${var.s3_bucket_name}/*" } ] } POLICY }
执行terraform apply时返回错误:
module.backup-s3-bucket[0].aws_s3_bucket_policy.bucket_policy: Creating... module.backup-s3-bucket[0].aws_s3_bucket_policy.bucket_policy: Still creating... [10s elapsed] module.backup-s3-bucket[0].aws_s3_bucket_policy.bucket_policy: Still creating... [20s elapsed] module.backup-s3-bucket[0].aws_s3_bucket_policy.bucket_policy: Still creating... [30s elapsed] module.backup-s3-bucket[0].aws_s3_bucket_policy.bucket_policy: Still creating... [41s elapsed] module.backup-s3-bucket[0].aws_s3_bucket_policy.bucket_policy: Still creating... [51s elapsed] ╷ │ Error: putting S3 policy: MalformedPolicy: Invalid principal in policy │ status code: 400, request id: WGXE66WB8MT8EASW, host id: wFSAqlvst1/KmB/n5UrC77jQCCN33bZ3yJ1kbWrN3LmRCzsZ938CdRl9kkXHho3JNX1PNmNKSH9J/9NnH0retWcRbI4Y0/Av6hSLJ8s3lGA= │ │ with module.backup-s3-bucket[0].aws_s3_bucket_policy.bucket_policy, │ on ../modules/backup-s3-bucket/main.tf line 9, in resource "aws_s3_bucket_policy" "bucket_policy": │ 9: resource "aws_s3_bucket_policy" "bucket_policy" {
请问Principal行配置哪里有误?
问题原因及修复
你的Principal配置存在两个核心错误:
- 错误使用Service类型Principal:EC2实例不属于AWS服务主体范畴,不能放在
"Service"字段下。跨账号授权EC2实例时,必须使用"AWS"类型的Principal,指向实例关联的IAM角色ARN,而非实例本身的ARN。 - 直接指定EC2实例ARN无效:S3桶策略无法直接授权给EC2实例,只能授权给实例所绑定的IAM角色——EC2实例是通过附加的IAM角色来获取访问权限的。
修复后的Terraform代码示例
resource "aws_s3_bucket_policy" "bucket_policy" { bucket = aws_s3_bucket.bucket.id policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Sid": "CrossAccountEC2Access", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::目标账号ID:role/EC2实例使用的IAM角色名" ] }, "Action": ["s3:GetObject", "s3:PutObject"], "Resource": "arn:aws:s3:::${var.s3_bucket_name}/*", "Condition": { "ArnEquals": { "aws:SourceArn": "arn:aws:ec2:us-east-1:目标账号ID:instance/实例ID" } } } ] } POLICY }
额外注意事项
- 确保目标账号的IAM角色信任策略允许EC2服务扮演该角色(信任关系中需包含
ec2.amazonaws.com)。 - 代码中添加的
Condition字段是可选的,用于进一步限制只有指定EC2实例能通过该角色访问S3桶,提升权限控制的精准度。
内容的提问来源于stack exchange,提问作者justyfied
相关产品推荐
相关产品推荐

