Skip to content

A golang library for reading and producing CloudFormation templates

License

Notifications You must be signed in to change notification settings

mweagle/go-cloudformation

This branch is 35 commits ahead of, 1 commit behind crewjam/go-cloudformation:master.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

0a35d7d · Oct 9, 2021
Jul 7, 2019
Jul 7, 2019
Jan 17, 2021
Nov 29, 2015
Apr 26, 2017
Feb 10, 2017
Oct 9, 2021
Nov 29, 2015
Sep 7, 2018
Nov 29, 2015
Mar 15, 2016
Dec 22, 2015
Oct 1, 2016
Jan 8, 2016
Jan 8, 2016
Jan 8, 2016
Jan 8, 2016
Jan 8, 2016
Jan 8, 2016
Jan 8, 2016
Jan 8, 2016
Jan 8, 2016
Oct 7, 2016
Oct 7, 2016
Jan 8, 2016
Jan 8, 2016
Nov 29, 2015
Nov 29, 2015
Apr 28, 2018
Jan 8, 2016
Nov 29, 2015
Nov 29, 2016
Nov 29, 2016
Jan 17, 2016
Sep 7, 2018
Jun 10, 2017
Jan 17, 2021
Jan 17, 2021
Jun 10, 2017
Jan 8, 2016
Mar 10, 2018
Aug 12, 2016
Sep 7, 2018
Nov 15, 2020
Jan 11, 2018

Repository files navigation

THIS REPO IS NO LONGER SUPPORTED

Please upgrade to goformation which has a larger community and is kept more current with Resource Definition releases.


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:

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

Producing Example:

t := NewTemplate()
t.Parameters["DnsName"] = &Parameter{
  Type: "string",
  Default: "example.com",
  Description: "the top level DNS name for the service"
}
t.AddResource("DataBucket", &S3Bucket{
  BucketName: Join("-", String("data"), Ref("DnsName"))
})
json.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.

type StringExpr struct {
  Func    StringFunc
  Literal string
}

// StringFunc is an interface provided by objects that represent
// CloudFormation functions that can return a string value.
type StringFunc interface {
  Func
  String() *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.

About

A golang library for reading and producing CloudFormation templates

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 100.0%