Initializing Amazon EC2 Instances with AWS CloudFormation Init
On This Page
Lab
Establishing Desired EC2 Instance State with AWS CloudFormation Init
1. In the AWS Console search bar, search for cloudformation and click the CloudFormation result under Services:
2. Click the Create stack dropdown menu and select With new resources:
3. In the Create stack form, in the Specify template section, ensure Amazon S3 URLis selected for the Template source.
4. Paste in the following URL in the Amazon S3 URL field:
AWSTemplateFormatVersion: '2010-09-09'
Description: Provision a Single Amazon EC2 Instance with CFN Helper Scripts
Parameters:
AmiID:
Description: The ID of the AMI.
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref AmiID
InstanceType: t3.micro
SecurityGroupIds:
- !Ref WebServerSecurityGroup
UserData:
# Update aws-cfn-bootstrap
# Run cfn-init to initialize WebServer content
# Return cfn-init run result to CloudFormation upon completion
Fn::Base64:
!Sub |
#!/bin/bash -xe
yum update -y aws-cfn-bootstrap
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServer --region ${AWS::Region}
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServer --region ${AWS::Region}
CreationPolicy:
ResourceSignal:
Count: 1
Timeout: PT5M
Metadata:
AWS::CloudFormation::Init:
config:
packages:
yum:
httpd: []
files:
"/var/www/html/index.html":
content: |
<center>
<h1>Cloud Academy EC2 Instance</h1>
<h3>This content has been initialized with <a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-helper-scripts-reference.html" target="_blank">AWS CloudFormation Helper Scripts</a></h3>
</center>
mode: '000644'
services:
sysvinit:
httpd:
enabled: 'true'
ensureRunning: 'true'
WebServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SSH and HTTP
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
FromPort: 22
IpProtocol: tcp
ToPort: 22
- CidrIp: 0.0.0.0/0
FromPort: 80
IpProtocol: tcp
ToPort: 80
Outputs:
WebServerPublicDNS:
Description: Public DNS of EC2 instance
Value: !GetAtt WebServer.PublicDnsName
The CloudFormation stack template is stored in a public S3 bucket. The EC2 instance resource definition is shown below:
The WebServer
EC2 instance is defined above. It is a size t3.micro
instance that references a WebServerSecurityGroup
resource for its security group and the AmiID
parameter for its image ID. Both of these referenced configurations are defined elsewhere in the template.
The UserData
script defined next performs the following tasks once the EC2 instance is created:
- Updates the
aws-cfn-bootstrap
package to retrieve the latest version of the helper scripts - Runs the
cfn-init
helper script to execute theWebServer
instanceMetadata
scripts - Runs the
cfn-signal
helper script to notify CloudFormation after all the service(s) (Apache in this case) is installed and configured on the EC2 instance
Note: The cfn-init
helper script is not executed automatically. You must run the cfn-init
script within the EC2 instance UserData
in order to execute your metadata scripts.
The cfn-signal
helper script works hand-in-hand with the CreationPolicy
configuration. The ResourceSignal
property has a Count
of 1
and a Timeout
of PT5M
. This instructs CloudFormation to wait for up to 5 minutes to receive 1 resource signal from the EC2 instance.
The cfn-signal
helper script call in the UserData
uses $?
to retrieve the return code of the previous script. If the cfn-init
script is successful and the EC2 instance is configured properly, cfn-signal
returns a success to CloudFormation which then transitions the EC2 instance to the CREATE_COMPLETEstatus. If the cfn-init
script is unsuccessful or the timeout of 5 minutes expires before receiving a signal, then the EC2 instance will be transitioned to a CREATE_FAILEDstatus and the stack deployment will fail.
The EC2 instance Metadata
configuration is the same as the previous lab step. It defines a AWS::CloudFormation::Init
script to install the httpd
package using yum
, generate an index.html
file within /var/www/html/
and start the httpd
service to serve the content from the EC2 instance.
5. Click Nextto continue:
6. Enter web-server-stack for the Stack name and click Next:
7. You will not be configuring additional stack options. Scroll to the bottom of the page and click Next.
8. On the review page, scroll to the bottom and click Create stackto deploy your stack:
Your stack will begin deploying and you will be brought to the Events page of your web-server-stack:
The stack can take up to 3 minutes to deploy successfully.
9. If the Events section does not automatically refresh after 3 minutes, click the refresh icon:
The WebServer instance remains in a CREATE_IN_PROGRESS status until CloudFormation receives a SUCCESS signal from the instance. In the screenshot above, the UniqueId of i-0fd18c8deb52983d5 belongs to the WebServer instance.
After the success signal is received, the WebServer instance is transitioned into the CREATE_COMPLETE status.
Without the CloudFormation signal helper script, CloudFormation would have transitioned the EC2 instance to a completed status when the resource was created instead of waiting until the Apache service has been installed and running on the instance.
10. Click the Outputs tab on the web-server-stack page:
11. Right-click and open the WebServerPublicDNS URL in a new browser tab:
The HTMLpage generated in the cfn-init script is now being served from the Apache server running within your WebServer EC2 instance: