Lab complete!
Now that you have completed this lab, make sure to update your Well-Architected review if you have implemented these changes in your workload.
Click here to access the Well-Architected Tool
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 will 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
MyEC2Instance
You only need to specify these five properties:
ImageId: References LatestAmiId
, which is the parameter discussed previously
InstanceType: References InstanceType
, another parameter
SecurityGroupIds: References PublicSecurityGroup
, which is defined elsewhere in the template
SubnetId: References PublicSubnet1
, which is defined elsewhere in the template
Tags: Use this YAML block:
Tags:
- Key: Name
Value: Simple Server
Remember
When referencing other resources in the same template, use !Ref
. See the BucketName
example you already implemented
When referencing SecurityGroupIds, CloudFormation is 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 true
Important |
---|
Change EC2SecurityEnabledParam to true |
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
After the stack status is UPDATE_COMPLETE, the instance will 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 from the EC2 resource
SecurityGroupIds
SubnetId
Add the following properties using the YAML below
NetworkInterfaces
: adds an external IP address (and DNS name) for the EC2 instanceUserData
: 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:
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:
!Sub |
#!/bin/bash -xe
yum -y update
sudo yum install -y httpd
sudo systemctl start httpd
sudo echo '<h1>Hello from ${AWS::Region}</h1>' > /var/www/html/index.html
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
The !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 and stack status is UPDATE_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.
Now that you have completed this lab, make sure to update your Well-Architected review if you have implemented these changes in your workload.
Click here to access the Well-Architected Tool