Search code examples
amazon-web-servicesaws-cloudformationaws-cloudformation-custom-resource

how to add a user defined condition to a PolicyDocument Statment in AWS Cloudformation


In AWS Cloudformation, I have a user defined condition, and a bucket policy being deployed:

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

...
BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Condition: NotProd
    Properties:
      Bucket: !Ref Bucket
      PolicyDocument:
        Statement:
          - Action:
              - s3:getObject
            Effect: Allow
            Principal:
              AWS: '*'
            Resource: '*'
          - Action:
              - s3:getBucketLocation
            Effect: Allow
            Principal:
              AWS: '*'
            Resource: '*'

The above configuration has no problems, but when I try to add the condition such that the s3:getBucketLocation permission is only added if we're not in production, as follows:

BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref Bucket
      PolicyDocument:
        Statement:
          - Action:
              - s3:getObject
            Effect: Allow
            Principal:
              AWS: '*'
            Resource: '*'
          - Action:
              - s3:getBucketLocation
            Effect: Allow
            Principal:
              AWS: '*'
            Resource: '*'
            Condition: NotProd

, then I get an error saying Condition NotProd not used. Is there any way I can somehow achieve my desired result of only adding s3:getBucketLocation when not in production without doing something like creating a separate bucket policy without the s3:getBucketLocation permission?


Solution

  • You have to use If:

    BucketPolicy:
        Type: AWS::S3::BucketPolicy
        Properties:
          Bucket: !Ref Bucket
          PolicyDocument:
            Statement:
              - Action:
                  - s3:getObject
                Effect: Allow
                Principal:
                  AWS: '*'
                Resource: '*'
              - !If
                - NotProd
                - Action:
                    - s3:getBucketLocation
                  Effect: Allow
                  Principal:
                    AWS: '*'
                  Resource: '*'
                - !Ref "AWS::NoValue"