You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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].

问题分析与修正方案

核心问题拆解

  1. 首次错误原因:S3策略的Statement必须包含Principal字段,原模板遗漏该字段,触发MalformedPolicy错误。
  2. 补充后仍报错的原因:原模板存在两处语法错误:
    • 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:50:28