In this task, your objective is to add an Amazon EC2 instance to the template, then update the stack with the revised template.
Whereas the bucket definition was rather simple (just two to four lines), defining an Amazon EC2 instance is more complex because it needs to use associated resources, such as an AMI, security group and subnet.
For this exercise we wil assume you now know how to edit your CloudFormation template and update your CloudFormation stack with the updated template
In the Parameters section of your template, look at the LatestAmiId parameter.
LatestAmiId: Description: Gets the latest AMI from Systems Manager Parameter store Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>' Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
This is a special parameter. This parameter uses the AWS Systems Manager Parameter Store to retrieve the latest AMI (specified in the Default parameter, which in this case is Amazon Linux 2) for the stack’s region. This makes it easy to deploy stacks in different regions without having to manually specify an AMI ID for every region.
For more details of this method, see: AWS Compute Blog: Query for the latest Amazon Linux AMI IDs using AWS Systems Manager Parameter Store
Edit the CloudFormation Template, adding a new resource for an EC2 instance
Use this documentation page for assistance: AWS::EC2::Instance
You only need to specify these six properties:
IamInstanceProfile: Refer to
Web1InstanceInstanceProfile, which is defined elsewhere in the template
ImageId: Refer to
LatestAmiId, which is the parameter discussed previously
InstanceType: Refer to
InstanceType, another parameter
SecurityGroupIds: Refer to
PublicSecurityGroup, which is defined elsewhere in the template
SubnetId: Refer to
PublicSubnet1, which is defined elsewhere in the template
Tags: Use this YAML block:
Tags: - Key: Name Value: Simple Server
When referring to other resources in the same template, use
!Ref. See the
BucketName example you already implemented
When referring to SecurityGroupIds, the template is actually expecting a list of security groups. You therefore need to list the security group like this:
SecurityGroupIds: - !Ref PublicSecurityGroup
Not sure what to do???
Once you have edited the template, update the stack deployment with your revised template file.
On the Parameters screen of the CloudFormation update switch EC2SecurityEnabledParam to
|Change EC2SecurityEnabledParam to |
|This will tell the template to create resources your EC2 instance will need such as the Security Group and IAM Role|
This deployment of the CloudFormation stack will take about three minutes
The instance will now be displayed in the Resources tab.
Go to the EC2 console to see the Simple Server that was created. Explore the properties of this EC2 instance.
The final deployment is now represented by this architecture diagram:
In this task you will update your CloudFormation template to modify the deployed EC2 instance so that it runs a simple web server
Modify the EC2 resource in the template
Delete the following properties form the EC2 resource
Add the following properties using the YAML below
NetworkInterfaces: adds an external IP address (and DNS name) for the EC2 instance
UserData: a simple bash script to install and run an Apache web server. This runs on EC2 instance creation only.
Visually the diff for this looks like:
The final EC2 instance resource should look like this:
MyEC2Instance: Type: AWS::EC2::Instance Properties: IamInstanceProfile: !Ref Web1InstanceInstanceProfile ImageId: !Ref LatestAmiId InstanceType: !Ref InstanceType Tags: - Key: Name Value: Simple Server NetworkInterfaces: - AssociatePublicIpAddress: "true" DeviceIndex: "0" GroupSet: - Ref: PublicSecurityGroup SubnetId: Ref: PublicSubnet1 UserData: Fn::Base64: | #!/bin/bash yum -y update sudo yum install -y httpd sudo systemctl start httpd
Add an output value so you can easily find the public DNS of the EC2 instance
Insert the following YAML under the Outputs section of your CloudFormation template
PublicServerDNS: Value: !GetAtt MyEC2Instance.PublicDnsName
Use the other entry under Outputs to ensure your new entry has the right indentation
!GetAtt function can return various attributes of the resource. In this case the public DNS name of the EC2 instance.
NOTE: if you used a Logical ID other than
MyEC2Instance when you added your EC2 resource, then you should use that name here
To download a sample solution, right-click and download this link: simple_stack_plus_s3_ec2_server.yaml
Update the CloudFormation stack using the modified template
After deployment is complete, click on the Outputs tab for the CloudFormation stack
You should see the Apache HTTP server Test Page, indicating your EC2 instance is running the web server and is accessible from the Internet.