Skip to content

Commit

Permalink
Merge pull request #114 from PaulMaddox/master
Browse files Browse the repository at this point in the history
Support for CloudFormation intrinsic functions (Go->YAML/JSON)
  • Loading branch information
PaulMaddox committed Sep 14, 2018
2 parents 2920e03 + 6f2ce4d commit 90ef940
Show file tree
Hide file tree
Showing 316 changed files with 1,095 additions and 662 deletions.
107 changes: 57 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
[![Build Status](https://travis-ci.org/awslabs/goformation.svg?branch=0.1.0)](https://travis-ci.org/awslabs/goformation) [![GoDoc Reference](https://godoc.org/gopkg.in/awslabs/goformation.v1?status.svg)](http://godoc.org/github.com/awslabs/goformation) ![Apache-2.0](https://img.shields.io/badge/Licence-Apache%202.0-blue.svg)

`GoFormation` is a Go library for working with AWS CloudFormation / AWS Serverless Application Model (SAM) templates.
- [AWS GoFormation](#aws-goformation)
- [Main features](#main-features)
- [Installation](#installation)
- [Usage](#usage)
- [Marshalling CloudFormation/SAM described with Go structs, into YAML/JSON](#marshalling-cloudformationsam-described-with-go-structs-into-yamljson)
- [Unmarshalling CloudFormation YAML/JSON into Go structs](#unmarshalling-cloudformation-yamljson-into-go-structs)
- [Updating CloudFormation / SAM Resources in GoFormation](#updating-cloudformation-sam-resources-in-goformation)
- [Advanced](#advanced)
- [AWS CloudFormation Intrinsic Functions](#aws-cloudformation-intrinsic-functions)
- [Resolving References (Ref)](#resolving-references-ref)
- [Contributing](#contributing)
- [Main features](#main-features)
- [Installation](#installation)
- [Usage](#usage)
- [Marshalling CloudFormation/SAM described with Go structs, into YAML/JSON](#marshalling-cloudformationsam-described-with-go-structs-into-yamljson)
- [Unmarshalling CloudFormation YAML/JSON into Go structs](#unmarshalling-cloudformation-yamljson-into-go-structs)
- [Updating CloudFormation / SAM Resources in GoFormation](#updating-cloudformation--sam-resources-in-goformation)
- [Advanced](#advanced)
- [AWS CloudFormation Intrinsic Functions](#aws-cloudformation-intrinsic-functions)
- [Resolving References (Ref)](#resolving-references-ref)
- [Versioning](#versioning)
- [Contributing](#contributing)

## Main features

Expand Down Expand Up @@ -41,6 +41,8 @@ package main

import (
"fmt"
"strconv"
"time"

"github.com/awslabs/goformation/cloudformation"
)
Expand All @@ -50,31 +52,27 @@ func main() {
// Create a new CloudFormation template
template := cloudformation.NewTemplate()

// An an example SNS Topic
template.Resources["MySNSTopic"] = &cloudformation.AWSSNSTopic{
DisplayName: "test-sns-topic-display-name",
TopicName: "test-sns-topic-name",
Subscription: []cloudformation.AWSSNSTopic_Subscription{
cloudformation.AWSSNSTopic_Subscription{
Endpoint: "test-sns-topic-subscription-endpoint",
Protocol: "test-sns-topic-subscription-protocol",
},
},
// Create an Amazon SNS topic, with a unique name based off the current timestamp
template.Resources["MyTopic"] = &cloudformation.AWSSNSTopic{
TopicName: "my-topic-" + strconv.FormatInt(time.Now().Unix(), 10),
}

// ...and a Route 53 Hosted Zone too
template.Resources["MyRoute53HostedZone"] = &cloudformation.AWSRoute53HostedZone{
Name: "example.com",
// Create a subscription, connected to our topic, that forwards notifications to an email address
template.Resources["MyTopicSubscription"] = &cloudformation.AWSSNSSubscription{
TopicArn: cloudformation.Ref("MyTopic"),
Protocol: "email",
Endpoint: "some.email@example.com",
}

// Let's see the JSON
// Let's see the JSON AWS CloudFormation template
j, err := template.JSON()
if err != nil {
fmt.Printf("Failed to generate JSON: %s\n", err)
} else {
fmt.Printf("%s\n", string(j))
}

// and also the YAML AWS CloudFormation template
y, err := template.YAML()
if err != nil {
fmt.Printf("Failed to generate YAML: %s\n", err)
Expand All @@ -91,24 +89,21 @@ Would output the following JSON template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"MyRoute53HostedZone": {
"Type": "AWS::Route53::HostedZone",
"MyTopic": {
"Properties": {
"Name": "example.com"
}
"TopicName": "my-topic-1536878058"
},
"Type": "AWS::SNS::Topic"
},
"MySNSTopic": {
"Type": "AWS::SNS::Topic",
"MyTopicSubscription": {
"Properties": {
"DisplayName": "test-sns-topic-display-name",
"Subscription": [
{
"Endpoint": "test-sns-topic-subscription-endpoint",
"Protocol": "test-sns-topic-subscription-protocol"
}
],
"TopicName": "test-sns-topic-name"
}
"Endpoint": "some.email@example.com",
"Protocol": "email",
"TopicArn": {
"Ref": "MyTopic"
}
},
"Type": "AWS::SNS::Subscription"
}
}
}
Expand All @@ -119,20 +114,32 @@ Would output the following JSON template:
```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
MyRoute53HostedZone:
Type: AWS::Route53::HostedZone
MyTopic:
Properties:
Name: example.com
MySNSTopic:
TopicName: my-topic-1536878058
Type: AWS::SNS::Topic
MyTopicSubscription:
Properties:
DisplayName: test-sns-topic-display-name
Subscription:
- Endpoint: test-sns-topic-subscription-endpoint
Protocol: test-sns-topic-subscription-protocol
TopicName: test-sns-topic-name
Endpoint: some.email@example.com
Protocol: email
TopicArn:
Ref: MyTopic
Type: AWS::SNS::Subscription
```

When creating templates, you can use the following convenience functions to use [AWS CloudFormation Intrinsics](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html):

- `cloudformation.Ref(logicalName string)`
- `cloudformation.GetAtt(logicalName string, attribute string)`
- `cloudformation.ImportValue(name string)`
- `cloudformation.Base64(input string)`
- `cloudformation.CIDR(ipBlock, count, cidrBits string)`
- `cloudformation.FindInMap(mapName, topLevelKey, secondLevelKey string)`
- `cloudformation.GetAZs(region string)`
- `cloudformation.Join(delimiter string, values []string)`
- `cloudformation.Select(index string, list []string)`
- `cloudformation.Split(delimiter, source string)`
- `cloudformation.Sub(value string)`

### Unmarshalling CloudFormation YAML/JSON into Go structs

Expand Down Expand Up @@ -218,7 +225,7 @@ Any unsupported intrinsic functions will return `nil`.

#### Resolving References (Ref)

The intrinsic 'Ref' function as implemented will resolve all of the [pseudo parameters](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html) such as `AWS::AccountId` with their default value as listed on [the bottom of this page](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html).
When converting a YAML/JSON template to go, the intrinsic 'Ref' function as implemented will resolve all of the [pseudo parameters](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html) such as `AWS::AccountId` with their default value as listed on [the bottom of this page](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html).

If a reference is not a pseudo parameter, GoFormation will try to resolve it within the AWS CloudFormation template. **Currently, this implementation only searches for `Parameters` with a name that matches the ref, and returns the `Default` if it has one.**

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-amazonmq-broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ func (r *AWSAmazonMQBroker) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSAmazonMQBroker) MarshalJSON() ([]byte, error) {
func (r AWSAmazonMQBroker) MarshalJSON() ([]byte, error) {
type Properties AWSAmazonMQBroker
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-amazonmq-configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ func (r *AWSAmazonMQConfiguration) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSAmazonMQConfiguration) MarshalJSON() ([]byte, error) {
func (r AWSAmazonMQConfiguration) MarshalJSON() ([]byte, error) {
type Properties AWSAmazonMQConfiguration
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-account.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ func (r *AWSApiGatewayAccount) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayAccount) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayAccount) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayAccount
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-apikey.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ func (r *AWSApiGatewayApiKey) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayApiKey) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayApiKey) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayApiKey
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-authorizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ func (r *AWSApiGatewayAuthorizer) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayAuthorizer) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayAuthorizer) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayAuthorizer
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-basepathmapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ func (r *AWSApiGatewayBasePathMapping) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayBasePathMapping) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayBasePathMapping) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayBasePathMapping
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-clientcertificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ func (r *AWSApiGatewayClientCertificate) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayClientCertificate) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayClientCertificate) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayClientCertificate
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ func (r *AWSApiGatewayDeployment) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayDeployment) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayDeployment) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayDeployment
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-documentationpart.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ func (r *AWSApiGatewayDocumentationPart) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayDocumentationPart) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayDocumentationPart) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayDocumentationPart
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-documentationversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ func (r *AWSApiGatewayDocumentationVersion) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayDocumentationVersion) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayDocumentationVersion) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayDocumentationVersion
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-domainname.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ func (r *AWSApiGatewayDomainName) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayDomainName) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayDomainName) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayDomainName
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-gatewayresponse.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ func (r *AWSApiGatewayGatewayResponse) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayGatewayResponse) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayGatewayResponse) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayGatewayResponse
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
4 changes: 2 additions & 2 deletions cloudformation/aws-apigateway-method.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ func (r *AWSApiGatewayMethod) AWSCloudFormationType() string {

// MarshalJSON is a custom JSON marshalling hook that embeds this object into
// an AWS CloudFormation JSON resource's 'Properties' field and adds a 'Type'.
func (r *AWSApiGatewayMethod) MarshalJSON() ([]byte, error) {
func (r AWSApiGatewayMethod) MarshalJSON() ([]byte, error) {
type Properties AWSApiGatewayMethod
return json.Marshal(&struct {
Type string
Properties Properties
}{
Type: r.AWSCloudFormationType(),
Properties: (Properties)(*r),
Properties: (Properties)(r),
})
}

Expand Down
Loading

0 comments on commit 90ef940

Please sign in to comment.