An intro to writing AWS CloudFormation Templates

AWS  introduced recently the ability to create & document  your AWS environment via CloudFormation. You need to create a JSON template that describes your environment . This template  is then used to create your AWS Stack.  The AWS documentation is pretty good but the getting started guide starts you off by using an example template .  I think a walk through showing you what the component parts that make up a  template are and how to put them  together is a much better starting point if you want to create a stack for your own AWS environment so here you are.

There are 6 basic components that can be used in the JSON Cloudformation templates that you need to become familiar with.

Format version (optional): The AWS CloudFormation template version against which the template was written

Description (optional):  JSON   text string description of template or part of template

Parameters (optional):  String or comma separated list. The values can be overridden at run time. Parameters are dereferenced in resources and outputs section of  the template e.g  you can declare a Parameter  called InstanceType with a default of t1.micro that can be overridden at Stack instantiation to be an alternative InstanceType.

*******************************************

“InstanceType”   : {

“Type”   : “String”,

“Default”   : “t1.micro”,

“Description”  : ” ‘t1.micro’ |  ‘m1.large’ |  ‘c1.xlarge’ ”

},

*******************************************

Mappings (optional):  Allow the passing of conditional parameter values used with the function Fn::FindInMap. It is similar to a case statement in usage. Used in conjunction with Parameters. Each mapping has a unique name in a template and consists of a number of key-attribute pairs. Each Attribute is a literal string

************************************

“Mappings” : {

“RegionMap” : {

“us-east-1” : {

“AMI” : “ami-8e1fece7”,

“AvailabilityZone” : “us-east-1b”

},

 

“eu-west-1” : {

“AMI” : “ami-45cefa31”,

“AvailabilityZone” : “eu-west-1a”

}

}

},

*********************************

When using the function Fn:FindInMap it needs to be passed the Map name, the  Reference key and the return value

Resources: AWS resources such as instances, RDS etc which are declared as members of the AWS stack . Resources declared in the Resources section contain a Properties section, in which you declare both required and optional properties for the resource.

**********************************

“Resources” : {

“Ec2Instance” : {

“Type” : “AWS::EC2::Instance”,

“Properties” : {

“KeyName” : { “Ref” : “KeyName” },

“AvailabilityZone” : { “Fn::FindInMap” : [ “RegionMap”, { “Ref” : “AWS::Region” }, “AvailabilityZone” ]},

“ImageId” : { “Fn::FindInMap” : [ “RegionMap”, { “Ref” : “AWS::Region” }, “AMI” ]},

“InstanceType” : { “Ref” : “InstanceType”}

}

}

},

********************************

Outputs (optional):  Messages that can be returned as  part of the cfn-describe-stacks command

**********************

“PublicIP” : {

“Description” : “Public IP address of the newly created EC2 instance”,

“Value” : { “Fn::GetAtt” : [ “Ec2Instance”, “PublicIp” ] }

}

****************************************

So putting all the above together to create a template that starts an ec2 instance you get ( I’ve added some bits to make it a workable solution):

******************************

{

“AWSTemplateFormatVersion” : “2010-09-09”,

 

“Description” : “Creates an EC2 instance running the AWS Linux 64 bit AMI from the EU region. “,

 

“Parameters” : {

“KeyName” : {

“Description” : “Name of  EC2 KeyPair to enable SSH access to the instance”,

“Default” : “AWSNet-EU”,

“Type” : “String”

},

“InstanceType”   : {

“Type”   : “String”,

“Default”   : “t1.micro”,

“Description”  : ” ‘t1.micro’ |  ‘m1.large’ |  ‘c1.xlarge’ ”

}

},

 

“Mappings” : {

“RegionMap” : {

“us-east-1” : {

“AMI” : “ami-8e1fece7”,

“AvailabilityZone” : “us-east-1b”

},

 

“eu-west-1” : {

“AMI” : “ami-45cefa31”,

“AvailabilityZone” : “eu-west-1a”

}

}

},

 

“Resources” : {

“Ec2Instance” : {

“Type” : “AWS::EC2::Instance”,

“Properties” : {

“KeyName” : { “Ref” : “KeyName” },

“AvailabilityZone” : { “Fn::FindInMap” : [ “RegionMap”, { “Ref” : “AWS::Region” }, “AvailabilityZone” ]},

“ImageId” : { “Fn::FindInMap” : [ “RegionMap”, { “Ref” : “AWS::Region” }, “AMI” ]},

“InstanceType” : { “Ref” : “InstanceType”}

}

}

},

 

“Outputs” : {

“InstanceId” : {

“Description” : “InstanceId of the newly created EC2 instance”,

“Value” : { “Ref” : “Ec2Instance” }

},

“AZ” : {

“Description” : “Availability Zone of the newly created EC2 instance”,

“Value” : { “Fn::GetAtt” : [ “Ec2Instance”, “AvailabilityZone” ] }

},

“PublicIP” : {

“Description” : “Public IP address of the newly created EC2 instance”,

“Value” : { “Fn::GetAtt” : [ “Ec2Instance”, “PublicIp” ] }

}

}

}

*******************************************************************

 

 


Advertisements

2 comments

  1. sskas · October 14, 2011

    Very well written. Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s