AWS CloudFormation- Infrastructure as Code
AWS CloudFormation enables us to create and provision AWS infrastructure deployments predictably and repeatedly. We can use it on services such as Amazon Elastic Compute Cloud (Amazon EC2), Amazon Elastic Block Store (Amazon EBS), Amazon Simple Notification Service (Amazon SNS), Elastic Load Balancing, and Auto Scaling.
AWS CloudFormation enables you to use a template file to create and delete a collection of resources, which are managed together as a single unit (a stack).
Currently, CloudFormation supports two languages JSON and YAML. We can write our code with one of these languages.
Que 1- Can user change those resources created, outside of AWS CloudFormation?
Ans- Yes, users can change resources outside of AWS CloudFormation. Users can edit resources directly by using the underlying service that created the resource.
For example, we can use the Amazon EC2 console to update a server instance that was created as part of an AWS CloudFormation stack.
Further, we can use drift detection to identify which stack resources have configuration changes that were made outside of AWS CloudFormation management.
Que 2- What are the two major terms for AWS CloudFormation?
Ans- Two major terms for AWS CloudFormation are templates and stacks. A template is a specification of the AWS resources to be provisioned. A stack is a collection of AWS resources that were created from a template. You might provision (create) a stack many times.
When a stack is provisioned, the AWS resources that are specified by the stack template are created. Any charges incurred from using these services will start accruing when they are created as part of the AWS CloudFormation stack.
When a stack is deleted, the resources that are associated with that stack are deleted. The order of deletion is determined by AWS CloudFormation.
Que 3- Explain the components of an AWS CloudFormation template.
Ans- These elements are the major components of an AWS CloudFormation template.
1) Parameters is an optional section of the template. When parameters are present, they include name-value pairs. These parameters can then be referenced later in the template.
2) Mappings is an optional section of the template. Mappings are typically used to refer to the values of the most current Amazon Machine Images (AMIs) in a Region because they differ by Region. They also change over time as new AMIs are released.
3) Resources is a required section of the template. The Resources section contains the AWS objects that you will create. You can create resources across a large number of AWS services, including Amazon EC2, Amazon Simple Storage Service (Amazon S3), Amazon Virtual Private Cloud (Amazon VPC), and many others. You can specify relationships and dependencies between resources to ensure that resources are created in the correct order.
The CloudFormation::Init resource type enables you to deploy applications, files, and other resources onto your EC2 instances as part of the deployment process.
The CloudFormation::WaitCondition resource type is used to coordinate resource creation. For example, suppose that a resource has a dependency on another resource. AWS CloudFormation will wait for other resource creation activities to complete before it attempts to create the dependent resource. WaitConditions enable you to signal back to AWS when your CloudFormation::Init commands finish running successfully.
6) Outputs is an optional section of the template. The Outputs section returns string values that are created by the template and that might be important to users. For example, if you create EC2 instance that functions as a public web server, you might choose to output the full public Domain Name Server (DNS) name of the server in the Outputs section.
It is not mandatory that the template requires all the above-mentioned sections. By using only the Resources section, we will be able to create a template.
Que 4- Few advantages of CloudFormation?
Ans- CloudFormation thus saves time in building infrastructure and helps in focusing on the development.
Estimate Cost — Each resources within the stack is tagged with an identifier so you can easily see how much a stack costs you.
Productivity — Ability to destroy and re-create an infrastructure on the cloud within no time.
Easy Deployment- Declarative programming (no need to figure out ordering and orchestration). Plus, it facilitates the orchestration of resources through APIs.
Re-useability — Leverage existing templates on the web and supports (almost) all AWS resources:.
Note: If an error is encountered when you launch an AWS CloudFormation template, all resources are rolled back by default.
Que 5 — What are Change Sets? How are they created?
Ans- Change sets allow engineers to understand just what will happen to a change in a stack before implementation. This ensures that any / all updates, changes, and deletes will be identified prior to implementation.
The steps in creating a change set are:
1. Create changes for the target stack. AWS CloudFormation then creates a change set.
2. Review the change set.
3. If necessary, make any additional changes that are required. For each additional change repeats steps 1 and 2.
4. Run the change set to implement the changes.
Scenario Implementation
Lets consider a situation that, a firm is having its application on t2.micro instance. During a festive season its expecting high traffic, hence it wants Cloud System Administrator to increase the capacity of the server to handle the load.
Also, the system Administrator has a requirement to disable the SSH access and provide only HTTP access to the server.
Task:
a) Sign in to AWS Management Console. Copy the S3 Object URL of the sample template (it will be used to create CloudFormation stack).
b) Create a CloudFormation stack using a template present in an S3 bucket.
c) Create a Change set for the CloudFormation stack.
d) Check the updates and changes applied.
Solution
a) Sign in to AWS Management Console.
Copy the S3 Object URL of the sample template, to create CloudFormation stack. (Here, we have a S3 object (EC2InstanceInput.template)which contains the sample template).
We will navigate to the S3 service, then to bucket, select the object & copy the Object URL (Copy URL tab) of sample template file (EC2InstanceInput.template)
The above template content looks like:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Metadata" : {
"Instances" : {"Description" : "EC2 instance with t2.micro as instance type"}
},
"Description" : "AWS CloudFormation Sample Template EC2InstanceWithSecurityGroupSample: Create an Amazon EC2 instance running the Amazon Linux AMI. The AMI is chosen based on the region in which the stack is run. This example creates an EC2 security group for the instance to give you SSH access. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.",
"Parameters" : {
"InstanceType" : {
"Description" : "WebServer EC2 instance type",
"Type" : "String",
"Default" : "t2.micro",
"AllowedValues" : [ "t2.micro", "t2.small", "t2.medium"],
"ConstraintDescription" : "must be a valid EC2 instance type."
},
"SSHLocation" : {
"Description" : "The IP address range that can be used to SSH to the EC2 instances",
"Type": "String",
"MinLength": "9",
"MaxLength": "18",
"Default": "0.0.0.0/0",
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
}
},
"Mappings" : {
"AWSInstanceType2Arch" : {
"t2.micro" : { "Arch" : "HVM64" },
"t2.small" : { "Arch" : "HVM64" },
"t2.medium" : { "Arch" : "HVM64" }
},
"AWSInstanceType2NATArch" : {
"t2.micro" : { "Arch" : "NATHVM64" },
"t2.small" : { "Arch" : "NATHVM64" },
"t2.medium" : { "Arch" : "NATHVM64" }
},
"AWSRegionArch2AMI" : {
"us-east-1" : {"HVM64" : "ami-032930428bf1abbff", "HVMG2" : "ami-0aeb704d503081ea6"}
}
},
"Resources" : {
"EC2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"InstanceType" : { "Ref" : "InstanceType" },
"SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ],
"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },
{ "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }
}
},
"InstanceSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Enable SSH access via port 22",
"SecurityGroupIngress" : [ {
"IpProtocol" : "tcp",
"FromPort" : "22",
"ToPort" : "22",
"CidrIp" : { "Ref" : "SSHLocation"}
} ]
}
}
},
"Outputs" : {
"PublicIP" : {
"Description" : "Public IP address of the newly created EC2 instance",
"Value" : { "Fn::GetAtt" : [ "EC2Instance", "PublicIp" ] }
}
}
}b) Create a CloudFormation stack using a template present in an S3 bucket.
- Goto to CloudFormation. Click Services, click on CloudFormation in the Management & Governance section.
On the CloudFormation dashboard, click on Create Stack.
2. Specify stack details, Stack Name: Enter DemoStack
For Parameters, Enter the details as mentioned below:
Instance type: Select t2.micro (default)
SSHLocation: Enter 0.0.0.0/0 (default)
Click on Next and create.
Wait till Stack creation is having status as CREATE_IN_PROGRESS and it may take up to 3 minutes for the status to change to CREATE_COMPLETE.
Let’s update the template and deploy the changes.
c) Create a Change set for the CloudFormation stack
In this task, we will create a change set for a CloudFormation stack to preview the modifications before applying them.
Note: A change set allows you to assess the impact of the proposed updates, review resource changes, and identify any potential issues or conflicts.
Steps:
1. From the left panel, click on Stacks.
2. To create a change set, perform the following tasks
• Select the present stack.
• Click on the Stack actions button.
• Choose the option of Create change set for current stack.
Specify stack,
Prerequisite — Prepare template: Select Edit template in designer.
Click on the View in Designer.
Once the editor opens. Make sure JSON is choosen as Template language. And then do the required changes.
On Line number 5, Change the metadata for the instance’s description, New Description: “EC2 instance with t2.medium as instance type”
Update the parameters value, On Line number 15, Change the default value of instance type to “t2.medium”
On Line number 20, Change the variable name to “HTTPLocation”.
And, On Line number 21, Update the description as “The IP address range that can be used to HTTP to the EC2 instances”.
No changes are required in Mappings and Resources. No changes in the EC2 Instance section because it is using mappings as a field.
Get Sumbul Naqvi’s stories in your inbox
Join Medium for free to get updates from this writer.
On Line number 64, Update the Group description to “Enable HTTP access via port 80”.
On Line number 67–68, In SecurityGroupIngress, Update FromPort and ToPort to 80.
On Line number 69, Change the reference of CidrIp to “HTTPLocation”.
In Outputs, On Line number 76, Change the variable to “PrivateIP”.
On Line number 77, Update the Description to the “Private IP address of the newly created EC2 instance”.
Lastly, On Line number 78, Update the GetAtt function to “EC2Instance”, “PrivateIp”.
Thus changes while being implemented, will look like:
Once all the changes are done click on the Validate template button (√ ) to verify. The validation will not take much time to go from Validating the template to Template is valid state.
After validation, click on the Save button.
Once you click on the Save button, the popup will appear to ask you whether you want to save to a Local file or Amazon S3 Bucket.
Select S3 Bucket and Rename the template to Demo, click on the Save button.
Now, copy the S3 Bucket URL and save it in your notepad. Click on the OK button to close the pop-up window.
Let’s create the stack now, to do so, click on the Create stack icon.
You will be redirected back to Specify template page. Now, paste the copied S3 Bucket URL and then click on the Next button.
Specify stack details. All the changes done in the previous step are now reflected as we have updated the template.
Click on the Next button to proceed further.
Note: In case, t2.medium is not selected, please select from the drop- down. Keep everything as default.
Click on the Create change set button, to create the change set which can be executed later. On the pop-up window, rename the Change set name as DemoStack-ChangeSet, and click on the Create change set button.
Change set creation will take a couple of seconds to create, click on the refresh icon to see the CREATE_COMPLETE status.
Change set is now created successfully. 😊
Note: Before executing the change set, you can view all the changes. Just scroll below.
Now, click on the Execute at the top right corner.
On the Execute Change set popup, choose Roll back all stack resources.
Now click on Execute change set button to execute the change set.
Changes will be applied immediately and the status of a stack will go to UPDATE_IN_PROGRESS. Then to UPDATE_COMPLETE.
d) Check the updates and changes applied.
- Switch to the Resources tab.
- Click on the Physical ID of the EC2 Instance.
EC2 Instance will open in the new tab, and here you can see the Instance type is now updated to t2.medium. 😊
3. Go to the previous tab, where you have the Resources tab open, click on the Physical ID of the Instance Security group.
The EC2 security group will open in the new tab, switch to the Inbound rules tab to see the HTTP as Type and 80 as Port range. 😊
Go to the previous tab, where you have the Resources tab open, now switch to the Outputs tab.
PrivateIP of the Instance is now showing up in outputs along with the variable name and the updated description.😊
Thus we see that all the changes we wanted have been implemented .😊
Note: CloudFormation can perform drift detection to identify any configuration changes made directly to the resources in the stack outside of CloudFormation. This helps you identify inconsistencies and maintain control over your infrastructure configuration.
Thanks,
Happy learning & sharing 😊
Sumbul







