Clever/go-cloudformation

Name: go-cloudformation

Owner: Clever

Description: A golang library for reading and producing CloudFormation templates

Created: 2016-03-14 22:09:13.0

Updated: 2016-03-14 22:09:15.0

Pushed: 2018-03-08 23:58:40.0

Homepage:

Size: 2371

Language: Go

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Build Status

This package provides a schema and related functions that allow you to parse and serialize CloudFormation templates in golang. The package places an emphasis on type-safety so that the templates it produces are (slightly) more likely to be correct, and maybe you can avoid endless cycles of UPDATE_ROLLBACK_IN_PROGRESS.

Parsing example:

 Template{}
.NewDecoder(os.Stdin).Decode(&t)
Printf("DNS name: %s\n", t.Parameters["DnsName"].Default) 

Producing Example:

 NewTemplate()
rameters["DnsName"] = &Parameter{
pe: "string",
fault: "example.com",
scription: "the top level DNS name for the service"

dResource("DataBucket", &S3Bucket{
cketName: Join("-", String("data"), Ref("DnsName"))

.NewEncoder(os.Stdout).Encoder(t)

See the examples directory for a more complete example of producing a cloudformation template from code.

Producing the Schema

As far as I can tell, AWS do not produce a structured document that describes the CloudFormation schema. The names and types for the various resources and objects are derived from scraping their HTML documentation (see scraper/). It is mostly, but not entirely, complete. I've noticed several inconsistencies in the documentation which suggests that it is constructed by hand. If you run into problems, please submit a bug (or better yet, a pull request).

Object Types

Top level objects in CloudFormation are called resources. They have names like AWS::S3::Bucket and appear as values in the “Resources” mapping. We remove the punctuation and redundant words from the name to derive a golang structure name like S3Bucket.

There are other non-resource structs that are refered to by resources or other non-resource structs. These objects have names with spaces in them, like “Amazon S3 Versioning Configuration”. To derive a golang type name the non-letter characters and redundant words are removed to get S3VersioningConfiguration.

Type System

CloudFormation uses three scalar types: string, int and bool. When they appear as properties we represent them as *StringExpr, *IntegerExpr, and *BoolExpr respectively.

 StringExpr struct {
nc    StringFunc
teral string


tringFunc is an interface provided by objects that represent 
loudFormation functions that can return a string value.
 StringFunc interface {
nc
ring() *StringExpr

These types reflect that fact that a scalar type could be a literal value ("us-east-1") or a JSON dictionary representing a “function call” ({"Ref": "AWS::Region"}).

Another vagary of the CloudFormation language is that in cases where a list of objects is expected, a single object can provided. For example, AutoScalingLaunchConfiguration has a property BlockDeviceMappings which is a list of AutoScalingBlockDeviceMapping. Valid CloudFormation documents can specify a single AutoScalingBlockDeviceMapping rather than a list. To model this, we use a custom type AutoScalingBlockDeviceMappingList which is just a []AutoScalingBlockDeviceMapping with extra functions attached so that a single items an be unserialized. JSON produced by this package will always be in the list-of-objects form, rather than the single object form.

Known Issues

The cloudformation.String("foo") is cumbersome for scalar literals. On balance, I think it is the best way to handle the vagaries of the CloudFormation syntax, but that doesn't make it less kludgy. A similar approach is taken by aws-sdk-go (and is similarly cumbersome).

There are some types that are not parsed fully and appear as interface{}.

I worked through public template files I could find, making sure the library could accurately serialize and unserialize them. In this process I discovered some of the idiosyncracies described. This package works for our purposes, but I wouldn't be surprised if there are more idiosyncracies hidden in parts of CloudFormation we are not using.

Feedback, bug reports and pull requests are gratefully accepted.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.