Table of contents
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
andOR
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