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

如何在AWS CloudFormation的PolicyDocument Statement中使用自定义条件?

解决CloudFormation S3桶策略按环境动态添加权限的问题

你遇到的报错是因为混淆了两个完全不同的「条件」概念:

  • CloudFormation的全局条件(Conditions块定义的):用来控制整个资源是否创建,或者资源属性的动态赋值
  • IAM策略的语句级条件:是IAM权限逻辑的一部分,用来控制这条权限在什么场景下生效(比如IP范围、时间等)

你直接把CloudFormation的NotProd条件放到IAM策略的Statement里,CloudFormation会认为你定义的全局条件没被使用,同时IAM也不认识这个自定义条件,所以报错。

不需要拆分两个桶策略,用CloudFormation的!If函数就能实现动态生成Statement数组,只在非生产环境加入s3:getBucketLocation权限:

Conditions:
  NotProd:
    !Not [!Equals [!Ref Environment, production]]

# 假设你已经定义了Bucket资源
Bucket:
  Type: AWS::S3::Bucket
  # 桶的其他配置...

BucketPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    Bucket: !Ref Bucket
    PolicyDocument:
      Statement:
        # 所有环境都生效的getObject权限
        - Action: s3:getObject
          Effect: Allow
          Principal:
            AWS: '*'
          Resource: !Sub '${Bucket.Arn}/*'
        # 动态添加非生产环境的getBucketLocation权限
        !If
          - NotProd
          - Action: s3:getBucketLocation
            Effect: Allow
            Principal:
              AWS: '*'
            Resource: !Sub '${Bucket.Arn}'
          - !Ref 'AWS::NoValue' # 生产环境下忽略这条语句

关键说明:

  • !If函数会根据NotProd的结果动态生成内容:当非生产环境时,把s3:getBucketLocation的Statement加入数组;生产环境时,用!Ref 'AWS::NoValue'让CloudFormation自动忽略这个元素,不会在Statement里留空项
  • 修正了Resource的写法:s3:getBucketLocation的目标资源是桶本身的ARN,s3:getObject是桶内所有对象的ARN,用!Sub引用桶的ARN比写*更严谨,也符合IAM策略的最佳实践

内容的提问来源于stack exchange,提问作者Sabo Boz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:10:38