TL;TR

Use AWS::NoValue as NULL value.

The problem

I want to create a CloudFormation template on AWS which some optional setting. This should be controlled over a parameter.

Let’s say we have a CloudFront Distribution which get should pre validated from a Lambda. This looks like this snippet of code:

Resources:
  FooDistribution:
    Type: "AWS::CloudFront::Distribution"
    Properties:
      # ...
      DistributionConfig: 
          LambdaFunctionAssociations: 
            - Authentication # This should be functional
              - EventType: "viewer-request"
                LambdaFunctionARN: "arn:aws:lambda:us-east-1:123456789:function:function-bar:7"

Here is missing a variable option to enable/disable the authentication lambda.

Solution

We need somthing like an if-function and this function is supported by CloudFormation. AWS give us some functions in YAML or JSON to make dynamic templates. We want to use Fn::If. The next part is that this function only allow two parameters to say A or B. But we don’t want a B value. To solve this we can use AWS::NoValue.

So we need to extend our template like this:

Parameters:
  AuthParam:
    Description: "Need authentication?"
    Type: String
    Default: "false"
Conditions:
  Authentication:
    Fn::Equals:
      - Ref: AuthParam
      - "true"
Resources:
  FooDistribution:
    Type: "AWS::CloudFront::Distribution"
    Properties:
      # ...
      DistributionConfig: 
          LambdaFunctionAssociations: 
            Fn::If: 
              - Authentication # If this true
                - EventType: "viewer-request" # .. then this
                  LambdaFunctionARN: "arn:aws:lambda:us-east-1:123456789:function:function-bar:7"
                - - Ref: "AWS::NoValue" # .. or this if not

That’s it!

References