DEV Community

Timo Schinkel
Timo Schinkel

Posted on

Make your Cloudformation conditions mean something

Within AWS Cloudformation it is possible to create conditions. You can use these conditions to change behavior of the stack, like create a resource only in some situations. It is tempting to use the environment as a base for your condition. Even the documentation of AWS has an example with the condition CreateProdResources. While performing some migrations I realised that these conditions don't mean anything, and so I renamed my conditions to have meaningful names.

Environment

A typical list of conditions as I've seen so far might look something like this:

Conditions: 
  IsTesting: !Equals [ !Ref Environment, "testing" ]
  IsProductionOrAcceptance: !Or [ !Equals [ !Ref Environment, "production" ], !Equals [ !Ref Environment, "acceptance" ]]
  IsProduction: !Equals [ !Ref Environment, "production" ]
Enter fullscreen mode Exit fullscreen mode

These conditions are typically used like so:

Resources:
  RdsClusterNew:
    Type: "AWS::RDS::DBCluster"
    Condition: IsTesting
    Properties:
      # ...
      DBClusterParameterGroupName: !If [ IsTesting, !Ref "RdsClusterParameterGroupWithPerformanceInsights", !Ref "RdsClusterParameterGroup" ]
      # ...
Enter fullscreen mode Exit fullscreen mode

This is a random resource and when you look at this example it makes sense; Only on the testing stack do we want to create this database cluster and only on the testing stack do we want to enable performance insights for the database. But a feature rarely has a single resource; When creating an RDS cluster you'll need a cluster, a parameter group, instances, instance parameter groups, and possibly even other resources. Enabling the RDS on another environment would mean changing multiple lines. This has an increased risk of changing a condition too many or too few.

Meaningful conditions

One way to avoid this is to give your conditions meaningful names, for example:

Conditions:
  CreateNewRdsCluster: !Equals [ !Ref Environment, "testing" ]
  EnablePerformanceInsights: !Equals [ !Ref Environment, "testing" ]

Resources:
  RdsClusterNew:
    Type: "AWS::RDS::DBCluster"
    Condition: CreateNewRdsCluster
    Properties:
      # ...
      DBClusterParameterGroupName: !If [ EnablePerformanceInsights, !Ref "RdsClusterParameterGroupWithPerformanceInsights", !Ref "RdsClusterParameterGroup" ]
      # ...
Enter fullscreen mode Exit fullscreen mode

Now also creating the new RDS cluster on the acceptance environment as well is a single line change; You only need to change the condition. And the same thing goes for enabling Performance Insights.

tl/dr;

Naming is hard, and just like with your methods and variables in code you will benefit from meaningful and descriptive names when working with (conditions in) Cloudformation. Not only does it make the resource definitions better to read and understand, it also makes enabling or disabling resources easier as they are one-line changes.

Top comments (0)