Conditions - !Equals function

Conditions - !Equals function

Everything you need to know about CloudFormation Conditions; the next top-level section of AWS CloudFormation

Introduction

In this blog post, we will explore the following:

  • How Conditions integrate with other top-level sections of CloudFormation

  • Benefits of integrating Conditions in your template

  • Practical examples using various conditional functions (AND, EQUALS, IF NO VALUE, NOT and OR conditions)

What are Conditions?

Suppose you want to deploy three environments, such as development, testing, and production. The old school way would be to build and maintain three templates and we all know the stress that comes with managing multiple templates that relate with one another.

From the scenario above, you can use Conditions to automate the deployment of different environments with minimal effort.

By using conditions, you can deploy only the necessary resources based on specific criteria (like regions, account types, or specific use cases).

Consider a scenario where you are in the testing phase while building an environment for your application. You will find yourself configuring an instance with security groups that allow both SSH, HTTP and HTTPS traffic. This is because you would want to interact with the server so as to troubleshoot issues, deploy and debug code, and test configurations. As you move to the production phase, you will limit the security group rules to only allow HTTPS traffic so as to enhance security and meet audit and compliance standards.

With Conditions, you are able to control the creation of your resources and configurations dynamically.

Understanding Conditions

Conditions will allow your template to be dynamic thus allowing the creation of different resources (e.g. security groups) or configurations for various environments (Dev, Test, Prod), regions or Parameters without the need for different templates.

Integrating Conditions with Other Sections

Resources

Resources have to be used with conditions since we are controlling how they will be created.

Outputs

We have not covered them yet but with conditions, you are able to generate resource values such as instance id, security group id once the stack has been created. The resource values are referred to as outputs which return information about the resources that are created in your stack.

Mappings and Parameters

Values from these sections can be used to determine logic decisions by controlling which resources get created and which ones get ignored.

Benefits of Using Conditions

  • It becomes easy to create different environments on one template (Dev, Test, Prod).

  • Ensures resource utilization as you avoid unnecessary resources from being created thus saving on cost.

  • It is easy to reuse your template and at the same time fix errors associated with your environment.

Condition functions

!Equals function

This functions compares two values and returns true if the values are identical and returns false if the values are not identical.

Template Sample

Let's use an example to demonstrate the use of the Equals function.

Consider you have this parameter set up alongside resources and other sections of your cloudformation template.

  ParamEnvironmentType:            
    Description: Select the Environment Type from the list
    Type: String
    Default: Dev
    AllowedValues:
      - Prod
      - Dev

We know that when we upload this template, we will be asked to select our default environment type as either Prod or Dev

Suppose we only want to create an instance that has an elastic IP address in the prod environment and not on the dev environment, we can set up a condition that allows the creation of an elastic IP address only when the environment type you select during stack creation is Prod

Conditions:
  ConditionForProdEIP: !Equals [!Ref ParamEnvironmentType, Prod]

It can also be written like this

Conditions:
  ConditionForProdEIP: !Equals
    - !Ref ParamEnvironmentType
    - Prod

Or, like this

Conditions:
  ConditionForProdEIP: !Equals [!Ref ParamEnvironmentType, Prod]

When designing your template, let !Ref ParamEnvironmentType in conditions above denote the environment type the template user will select when creating the stack. If the selected environment equates to Prod as highlighted above, then the resource below is going to be created

Resources:
  MyEIP:
    Type: AWS::EC2::EIP
    Condition: ConditionForProdEIP
    Properties:
      InstanceId: !Ref MyProdEC2Instance3

Take note of Condition: ConditionForProdEIP added in the MyEIP resource just above the EIP Properties.

The snippet above show MyEIP resource is created only if the ConditionForProdEIP condition is true. This means the elastic IP address will only be created in the production environment.

Please use the template below to create a Production environment that:

  • Creates an Elastic IP address that is only associated with the production environment.

  • Attaches the elastic IP address onto a production based instance.

AWSTemplateFormatVersion: 2010-09-09
Description: Creating an ec2 instance

Mappings:
  # Allows cloudformation to use only these AMIs in the following regions
  MapEc2Region:
    us-east-2:
      HVM64: ami-0c0d141edc4f470cc
    us-west-2:
      HVM64: ami-093467ec28ae4fe03

  MapEnvironmentType:
    # Allows cloudformation to only use these instance types depending on the Env type 
    Prod:
      InstanceType: t3.small
    Dev:
      InstanceType: t3.micro

Parameters:
  ParamEnvironmentType:
    Description: Select the Environment Type from the list
    Type: String
    Default: Dev
    AllowedValues:
      - Prod
      - Dev
  ParamKeyName:
    Description: Select the key name from the list
    Type: AWS::EC2::KeyPair::KeyName

  ParamAZName:
    Description: Select the Avaiability Zone name from the list
    Type: AWS::EC2::AvailabilityZone::Name

Conditions:
  ConditionForProdEIP: !Equals
    - !Ref ParamEnvironmentType
    - Prod

Resources:
  HTTpSShSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Allow HTTP and SSH traffic
      GroupName: DemoHTTPSShSecurityGroup
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
  MyEIP:
    Type: AWS::EC2::EIP
    Condition: ConditionForProdEIP
    Properties:
      InstanceId: !Ref MyProdEC2Instance


  MyProdEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !FindInMap
        - MapEc2Region
        - !Ref AWS::Region
        - HVM64

      KeyName: !Ref ParamKeyName
      AvailabilityZone: !Ref ParamAZName
      InstanceType: !FindInMap
        - MapEnvironmentType
        - !Ref ParamEnvironmentType
        - InstanceType
      Tags:
        - Key: Name
          Value: !Ref ParamEnvironmentType
      UserData: !Base64 |
        #!/bin/bash -xe
        yum update -y
        yum install -y httpd
        systemctl start httpd
        systemctl enable httpd
        echo '<html><h1>Hello From Your Restart Web Server!</h1></html>' > /var/www/html/index.html
      SecurityGroups:
        - !Ref HTTpSShSecurityGroup