AWS CloudFormation
User Guide (API Version 2010-05-15)

Get Started

With the right template, you can deploy at once all the AWS resources you need for an application. In this section, you'll examine a template that declares the resources for a WordPress blog, creates a WordPress blog as a stack, monitors the stack creation process, examines the resources on the stack, and then deletes the stack. You use the AWS Management Console to complete these tasks.

Step 1: Pick a template

Next, you'll need a template that specifies the resources that you want in your stack. For this step, you use a sample template that is already prepared. The sample template creates a basic WordPress blog that uses a single Amazon EC2 instance with a local MySQL database for storage. The template also creates an Amazon EC2 security group to control firewall settings for the Amazon EC2 instance.


AWS CloudFormation is free, but the AWS resources that AWS CloudFormation creates are live (and not running in a sandbox). You will incur the standard usage fees for these resources until you terminate them in the last task in this tutorial. The total charges will be minimal. For information about how you might minimize any charges, go to

To view the template

  • You can view the JSON or YAML WordPress sample template. You don't need to download it because you will use the template URL later in this guide. For more information about the template formats, see AWS CloudFormation Template Formats.

A template is a JSON or YAML text file that contains the configuration information about the AWS resources you want to create in the stack. For this walkthrough, the sample template includes six top-level sections: AWSTemplateFormatVersion, Description, Parameters, Mappings, Resources, and Outputs; however, only the Resources section is required.

The Resources section contains the definitions of the AWS resources you want to create with the template. Each resource is listed separately and specifies the properties that are necessary for creating that particular resource. The following resource declaration is the configuration for the EC2 instance, which in this example has the logical name WebServer:


"Resources" : { ... "WebServer": { "Type" : "AWS::EC2::Instance", "Properties": { "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, "InstanceType" : { "Ref" : "InstanceType" }, "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], "KeyName" : { "Ref" : "KeyName" }, "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -xe\n", "yum update -y aws-cfn-bootstrap\n", "/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServer ", " --configsets wordpress_install ", " --region ", { "Ref" : "AWS::Region" }, "\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource WebServer ", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]}} }, ... }, ... "WebServerSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Enable HTTP access via port 80 locked down to the load balancer + SSH access", "SecurityGroupIngress" : [ {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : ""}, {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}} ] } }, ... },


Resources: ... WebServer: Type: AWS::EC2::Instance Properties: ImageId: !FindInMap [AWSRegionArch2AMI, !Ref 'AWS::Region', !FindInMap [AWSInstanceType2Arch, !Ref InstanceType, Arch]] InstanceType: Ref: InstanceType KeyName: Ref: KeyName SecurityGroups: - Ref: WebServerSecurityGroup UserData: Fn::Base64: !Sub | #!/bin/bash -xe yum update -y aws-cfn-bootstrap /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource WebServer --configsets wordpress_install --region ${AWS::Region} /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource WebServer --region ${AWS::Region} ... ... WebServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "Enable HTTP access via port 80 locked down to the load balancer + SSH access" SecurityGroupIngress: - CidrIp: FromPort: '80' IpProtocol: tcp ToPort: '80' - CidrIp: !Ref SSHLocation FromPort: '22' IpProtocol: tcp ToPort: '22' ...

If you have created EC2 instances before, you can recognize properties, such as ImageId, InstanceType, and KeyName, that determine the configuration of the instance. Resource declarations are an efficient way to specify all these configuration settings at once. When you put resource declarations in a template, you can create and configure all the declared resources easily by using the template to create a stack. To launch the same configuration of resources, all you have to do is create a new stack that uses the same template.

The resource declaration begins with a string that specifies the logical name for the resource. As you'll see, the logical name can be used to refer to resources within the template.

You use the Parameters section to declare values that can be passed to the template when you create the stack. A parameter is an effective way to specify sensitive information, such as user names and passwords, that you don't want to store in the template itself. It is also a way to specify information that might be unique to the specific application or configuration you are deploying, for example, a domain name or instance type. When you create the WordPress stack later in this section, you'll see the set of parameters declared in the template appear on the Specify Details page of the Create Stack wizard, where you can specify the parameters before you create the stack.

The following parameters are used in the template to specify values that are used in properties of the EC2 instance:


"Parameters" : { ... "KeyName": { "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances", "Type": "AWS::EC2::KeyPair::KeyName", "ConstraintDescription" : "must be the name of an existing EC2 KeyPair." }, "InstanceType" : { "Description" : "WebServer EC2 instance type", "Type" : "String", "Default" : "t2.small", "AllowedValues" : [ "t1.micro", "t2.nano", "t2.micro", "t2.small", "t2.medium", "t2.large", "m1.small", "m1.medium", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "m4.large", "m4.xlarge", "m4.2xlarge", "m4.4xlarge", "m4.10xlarge", "c1.medium", "c1.xlarge", "c3.large", "c3.xlarge", "c3.2xlarge", "c3.4xlarge", "c3.8xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "g2.8xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge", "i2.xlarge", "i2.2xlarge", "i2.4xlarge", "i2.8xlarge", "d2.xlarge", "d2.2xlarge", "d2.4xlarge", "d2.8xlarge", "hi1.4xlarge", "hs1.8xlarge", "cr1.8xlarge", "cc2.8xlarge", "cg1.4xlarge"], "ConstraintDescription" : "must be a valid EC2 instance type." }, ...


Parameters: ... KeyName: ConstraintDescription: must be the name of an existing EC2 KeyPair. Description: Name of an existing EC2 KeyPair to enable SSH access to the instances Type: AWS::EC2::KeyPair::KeyName InstanceType: AllowedValues: - t1.micro - t2.nano - t2.micro - t2.small - t2.medium - t2.large - m1.small - m1.medium - m1.large - m1.xlarge - m2.xlarge - m2.2xlarge - m2.4xlarge - m3.medium - m3.large - m3.xlarge - m3.2xlarge - m4.large - m4.xlarge - m4.2xlarge - m4.4xlarge - m4.10xlarge - c1.medium - c1.xlarge - c3.large - c3.xlarge - c3.2xlarge - c3.4xlarge - c3.8xlarge - c4.large - c4.xlarge - c4.2xlarge - c4.4xlarge - c4.8xlarge - g2.2xlarge - g2.8xlarge - r3.large - r3.xlarge - r3.2xlarge - r3.4xlarge - r3.8xlarge - i2.xlarge - i2.2xlarge - i2.4xlarge - i2.8xlarge - d2.xlarge - d2.2xlarge - d2.4xlarge - d2.8xlarge - hi1.4xlarge - hs1.8xlarge - cr1.8xlarge - cc2.8xlarge - cg1.4xlarge ConstraintDescription: must be a valid EC2 instance type. Default: t2.small Description: WebServer EC2 instance type Type: String ...

In the WebServer resource declaration, you see the KeyName property specified with the KeyName parameter:


"WebServer" : { "Type": "AWS::EC2::Instance", "Properties": { "KeyName" : { "Ref" : "KeyName" }, ... } },


WebServer: Type: AWS::EC2::Instance Properties: KeyName: Ref: KeyName ...

The braces contain a call to the Ref function with KeyName as its input. The Ref function returns the value of the object it refers to. In this case, the Ref function sets the KeyName property to the value that was specified for KeyName when the stack was created.

The Ref function can also set a resource's property to the value of another resource. For example, the resource declaration WebServer contains the following property declaration:


"WebServer" : { "Type": "AWS::EC2::Instance", "Properties": { ... "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], ... } },


WebServer: Type: AWS::EC2::Instance Properties: SecurityGroups: - Ref: WebServerSecurityGroup ...

The SecurityGroups property takes a list of EC2 security groups. The Ref function has an input of WebServerSecurityGroup, which is the logical name of a security group in the template, and adds the name of WebServerSecurityGroup to the SecurityGroups property.

In the template, you'll also find a Mappings section. You use mappings to declare conditional values that are evaluated in a similar manner as a lookup table statement. The template uses mappings to select the correct Amazon machine image (AMI) for the region and the architecture type for the instance type. Outputs define custom values that are returned by the aws cloudformation describe-stacks command and in the AWS CloudFormation console Outputs tab after the stack is created. You can use output values to return information from the resources in the stack, such as the URL for a website that was created in the template. We cover mappings, outputs, and other things about templates in more detail in Learn Template Basics.

That's enough about templates for now. Let's start creating a stack.

Step 2: Make sure you have prepared any required items for the stack

Before you create a stack from a template, you must ensure that all dependent resources that the template requires are available. A template can use or refer to both existing AWS resources and resources declared in the template itself. AWS CloudFormation takes care of checking references to resources in the template and also checks references to existing resources to ensure that they exist in the region where you are creating the stack. If your template refers to a dependent resource that does not exist, stack creation fails.

The example WordPress template contains an input parameter, KeyName, that specifies the key pair used for the Amazon EC2 instance that is declared in the template. The template depends on the user who creates a stack from the template to supply a valid Amazon EC2 key pair for the KeyName parameter. If you supply a valid key pair name, the stack creates successfully. If you don't supply a valid key pair name, the stack is rolled back.

Make sure you have a valid Amazon EC2 key pair and record the key pair name before you create the stack.

To see your key pairs, open the Amazon EC2 console, then click Key Pairs in the navigation pane.


If you don't have an Amazon EC2 key pair, you must create the key pair in the same region where you are creating the stack. For information about creating a key pair, see Getting an SSH Key Pair in the Amazon EC2 User Guide for Linux Instances.

Now that you have a valid key pair, let's use the WordPress template to create a stack.

Step 3: Create the stack

You will create your stack based on the WordPress-1.0.0 file discussed earlier. The template contains several AWS resources, such as an EC2 instance.

To create the WordPress stack

  1. Sign in to the AWS Management Console and open the AWS CloudFormation console at

  2. If this is a new AWS CloudFormation account, click Create New Stack. Otherwise, click Create Stack.

  3. In the Template section, select Specify an Amazon S3 Template URL to type or paste the URL for the sample WordPress template, and then click Next:


    AWS CloudFormation templates that are stored in an S3 bucket must be accessible to the user who is creating the stack, and must be located in the same region as the stack that is being created. Therefore, if the S3 bucket is located in the us-east-1 Region, the stack must also be created in us-east-1.

  4. In the Specify Details section, enter a stack name in the Name field. For this example, use MyWPTestStack. The stack name cannot contain spaces.

  5. In the KeyName field, enter the name of a valid Amazon EC2 key pair in the same region you are creating the stack.


    On the Specify Parameters page, you'll recognize the parameters from the Parameters section of the template.

  6. Click Next.

  7. In this scenario, we won't add any tags. Click Next. Tags, which are key-value pairs, can help you identify your stacks. For more information, see Adding Tags to Your AWS CloudFormation Stack.

  8. Review the information for the stack. When you're satisfied with the settings, click Create.

Your stack might take several minutes to create—but you probably don't want to just sit around waiting. If you're like us, you'll want to know how the stack creation is going.

Step 4: Monitor the progress of stack creation

After you complete the Create Stack wizard, AWS CloudFormation begins creating the resources that are specified in the template. Your new stack, MyWPTestStack, appears in the list at the top portion of the CloudFormation console. Its status should be CREATE_IN_PROGRESS. You can see detailed status for a stack by viewing its events.

To view the events for the stack

  1. On the AWS CloudFormation console, select the stack MyWPTestStack in the list.

  2. In the stack details pane, click the Events tab.

    The console automatically refreshes the event list with the most recent events every 60 seconds.

The Events tab displays each major step in the creation of the stack sorted by the time of each event, with latest events on top.

The first event (at the bottom of the event list) is the start of the stack creation process:

2013-04-24 18:54 UTC-7 CREATE_IN_PROGRESS AWS::CloudFormation::Stack MyWPTestStack User initiated

Next are events that mark the beginning and completion of the creation of each resource. For example, creation of the EC2 instance results in the following entries:

2013-04-24 18:59 UTC-7 CREATE_COMPLETE AWS::EC2::Instance...

2013-04-24 18:54 UTC-7 CREATE_IN_PROGRESS AWS::EC2::Instance...

The CREATE_IN_PROGRESS event is logged when AWS CloudFormation reports that it has begun to create the resource. The CREATE_COMPLETE event is logged when the resource is successfully created.

When AWS CloudFormation has successfully created the stack, you will see the following event at the top of the Events tab:

2013-04-24 19:17 UTC-7 CREATE_COMPLETE AWS::CloudFormation::Stack MyWPTestStack

If AWS CloudFormation cannot create a resource, it reports a CREATE_FAILED event and, by default, rolls back the stack and deletes any resources that have been created. The Status Reason column displays the issue that caused the failure.

Step 5: Use your stack resources

When the stack MyWPTestStack has a status of CREATE_COMPLETE, AWS CloudFormation has finished creating the stack, and you can start using its resources.

The sample WordPress stack creates a WordPress website. You can continue with the WordPress setup by running the WordPress installation script.

To complete the WordPress installation

  1. On the Outputs tab, in the WebsiteURL row, click the link in the Value column.

    The WebsiteURL output value is the URL of the installation script for the WordPress website that you created with the stack.

  2. On the web page for the WordPress installation, follow the on-screen instructions to complete the WordPress installation. For more information about installing WordPress, see

    After you complete the installation and log in, you are directed to the dashboard where you can set additional options for your WordPress blog. Then, you can start writing posts for your blog that you successfully created by using a AWS CloudFormation template.

Step 6: Clean Up

You have completed the AWS CloudFormation getting started tasks. To make sure you are not charged for any unwanted services, you can clean up by deleting the stack and its resources.

To delete the stack and its resources

  1. From the AWS CloudFormation console, select the MyWPTestStack stack.

  2. Click Delete Stack.

  3. In the confirmation message that appears, click Yes, Delete.

The status for MyWPTestStack changes to DELETE_IN_PROGRESS. In the same way you monitored the creation of the stack, you can monitor its deletion by using the Event tab. When AWS CloudFormation completes the deletion of the stack, it removes the stack from the list.

Congratulations! You successfully picked a template, created a stack, viewed and used its resources, and deleted the stack and its resources. Not only that, you were able to set up a WordPress blog using a AWS CloudFormation template. You can find other templates in the AWS CloudFormation Sample Template Library.

Now it's time to learn more about templates so that you can easily modify existing templates or create your own: Learn Template Basics.