Using Conditions in your CloudFormation templates


Brett Gillett

This post is part of a series of introductory articles related to building AWS services using AWS CloudFormation. You can read about CloudFormation Parameters and the DependsOn attribute in earlier posts

The simplest way to think about Conditions within a CloudFormation template is to treat them like ‘if’ statements in your favourite programming language.

By using Conditions, we’re able to create templates that can be used across multiple environments within our AWS accounts, which results in a lower number of templates to manage - which is a good thing.

Conditions are not required and exist in a dedicated section within a CloudFormation template. Once defined, you can use them in both the Resources and Output sections of your template.

An everyday use case is defining one (or more) Conditions to control resources deployed in production versus a non-production environment.

Let’s walk through how you might set up a Condition to determine your specific deployment.

The first step is to define a CloudFormation Parameter that you’ll use to define the environment where you’re deploying the resources in your template.

1
2
3
4
5
6
7
8
Parameters:
    environment:
        Type: String
        Default: development
        AllowedValues:
            - development
            - production
            - poc

In the above Parameter definition, we create the logical ID ‘environment,’ define it as a string, and set a default value. We’re also using an optional property called ‘AllowedValues,’ which allows us to control the possible inputs for the ‘environment’ parameter.

Once the Parameter is defined, we can move on to the Condition.

1
2
Condition:
    isProduction: !Equals [ !Ref environment, production]

Just like when we defined our Parameter, the first step is to set a logical ID for the Condition. In this case, I decided on ‘isProduction.’ Next is to define the Intrinsic function we’ll use in the Condition. My example is simple - we’re setting ‘isProduction’ to true if the ‘environment Parameter is set to ‘production.’

Conditions support several intrinsic functions - including And, If, Not, Or, and Equals.

Now that we have both the Parameter and Condition defined, we can use the Condition in the Resources section of our CloudFormation template.

Conditions can be used to control the creation of resources or the attributes defined in the resource definition itself.

In our first example, we’ll deploy an EC2 instance, but only if the ‘environment’ Parameter is set to ‘production.’

1
2
3
4
5
6
Resources:
    instance0:
        Type: AWS::EC2::Instance
        Condition: isProduction
        Properties:
            ...

You can also use Conditions to adjust attributes dynamically. In the following example, we’ll adapt the instance size based on the ‘environment’ Parameter. If we’re deploying in production, we’ll set the instance to use a t3.large, and if we’re deploying the same instance in any other environment we’ll use a t3.small.

1
2
3
4
5
6
7
Resources:
    ec20:
        Type: AWS::EC2::Instance
        Properties:
            ...
            InstanceType: !If [ isProduction, t3.large, t3.small ]
            ...

In the above example, we used the intrinsic function ‘If’ to determine the size of the EC2 instance deployed. If ‘isProduction’ is true, then we’ll use a t3.large; otherwise, we’ll use a t3.small.

Finally, we can also use ‘Conditions’ in the ‘Outputs’ section of our CloudFormation templates.

1
2
3
4
5
6
Outputs:
    instance0:
        Condition: isProduction
        Value: !Ref instance0
        Export:
            Name: !Sub '${AWS::StackName}-instance0'

In our final example, we set the ‘instance0’ Output only if we’re deploying the resources in a production environment.

There you have it, some simple examples of how you can use Conditions in your CloudFormation template design to create templates that can be used across multiple environments.


Brett Gillett


Orbit

Like what you read? Why not subscribe to the weekly Orbit newsletter and get content before everyone else?