CloudFormation::Init下载S3文件时触发Access Denied错误
问题:EC2 Windows实例通过CloudFormation Init从S3下载文件时返回403 Access Denied错误
场景描述
尝试通过CloudFormation将S3存储桶中的文件下载到EC2 Windows服务器,已配置IAM角色、策略和实例配置文件,在CloudFormation::Init中定义了downloadS3Data配置集用于下载文件。执行cfn-init后,目标文件被创建但内容为空,日志返回HTTP 403 Access Denied错误。尝试扩大IAM策略的Action范围(如s3:*Object、s3:Get*)后问题依然存在。
核心问题:IAM策略Resource配置错误
当前IAM策略中,s3:GetObject权限对应的Resource是存储桶级ARN(arn:aws:s3:::bucket-name),但s3:GetObject操作需要的是对象级ARN(arn:aws:s3:::bucket-name/*)。存储桶级ARN仅适用于桶级操作(如s3:ListBucket),无法授权访问桶内的具体对象。
修复步骤
1. 修正IAM策略的Resource配置
修改RolePolicies中的PolicyDocument,将Resource更新为包含对象路径的ARN:
"RolePolicies":{ "Type":"AWS::IAM::Policy", "Properties":{ "PolicyName":"S3Download", "PolicyDocument":{ "Statement":[ { "Action":[ "s3:GetObject" ], "Effect":"Allow", "Resource": {"Fn::Join": ["", ["arn:aws:s3:::", {"Ref": "S3BucketName"}, "/*"]]} } ] }, "Roles":[ {"Ref":"InstanceRole"} ] } }
添加/*后缀后,策略将授权角色访问指定存储桶内的所有对象。
2. 优化S3文件源路径(可选)
当前source路径为硬编码值,建议改为动态拼接,避免桶名/区域不匹配:
"downloadS3": { "files": { "C:\\Users\\Administrator\\Documents\\s3download.bak": { "source": {"Fn::Join": ["", ["https://", {"Ref": "S3BucketName"}, ".s3.", {"Ref": "AWS::Region"}, ".amazonaws.com/test.txt"]]}, "authentication": "S3AccessCreds" } } }
3. 额外排查点
- 检查S3桶策略:确认没有拒绝该IAM角色访问的规则;
- 检查桶加密配置:如果使用SSE-KMS加密,需在IAM策略中添加
kms:Decrypt权限(针对对应的KMS密钥ARN); - 验证实例关联:确认EC2实例已正确关联
InstanceProfile(当前配置中myAppServer的IamInstanceProfile已引用InstanceProfile,此部分无问题)。
内容的提问来源于stack exchange,提问作者Lacrosse343
相关产品推荐
相关产品推荐

