AWS CloudFormation部署S3 Bucket Policy遇MalformedPolicy错误
S3存储桶策略配置仅允许CloudFront访问时反复触发MalformedPolicy错误
问题背景
尝试为静态网站的S3存储桶配置策略,仅允许CloudFront访问,但部署过程中持续出现MalformedPolicy错误,无法定位问题。以下是相关代码和错误信息:
CloudFormation模板核心部分
Resources: BucketPolicy: Type: 'AWS::S3::BucketPolicy' DependsOn: - AppBucket - CloudFrontDistribution Properties: Bucket: !Ref AppBucket PolicyDocument: Id: MyPolicy Version: 2012-10-17 Statement: - Sid: PolicyForCloudFrontPrivateContent Action: 's3:GetObject*' Effect: Allow Condition: StringLike: 'aws:Referer': - !Sub 'https://*.${CloudFrontDistribution}.cloudfront.net/*' Resource: - !Sub arn:aws:s3:::${AppBucket} CloudFrontDistribution: # ... AppBucket: # ...
首次部署错误信息
(...) CloudFormation堆栈操作事件(每0.5秒刷新一次) --------------------------------------------------------------------------------------------------------------------------------------------- 资源状态 资源类型 逻辑资源ID 资源状态原因 --------------------------------------------------------------------------------------------------------------------------------------------- UPDATE_IN_PROGRESS AWS::S3::BucketPolicy BucketPolicy - UPDATE_FAILED AWS::S3::BucketPolicy BucketPolicy 缺少必填字段Principal (服务: Amazon S3; 状态码: 400; 错误代码: MalformedPolicy; 请求ID: DG2QHRDJQ2WS6JZV; S3 扩展请求ID: 6u+LYv77A4Ao DmKmyB4Sfup+rueC1iGAQ82GdkfHimIZL X/HXUPWj2FKSq7WCgi41F4XU6z6BOk=; 代理: null) UPDATE_ROLLBACK_IN_PROGRESS AWS::CloudFormation::Stack test-app-hosting 以下资源更新失败: [BucketPolicy]. UPDATE_COMPLETE AWS::S3::BucketPolicy BucketPolicy - UPDATE_ROLLBACK_COMPLETE_CLEANUP_ AWS::CloudFormation::Stack test-app-hosting - IN_PROGRESS UPDATE_ROLLBACK_COMPLETE AWS::CloudFormation::Stack test-app-hosting - --------------------------------------------------------------------------------------------------------------------------------------------- 错误: 无法创建/更新堆栈: test-app-hosting,等待器StackUpdateComplete失败: 等待器遇到终端失败状态: 对于表达式"Stacks[].StackStatus",我们至少匹配到一次预期路径:"UPDATE_ROLLBACK_COMPLETE"
补充字段后的新错误
根据提示补充了Statement>Principal字段后,仍然出现语法错误:
--------------------------------------------------------------------------------------------------------------------------------------------- 资源状态 资源类型 逻辑资源ID 资源状态原因 --------------------------------------------------------------------------------------------------------------------------------------------- UPDATE_IN_PROGRESS AWS::S3::BucketPolicy BucketPolicy - UPDATE_FAILED AWS::S3::BucketPolicy BucketPolicy 策略语法无效。(服务: Amazon S3; 状态码: 400; 错误代码: MalformedPolicy; 请求ID: NH6PZB3QF0747F4N; S3 扩展请求ID: xdXOFPWgHCjg Lzf4gdjCg79NIXS6qtmtLuGn8N7NeLIOJ 4Qw2bgSJ2v6MKdNzbrMCWCEPKBc90E=; 代理: null) UPDATE_ROLLBACK_IN_PROGRESS AWS::CloudFormation::Stack test-app-hosting 以下资源更新失败: [BucketPolicy].
问题分析与修正方案
核心问题拆解
- 首次错误原因:S3策略的Statement必须包含
Principal字段,原模板遗漏该字段,触发MalformedPolicy错误。 - 补充后仍报错的原因:原模板存在两处语法错误:
Resource字段被错误嵌套在Condition内部,应与Effect、Action同级。- 引用CloudFront域名的方式错误:
${CloudFrontDistribution}是资源逻辑ID,直接引用无法获取实际域名,需用!GetAtt CloudFrontDistribution.DomainName。 - 额外风险:用Referer头验证访问不安全,容易被伪造,推荐使用CloudFront Origin Access Identity(OAI)做身份验证。
修正后的模板代码
Resources: # 定义CloudFront Origin Access Identity(若之前未配置) CloudFrontOAI: Type: AWS::CloudFront::CloudFrontOriginAccessIdentity Properties: CloudFrontOriginAccessIdentityConfig: Comment: "OAI for accessing AppBucket" BucketPolicy: Type: 'AWS::S3::BucketPolicy' DependsOn: - AppBucket - CloudFrontDistribution Properties: Bucket: !Ref AppBucket PolicyDocument: Id: MyPolicy Version: 2012-10-17 Statement: - Sid: PolicyForCloudFrontPrivateContent Action: 's3:GetObject*' Effect: Allow # 指定CloudFront OAI为访问主体 Principal: AWS: !Sub 'arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOAI}' # Resource移至正确层级,需包含对象路径/* Resource: - !Sub 'arn:aws:s3:::${AppBucket}/*' CloudFrontDistribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: Origins: - DomainName: !Sub '${AppBucket}.s3.amazonaws.com' Id: AppBucketOrigin # 关联OAI S3OriginConfig: OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/${CloudFrontOAI}' # 其他分发配置... AppBucket: Type: AWS::S3::Bucket # 存储桶配置...
关键说明
- 优先使用OAI验证:OAI是CloudFront专用身份,只有CloudFront能通过该身份访问S3,比Referer头验证更安全可靠。
- Resource路径配置:若允许访问存储桶内所有对象,需在ARN末尾添加
/*,否则策略仅作用于存储桶本身(而非桶内对象)。 - 字段层级正确性:确保
Resource、Principal等字段与Effect、Action同级,不要嵌套在其他字段内部。
内容的提问来源于stack exchange,提问作者fudo
相关产品推荐
相关产品推荐

