• This repository has been archived on 03/Jan/2022
  • Stars
    star
    103
  • Rank 333,046 (Top 7 %)
  • Language
    Go
  • License
    BSD 2-Clause "Sim...
  • Created over 9 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A golang library for reading and producing CloudFormation templates

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.

More Repositories

1

saml

SAML library for go
Go
945
star
2

etcd-aws

tools for building a robust etcd cluster in AWS
Go
123
star
3

go-xmlsec

golang bindings for xmlsec
Go
25
star
4

rfc5424

a Go library that can read and write RFC-5424 syslog messages
Go
18
star
5

awsconsoleauth

Amazon AWS login with Google credentials
Go
13
star
6

dev

Infrastructure for building a development and collaboration environment with CoreOS and Docker.
Python
9
star
7

dynamotree

dynamotree is an implementation of hierarchical data storage for DynamoDB.
Go
8
star
8

redisproxy

Access control for Redis
Go
7
star
9

ec2cluster

Simple EC2 cluster auto-discovery for go
Go
7
star
10

ringfile

A library for writing and reading fixed size circular log files
C++
5
star
11

slackcat

like netcat but for Slack
Go
3
star
12

minichaos

A tiny version of ChaosMonkey for a single autoscaling group
Go
2
star
13

awsregion

tiny golang function to guess the correct aws region for use with aws-sdk-go
Go
2
star
14

standupbot

a super simple slack bot to run standups
Go
2
star
15

certcheck

Tools to check expiration and renew TLS certificates
Shell
2
star
16

cl

cl is a tool to make github pull requests less annoying
Go
2
star
17

s3repo

Tools for manipulating simple Debian repositories in S3
Python
2
star
18

jsupdate

a tool for keeping your `package.json` file updated without breaking everything
Go
2
star
19

csp

go library for generating Content-Security-Policy headers
Go
1
star
20

goupdate

goupdate is a tool for keeping your go.mod file updated without breaking everything.
Go
1
star
21

withebs

Withebs runs a command with the specified EBS volume attached to the currently running EC2 instance.
Go
1
star
22

etcd-amb

Ambassador for etcd
Go
1
star
23

dockerelb

attach docker containers to AWS Elastic Load Balancers
Go
1
star
24

usermgr

Usermgr is a tool to turn access to production systems from a pain in the butt into ponies and rainbows.
Go
1
star
25

reversehttp

reversehttp implements a simple scheme for reversing the request/response flow of HTTP in go
Go
1
star
26

httperr

A golang error object that speaks HTTP
Go
1
star