3
votes

I'm having a strange behavior with cloudformation template. This my template, where I create a bucket and want to notification configuration depending on a condition :

AWSTemplateFormatVersion: '2010-09-09'
Description: "Setup Artifacts Bucket"
Parameters:
  BucketName:
    Description: Name of the pipeline setup arctifact bucket
    Type: String 
    Default: "s3-pipeline-setup"
  NotificationCondition:
    Description: Conditionally add Notification configuration to the artifact bucket
    Type: String
    Default: false
Conditions:
  AddNotificationConfiguration: !Equals [ !Ref NotificationCondition, true ]

Resources:
  ArtifactBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      Fn::If:
        - AddNotificationConfiguration
        -
          NotificationConfiguration:
            LambdaConfigurations:
              -
                Function: "arn:aws:lambda:eu-west-1:341292222222227:function:lambda-ops-trigger-pipeline-setup"
                Event: "s3:ObjectCreated:*"
                Filter:
                  S3Key:
                    Rules:
                      -
                        Name: prefix
                        Value: "appstackcodes/"
                      -
                        Name: suffix
                        Value: "txt"
        - !Ref AWS::NoValue

When I try a deploy it fails with this error :

00:28:10 UTC+0200 CREATE_FAILED AWS::S3::Bucket ArtifactBucket Encountered unsupported property Fn::If

I don't really understand the matter.. Can someone try and let me know the mistake there please?

Thanks

1

1 Answers

4
votes

Unfortunately you can not do what you intended in cloudformation.

The Fn::If can basically just be used as a ternary expression. E.g.

key: Fn::If: [condition_name, value_if_true, value_if_false]

It can't be used as logic flow like you would in a programming language. There are ways around it. You actually already seemed to have discovered the AWS::NoValue, so it's just a matter of moving the NotificationConfiguration assignment to outside the if.

Resources:
  ArtifactBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      NotificationConfiguration:
        Fn::If:
          - AddNotificationConfiguration
          - LambdaConfigurations:
              -
                Function: "arn:aws:lambda:eu-west-1:341294322147:function:lambda-itops-trigger-pipeline-setup"
                Event: "s3:ObjectCreated:*"
                Filter:
                  S3Key:
                    Rules:
                      -
                        Name: prefix
                        Value: "appstackcodes/"
                      -
                        Name: suffix
                        Value: "txt"
          - !Ref AWS::NoValue

Effectively you are always assigning something to NotificationConfiguration, but sometimes it's the magic AWS::NoValue. This works in the majority of cases, although there are times when this just isn't sufficient and more creativity is required!