Parameters
Everything you need to know about CloudFormation Parameters; the next top-level section of AWS CloudFormation
Introduction
From the previous blog posts, we have been hardcoding specific values like ImageId
, InstanceType
, KeyName
etc. directly in our template.
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-04e5276ebb8451442
InstanceType: t2.micro
But what about situations where you want to choose between different EC2 instance types during deployment, or maybe reference existing security groups by name, or maybe you want to securely manage database credentials without exposing them in the template? You will need parameters for such reasons.
So, what are parameters?
Parameters allow us to provide dynamic values when we are creating new stacks or when updating an existing stack. This prevents you from hardcoding specific values from your template.
Here is a code snippet of parameters from my template
Parameters:
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
ParamInstanceType: #Go to SSM> PARAMETER STORE,,,E.G. Name - DemoInstance Value - t2.micro
Description: Select the Instance Type from the list
Type: AWS::SSM::Parameter::Value<String>
Here are the dynamic values that I will key in before uploading the template on AWS CloudFormation.
In the Parameters section, we have declared a parameter named ParamKeyName
(You can declare any name) of type AWS::EC2::KeyPair::KeyName
. It gives you the flexibility to choose which ssh key to use when creating or updating your stack.
Benefits of Parameters
Parameters are essential for a couple of reasons:
Offer flexibility - Parameters enable you to reuse templates. You can deploy different stacks with different configurations based on the values that you specify when reuploading the template. you can have one template deploying an instance in Availability zone A with a ssh key
(KeyName)
called 'cloudformation'. You can have the same template deploying another instance in Availability zone B with a ssh key called 'demo-key'.Environment-Specific Deployments - You can have different parameter values for different environments (e.g., dev, test, prod) where you can create different stacks. One for dev, test and another for prod.
Security - Like I stated earlier, you can secure database credentials alongside other sensitive information such as sensitive URLs and endpoints, user credentials etc. using parameters
Validation - You can declare predefined constraints that ensure only certain input values are added as parameter values. You can specify to only allow certain instance types in your stack e.g.
t3.small
,t2.micro
,t3.large.
This validation enforces compliance by only accepting allowed values specified in the parameters section of the template.
Parameter Types
AWS-specific parameter types
These parameter types are essential in helping you detect invalid values when creating or updating your stack. The parameter you specify must be assigned a value when uploading the template for CloudFormation to create/update a stack successfully.
Supported AWS-specific parameter types
If you intend to use parameters with AWS-specific types, you must enter existing AWS values in your account e.g. key pair names, VPC id, instance id etc. AWS CloudFormation will validate these input values against existing values in the account.
AWS::EC2::AvailabilityZone::Name
- Depending on the region you're deploying your template in, it will list out all the availability zones
Parameters:
ParamAZName:
Description: Select the Avaiability Zone name from the list
Type: AWS::EC2::AvailabilityZone::Name
AWS::EC2::Image::Id
- Allows you to specify the Image Id you want to use. You have to confirm from the console the image id depending on the region you want to deploy your stack in.
Note that when uploading a template, it doesn't show a drop-down list of values for this parameter type. You simply type it out after confirming from the console.
Parameters:
ParamImageId:
Description: specify the Image Id for your Instance
Type: AWS::EC2::Image::Id
AWS::EC2::KeyPair::KeyName
- Allows you to specify the ssh key to use depending on the ssh keys you have created in your account.
ParamKeyName:
Description: Select the ssh key from the list
Type: AWS::EC2::KeyPair::KeyName
Other supported AWS-specific parameter types
AWS::EC2::Instance::Id
AWS::EC2::SecurityGroup::GroupName
AWS::EC2::SecurityGroup::Id
AWS::EC2::Subnet::Id
AWS::EC2::Volume::Id
AWS::EC2::VPC::Id
AWS::Route53::HostedZone::Id
SSM Parameters
To understand SSM parameters, we will have to revisit AWS Systems Manager Parameter Store and understand its essence.
Parameter store acts as a central repository for all your configuration data and application settings. It also allows versioning by keeping records of all parameter changes, allowing you to rollback to previous versions if necessary.
It also improves security by encrypting your parameters either at rest or in transit thus reducing the risk of exposing sensitive values that would have been visible in your template.
By referencing SSM Parameters, your templates become leaner and more focused on infrastructure definitions. The template size becomes smaller and less complex, making them easier to understand and manage.
We start by creating a parameter in AWS SSM Parameter Store
Navigate to AWS System Manager console and on the left hand pane, choose Parameter Store under Application Management
Under Parameter Store, choose Create Parameter
Next, configure your parameter as follows. Name - DefaultInstance
, Description - Default Instance Type
, Tier - Standard
, Type - String
, Data Type - Text
, Value - t2.micro
Next, upload your template in the console and take note of the parameter value (DefaultInstance
) under ParamInstanceType
entry
Below is the template that captures the AWS SSM parameter you created (DefaultInstance
) to be fetched by AWS CloudFormation.
AWSTemplateFormatVersion: 2010-09-09
Description: Creating an ec2 instance
Parameters:
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
ParamInstanceType: #Go to SSM> PARAMETER STORE,,,E.G. Name - DemoInstance Value - t2.micro
Description: Select the Instance Type from the list
Type: AWS::SSM::Parameter::Value<String>
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
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-01cd4de4363ab6ee8
KeyName: !Ref ParamKeyName
AvailabilityZone: !Ref ParamAZName
InstanceType: !Ref ParamInstanceType
Tags:
- Key: Name
Value: DevInstance
UserData:
Fn::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
The instance type of the MyEC2Instance
resource uses the !Ref
intrinsic function which fetches the value associated with ParamInstanceType
parameter
InstanceType: !Ref ParamInstanceType
Parameter with additional Properties
This category consists of parameters with additional attributes/properties acting as constraints and guidelines for users interacting with your templates. Let's dive into some properties:
AllowedValues
- contains the list of values allowed for the parameter
Parameters:
DBEngine:
Description: Database engine (e.g., mysql, postgresql)
Type: String
AllowedValues: [mysql, postgresql, sqlserver]
ConstraintDescription
- You have probably encountered a situation where you're filling out a google form to sign up for a service and you are required to enter your email address. The form probably has validation rules in place to ensure the email address you enter is in the correct format (ensuring the email address includes an "@" symbol and a domain name.)That is exactly what
ConstraintDescription
does. It aids template users in understanding why their input was rejected and how they can correct it.This parameter attribute lets you provide a custom error message when the user input fails to meet the specified constraints for a parameter.
Parameters: RDSInstanceIdentifier: Description: RDS Database Instance Name ConstraintDescription: Allows alphanumerics Type: String MinLength: '1' MaxLength: '64' AllowedPattern: '[A-Za-z0-9]*' # Allows alphanumerics
From the template snippet above, you are required to input a database instance name that allows alphanumeric values. The name I provided includes special characters which are not part of the regular expression
[A-Za-z0-9]*
hence the validation error highlighted in red in the image below.Below is what is displayed when uploading your template alongside the other top-level sections of your template such as resources, metadata etc.
Below is
ConstraintDescription
as an error when the database instance name doesn't meet the specified requirements when uploading the template.Note that the validation error states that the parameter failed to allow alphanumerics (
ConstraintDescription
: Allows alphanumerics)AllowedPattern
In our earlier discussion, we talked about
Regular Expressions
. TheAllowedPattern
attribute uses regular expressions to validate parameter values.If you want template users to follow strict patterns or rules that text strings must adhere to, then you will need regular expressions/regex in your
AllowedPattern
attribute. You will need to be understand how to create regular expressions first.There are certain scenarios where
AllowedPattern
would be commonly used:Validating IP addresses and subnet masks for your AWS VPC configurations
Validating user inputs by enforcing required naming conventions for resources such as EC2 Instance names, s3 Bucket names etc.
Below is a template snippet with different parameters responsible for setting up an AWS VPC with both public and private subnets.
We start by defining the parameter logical name VPCCIDR
which expects a string value representing the CIDR block for the entire VPC. Under AllowedPattern
, we come up with a regular expression that validates the format required when indicating your VPC CIDR (likely matching four octets separated by periods and a subnet mask e.g. 10.0.0.0/16).
The same pattern is defined for the public and private subnets.
Parameters:
VPCCIDR:
Type: String
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{2})"
ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x.
PublicSubnet1CIDR:
Type: String
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{2})"
ConstraintDescription: Must be a valid IP subnet within the VPCCIDR and not in use by another resource.
PublicSubnet2CIDR:
Type: String
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{2})"
ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x.
PrivateSubnet1CIDR:
Type: String
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{2})"
ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x.
PrivateSubnet2CIDR:
Type: String
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{2})"
ConstraintDescription: Must be a valid IP CIDR range of the form x.x.x.x/x.
Default
- TheDefault
attribute in parameters serves as the default value/fallback value that is automatically displayed and assigned to the parameter if the template user fails to key in a different value during stack creation.Below is a template snippet of how the
Default
attribute is represented in parameters```yaml Parameters: ParamDBInstanceClass: Default: db.t3.micro Description: DB Instance Class for the RDS Instance Type: String
ParamAllocatedStorage: Default: '30' Description: Storage for RDS Instance Type: Number MinValue: '20' MaxValue: '6144'
ParamStorageType: Default: gp2 Description: DB Storage type for the RDS Instance Type: String ```
Below is an image of the default values for the parameters above after uploading your template. If you wish to select other values, simply click on the other options on the dropdown or simply type your desired value.
Other parameter attributes include
Description
MinLength
MaxLength
MinValue
MaxValue
NoEcho
To understand more about these parameter attributes visit the Parameters documentation.