07 12 / 2012

Amazon CloudFormation Primer

Amazon CloudFormation (CFN) is an AWS service which provides users with a way to describe the AWS resources they want created, in a declarative and re-usable fashion, through the use of simple JSON formatted text files. It supports a wide variety of AWS services, includes the ability to pass in user supplied paramaters, has a nice set of CLI tools, and a few handy functions you are able to use in the JSON files.

Stacks

CloudFormation starts with the idea of a stack. A stack is a JSON formatted file with the following attributes

  • A template the stack will be based on
  • A list of template parameters, user supplied inputs, such as a EC2 instance or VPC id
  • An optional list of mappings which are used to lookup values, such as AMI ids for different regions
  • An optional list of data tables used to lookup static configuration values (e.g. AMI names)
  • The list of AWS resources and their configuration values
  • A list of outputs, such as the id of an ELB instance that was created

A stack can be created using the AWS Console, the CLI tools, or an API library. Stacks can be as re-usable or as monolithic as your choose to make them. A future post will cover some ideas on CFN stack re-usable, design goals, and driving CFN stacks with Boto, but this post is going to focus on getting you up and running with a simple stack and give you some jumping off points for further research on your own.

You’re able to use templates to create new stacks or update existing stacks.

Cost

CloudFormation itself does not cost anything. You are charged the normal AWS costs for any resources created as part of creating a new stack or updating an existing stack.

It’s important to note you’re charged a full hour for any resources costs, even if you’re stack gets rolled back due to an error during stack creation.

* This can mean it could become costly if you’re not careful while testing and building your templates and stacks. *

Getting Started

We’re going to assume you already have an AWS account and are familiar with editing JSON files.

To get started you’ll need to install the CFN CLI tools.

Writing a basic template

A template is a JSON formatted text file. Amazon ends theirs with a .template, while I prefer to name mine .json as, for naming and syntax highlighting reasons, but ultimately this is arbitrary.

A template begins with the AWSTemplateFormatVersion and a Description, and must contain at least one Resources block with a single Resource.

A most basic template only needs what is show below

basic.template

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "basic template",

  "Resources" : {
    "Ec2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : "ami-16fd7026"
      }
    }
  }
}

A template can contain Parameters for user input. An example of this would be a parameter for the instance type.

As you’ll see in the example below, you refer to paramaters or other values using a special function, called Ref.

basic-paramater.template

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "basic template with instance parameter",

  "Parameters" : {
    "InstanceTypeInput" : {
      "Description" : "EC2 instance type",
      "Type" : "String"
    }
  },

  "Resources" : {
    "Ec2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "InstanceType" : { "Ref" : "InstanceTypeInput"},
        "ImageId" : "ami-16fd7026"
      }
    }
  }
}

Sometimes Mappings are a better option than Parameters, a common pattern you’ll see in CFN templates is using a Mapping for the AMI ids in various AWS rgions, as shown below

basic-mapping.template

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "basic template with AMI id mapping",

  "Parameters" : {
    "InstanceTypeInput" : {
      "Description" : "EC2 instance type",
      "Type" : "String"
    }
  },

  "Mappings" : {
    "RegionMap" : {
      "us-east-1"      : { "AMI" : "ami-7f418316" },
      "us-west-1"      : { "AMI" : "ami-951945d0" },
      "us-west-2"      : { "AMI" : "ami-16fd7026" },
      "eu-west-1"      : { "AMI" : "ami-24506250" },
      "sa-east-1"      : { "AMI" : "ami-3e3be423" },
      "ap-southeast-1" : { "AMI" : "ami-74dda626" },
      "ap-northeast-1" : { "AMI" : "ami-dcfa4edd" }
    }
  },


  "Resources" : {
    "Ec2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "InstanceType" : { "Ref" : "InstanceTypeInput"},
        "ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}
      }
    }
  }
}

Finally, you’re usually going to want to use one or more Outputs in your template to provide you with information about the resources the creation of stack made.

basic-output.template

{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "basic template with instance id output",

  "Parameters" : {
    "InstanceTypeInput" : {
      "Description" : "EC2 instance type",
      "Type" : "String"
    }
  },

  "Mappings" : {
    "RegionMap" : {
      "us-east-1"      : { "AMI" : "ami-7f418316" },
      "us-west-1"      : { "AMI" : "ami-951945d0" },
      "us-west-2"      : { "AMI" : "ami-16fd7026" },
      "eu-west-1"      : { "AMI" : "ami-24506250" },
      "sa-east-1"      : { "AMI" : "ami-3e3be423" },
      "ap-southeast-1" : { "AMI" : "ami-74dda626" },
      "ap-northeast-1" : { "AMI" : "ami-dcfa4edd" }
    }
  },


  "Resources" : {
    "Ec2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "InstanceType" : { "Ref" : "InstanceTypeInput"},
        "ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}
      }
    }
  },

  "Outputs" : {
    "InstanceId" : {
      "Description" : "InstanceId of the newly created EC2 instance",
      "Value" : { "Ref" : "Ec2Instance" }
    }
  }
}

Once you’ve created a template, you’ll want to validate that it works with the cfn-validate-template command from the CLI tools.

An example of using it with a local file is shown below

cfn-validate-template --template-file basic-output.template

PARAMETERS InstanceTypeInput false EC2 instance type

After you’ve verified the template is valid, you can try creating it using the cfn-create-stack command. The you give the command a stackname and a file or URL for the template you want to use. The command will return some info, including the new stack id

Note:__Running this command with a template will create AWS resources, that you will be billed for if they exceed your free tier__

An example of creating a stack is shown below

cfn-create-stack basic-test-1 --template-file basic.template

arn:aws:cloudformation:us-west-2:740810067088:stack/basic-test-1/bae25430-4037-11e2-ac91-50698256405b

You can check the progress of the stack creation with the cfn-describe-stack-events, which you give the stackname.

An example of a stack creation in progress

cfn-describe-stack-events basic-test-1

STACK_EVENT basic-test-1 Ec2Instance AWS::EC2::Instance 2012-12-07T06:35:42Z CREATE_IN_PROGRESS

STACK_EVENT basic-test-1 basic-test-1 AWS::CloudFormation::Stack 2012-12-07T06:35:37Z CREATE_IN_PROGRESS User Initiated

An example of the stack creation finished

cfn-describe-stack-events basic-test-1

STACK_EVENT basic-test-1 basic-test-1 AWS::CloudFormation::Stack 2012-12-07T06:36:24Z CREATE_COMPLETE

STACK_EVENT basic-test-1 Ec2Instance AWS::EC2::Instance 2012-12-07T06:36:24Z CREATE_COMPLETE

STACK_EVENT basic-test-1 Ec2Instance AWS::EC2::Instance 2012-12-07T06:35:42Z CREATE_IN_PROGRESS

STACK_EVENT basic-test-1 basic-test-1 AWS::CloudFormation::Stack 2012-12-07T06:35:37Z CREATE_IN_PROGRESS User Initiated

To delete the stack, you use the cfn_delete_stack command and give it the stackname. An example run is shown below.

cfn-delete-stack basic-test-1

Warning: Deleting a stack will lead to deallocation of all of the stack's resources. Are you sure you want to delete this stack? [Ny]y

At this point we’ve covered writing some basic templates and how to get started using a template with the CLI tools.

Where to go from here

To start you should read the Learn Template Basics and Working with Templates documentation.

While writing and exploring templates, I highly recommend getting familiar with the Template Reference which has detailed docs on the various Template types, their properties, return values, etc.

Finally, Amazon has provided a wide variety of templates in the Sample Templates library, ranging from single EC2 instances, to Drupal or Redmine application stacks, and even a full blown multi-tier application in a VPC, which you’re able to download and run.

I’ve put the samples from this article in the Github repository as well.

I hope you’ve found this post helpful in getting started with CloudFormation.

  1. technicalpicklejar reblogged this from awsadvent
  2. awsadvent posted this