Kevin's AWS CloudFormation Notes

From Public wiki of Kevin P. Inscoe
Jump to navigation Jump to search

CloudFormation Mantra

  • Start thinking of deployment as code. Think first like a developer but also as an admin for cost containment.
  • Do E.V.E.R.Y.T.H.I.N.G. as CloudFormation (AWS resource related). it s a new way of thinking. Again think code more than manual steps. To paraphrase Spider Man: "With great Stacks come great responsibility". When Stacks dies everything (attached to it) dies but that's ok if we are being thoughtful.
  • Stacks can be updated to reflect changed resources. It seems more code easy to use CLI (rake update_stacks command) to do this then Console.
  • Save and track templates in Git. Check your revisions and changes.
  • Versioning of Stacks? I don't think it's needed if you think stack updates.
  • Use Stack Policies to protect against mistakes and errant deployments particularly in production.
  • AWS Best Practise:

CloudFormation Practise

  • Use parameterization heavily - See Parameterization
  • Use rake to update templates into AWS. Why? See Rake


Need to understand JSON first:

JSON validation tools: -

Command line (or offline) version of jsonlint - -OR- just call the web site from the command line with: (see also See also Installing jheri-curl on a Mac.

Some other useful JSON tools such as formatters, pretty-print, etc..:

From command line (if you have Python 2.6+ installed): $ python -m json.tool < AWS_CFN_KPI_POC_01.template (for Mac only?)

JSON Editors:

Vim has plug-ins: I have not tried these yet.

On Mac I currently use Cocoa JSON Editor: (Mac only).

Online editors a plenty!

There are cross-platform editors out there.

Sublime was heavily liked ($70) -

More cross platform tools at

CloudFormation tutorials I found useful

CloudFormation creation and generation of templates

CloudFormation is described as a JSON (JavaScript Object Notation) template. It's a model-driven template in that the AWS infrastructure is instantiated according to its own specification of proper order of execution. It is not a procedural language. If you are writing a CloudFormation template, you only need to follow the rules of the CloudFormation external Domain Specific Language (DSL) in JSON notation. Editing templates is not difficult, but it is a process that could require some time (not to mention validation). Once you create a template updating it is not difficult but the initial creation particularly for new applications and environments can be a lot of upfront effort.

One feature of CFN that may make validation amd selection easier is [[1]].

Some tools to help us:

CFN Validation

"Two biggest things I've found that help with cfn:

commit often, diffs will save your life run them often with the CLI.

I run them every time I add a resource or change anything. If you're apprehensive about running your template because it creates a lot of costly resources, at least validate it with the CLI:

$ aws cloudformation validate-template --template-body file:////home//local//test//sampletemplate.json

CFN Editors

Loose notes from my class notes. Need to clean up.

AWS prefers Java Eclipse IDE using AWS Toolkit - (install instructions at see also AWS Explorer -

Would love a really RAD environment validation editor but that does not exist and is somewhat an anti-pattern in a cloud world.

CFN Visualization

Visualization of diagram from template

CFN Management


Lots of talk of using Yaml to create JSON.


"json is not a subset (although it's close), and the incompatibilities are infuriating when you encouter them. json libraries are generally faster... (…). yaml proponents will insist that it is a subset. if readability is a concern, use yaml. if interoperability and speed are a concern, use JSON."


Python programmers are generally big fans of YAML, because of the use of indentation, rather than bracketed syntax, to indicate levels. Many programmers consider the attachment of "meaning" to indentation a poor choice.

YAML is very human readable however JSON is natively supported.

JSON is not self documenting but can have comments.

Cumulus takes YAML input and creates Stacks from it.

$ AMID=ami-1q23123123 cumulus -y example_stack.yaml -a create

would be seen by cloudformation with the ami id of ami-1q23123123

"The problem:

Amazon CloudFormation (CF) allows you to instantiate multiple AWS resources in a repeatable, ordered and structured method. As our infrastructure grew, so did our CF templates and soon they were monolithic and complex to maintain. We looked at splitting these templates into smaller chunks, which worked as a short term solution but created a new problem. With multiple templates dependant on other declared resources, we were forced to manually pass parameters for inter-stack operability. This greatly affected the repeatability of our stacks as we did not have an easy method to keep track of what parameters were used, especially those relating to physical resource IDs.

The solution:

Cumulus attempts to solve the problem by introducing a layer above CF templates, a stack configuration YAML file. This allows multiple CF stacks to be created in order and maintained respecting their dependencies. The YAML file stores values for parameters to be passed into each of the stacks. Parameters can be assigned with static values or will source the value of a parameter, output or resource of another stack described in the YAML file. Cumulus actively translates reference values to physical resource values on creation of the stack."

CFN Descriptions

Look at JSON query tools like command line tool:

Can be used to look at specific parameters:

$ aws cloudformation describe-stack-resource --stack-name wordpress \
 --logical-resource-id DBInstance \
 | jq '.StackResourceDetail .PhysicalResourceId' \
 | xargs aws rds describe-db-instances --db-instance-identifier \
 | jq '.DBInstances[0] .Endpoint .Address'

Instead of the complete JSON response, we get exactly the piece of data we care about:

Describe Stack resources:

Ruby Rake

Rake job for installing updated Stacks. I have this code from lab. (Upload later?)

You need the AWS keys in your environment variable before running this:

(these are not real keys)

$ rake update_stack["$AMM_STACK_NAME","AppEC2InstanceType=m3.medium"]

If you see this error:

$ rake update_stack["$AMM_STACK_NAME","AppEC2InstanceType=m3.medium"]
rake aborted!
cannot load such file -- aws-sdk
/Users/kevin/Dropbox/AWS/Class/AWS_Advanced_Ops/amm/Rakefile:1:in `<top (required)>'
(See full trace by running task with --trace)

To fix:

Now install aws-sdk-v1 and modify the Rakefile to use aws-sdk-v1:

Installs v1 of the SDK (which uses AWS:: rather than v2 which uses Aws:: calls).

The V2 that's installed results in "uninitialized constant AWS" errors.

$ sudo gem install aws-sdk-v1

Edit Rakefile and change line:

require 'aws-sdk-v1'

CFN Parameterization


            "Description":"EC2 Instance Type to use. 32-bit or 64-bit.",

Misc Tools