To learn AWS Cloud Formation and how to launch EC2 and S3 using cloud formation, you must have the AWS console account and this post assumes that you have already logged in to the AWS console.
This post will show how to launch an EC2 instance, S3, and place the EC2 Instance in a security group using the private key by utilizing Cloud Formation.
Go to Cloud Formation dashboard from Services –> Cloud Formation and Select Create Stack and select “Create Template Designer”.
Create Template in Designer
On the template designer From EC2 drag and drop the Instance to the template and rename it as per your needs and remember to refresh the page by pressing the refresh button on the right. Similarly, add an S3 bucket and rename it accordingly. Each resource has Parameters, Mappings, Conditions, Metadata, and Outputs. Similarly, the template we designed using the designer can be viewed under the template tab at the bottom left.
If we check in the template we can see the JSON code generated by the Cloudformation designer. To understand more about the JSON cloud formation template, let’s now create this template from scratch. Create a JSON file in any text editor but for the best working environment, you can use Visual Studio Code or Visual Studio .Net, it will help in formatting and shows errors with color-coding text.
The blank CloudFormation Template looks like below:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "",
"Parameters" : {
},
"Resources" : {
},
"Outputs" : {
}
}
There are sections called Description, Parameters, Resources, and Outputs. To fill up these you can use sample templates from the AWS Cloud Formation Samples and copy the sample just for launching EC2 and make changes to the template. The template contains the following sections:
Description
It is self-explanatory, this is used to provide the description of the cloud formation template.
Parameters
Parameters contain KeyName, InstanceType, and SSH Location. These are the inputs that the Cloudformation template will ask from the user while creating the stack.
Key Name: A key pair is a combination of a public key that is used to encrypt data and a private key that is used to decrypt data. The users must specify the name of the key pair when they use AWS Service to launch the product that is based on the template. To Create Key Pair you can go to the EC2 console and Key pairs.
Instance Type: Instance type is the type of instance that users can use for EC2 instances like t2.micro, t2.nano, etc. For this demo, let’s remove all and only keep t2.nano, t2.micro (free tier eligible).
SSH Location: Specify which IP address is allowed to access this instance type that you have selected. By default it allows everything but this must be changed to specify which CIDR range or IP must be allowed.
Mappings
In this section, we can map the resources based on the parameters provided by the user. If the user selects t2.micro, then here the mapping of appropriate AMI (Amazon Machine Image) for the user’s region is done. In the parameter sections, there are only two options provided for user input, all the default mappings generated by the template can be removed and only provide the mapping for t2.nano and t2.micro for this demo.
"Mappings" : {
"AWSInstanceType2Arch" : {
"t2.nano" : { "Arch" : "HVM64" },
"t2.micro" : { "Arch" : "HVM64" }
}
Next is the mappings for Regions, the image must be selected. You can remove the unwanted regional mappings and just keep the region where you normally work. Let’s give only two options open for this demo us-east-1 (North Virginia) and ap-southeast-2 (Sydney). For a full list of all the resources mapping examples you can check AWS Cloudformation > User Guide
Resources
Resources is the required section where you declare the resources that you want to include in the stack, like EC2, S3, RDS, etc. There are two default sections here EC2Instance & InstanceSecurityGroup.
EC2Instance: Here you can specify what type of instance that you want. The type of instance has to be passed by the users because it has been specified in the parameter, so it must be picked up in this section by using the keyword “Ref“. Next is the SecurityGroups, which we will configure in the next section. The next Key Name is the key-value pairs picked up from the value passed on the parameters section. Finally, Image ID is where the mapping of the region with the resources will happen based on the selection by the user in the Parameter section.
"Resources" : {
"EC2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"InstanceType" : {
"Ref" : "InstanceType" },
"SecurityGroups" : [
{ "Ref" : "InstanceSecurityGroup"
}
],
"KeyName" : { "Ref" : "KeyName" },
"ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },
{ "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }
}
},
InstanceSecurityGroup: A security group acts as a virtual firewall for your EC2 instances to control incoming and outgoing traffic, inbound rules control the incoming traffic, and outbound rules control the outgoing traffic from your instance. You can specify the security group while launching the instance, if not provided EC2 uses the default security group. It will pick up the SSHlocation or the IP address to use from the parameter section.
Since we want S3 in our Architecture we need to add S3 in the Resources section. To know all the syntax of the resources to include in this section you can refer to the AWS User guide about “AWS resource and property types reference”. Tip: It’s best to pick from the example which will have minimal required JSON code.
"S3Bucket": {
"Type": "AWS::S3::Bucket",
"DeletionPolicy": "Retain",
"Properties": {
"BucketName": "CLOUD-FORMATION-EXAMPLE-001"
},
"DependsOn":
[
"EC2Instance"
]
},
Here you can see, S3Bucket is added in the resources section, and in the end, it tells that it Depends on EC2Instance. This means S3 will wait for EC2Instance to be created first but if you don’t add dependency both will be created in parallel.
Now after creating the required resources you can see the outputs to see the progress of the creation process.
Outputs
The template contains the following default outputs.
InstanceId – InstanceId of the newly created EC2 instance.
AZ – Availability zone information where the Instance is created
PublicDNS – Public DNS name of the newly created instance
Public IP: Public IP address of the newly created instance.
We can keep these as-is for this demo and ad one more section for S3.
"Outputs" : {
"InstanceId" : {
"Description" : "InstanceId of the newly created EC2 instance",
"Value" : { "Ref" : "EC2Instance" }
},
"S3" : {
"Description" : "Bucket Name of S3",
"Value" : { "Ref" : "S3Bucket" }
},
"AZ" : {
"Description" : "Availability Zone of the newly created EC2 instance",
"Value" : { "Fn::GetAtt" : [ "EC2Instance", "AvailabilityZone" ] }
},
"PublicDNS" : {
"Description" : "Public DNSName of the newly created EC2 instance",
"Value" : { "Fn::GetAtt" : [ "EC2Instance", "PublicDnsName" ] }
},
"PublicIP" : {
"Description" : "Public IP address of the newly created EC2 instance",
"Value" : { "Fn::GetAtt" : [ "EC2Instance", "PublicIp" ] }
}
}
Ok after the template is completed you can copy the template and paste it in CloudFormation Designer to see how your template looks visually.
The pink line from S3 to EC2 shows that S3 depends on EC2 Instance. Now on the left-hand side, you can press Create Stack to create the stack from this Cloudformation Template. Or if you save this template and later want to create the stack then you can upload the JSON file while creating Stack.
Create Stack
Go to Cloudformation –> Create Stack –>Upload a template file.
Next Provide Stack name and parameters (Instance Type, KeyName, and SSHLocation-currently allow everyone or provide your restricted CIDR range). In parameters, you can see all the sections contain the values that you specified in the template.
Next, add the tags that you want to call the EC2 instance, and keep all demo and create Stack to create.
In the Events, you can see the progress of the Creation of the Stack.
Here you can see, we have an error and our Stack creation process is rolled back. The error is S3 bucket name should not contain uppercase characters. If you go and check in the EC2 dashboard you can see the instance was created but it got terminated due to the error. Fix the error and try again.
The creation of EC2 and S3 is now successful and if you go and check in the EC2 dashboard and S3 dashboard you can find these resources created successfully.
Similarly, if you check the outputs the values provided in the cloud formation template outputs are displayed here.
Delete Stack
To delete everything that was created by the stack or if you want the whole infrastructure to be cleaned up then go to the stack in CloudFormation > Stacks and select the Stack that you created earlier and press Delete.
Now all the resources will be deleted and cleaned up
This is how cloud formation templated can be used to spin up various infrastructure resources in AWS cloud and therefore Cloudformation is also called Infrastructure as Code.
Please comment and provide feedback on what can be improved or what post you would like me to publish next.