Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for CloudFormation intrinsic functions (Go->YAML/JSON) #114

Merged
merged 13 commits into from
Sep 14, 2018
Merged

Support for CloudFormation intrinsic functions (Go->YAML/JSON) #114

merged 13 commits into from
Sep 14, 2018

Conversation

PaulMaddox
Copy link
Contributor

@PaulMaddox PaulMaddox commented Sep 12, 2018

An alternative (to #103) implementation of CloudFormation references (!Ref).

It works by adding a few simple methods in the cloudformation package for inserting intrinsic functions, such as !Ref and !GetAtt. For example:

// Ref creates a CloudFormation Reference to another resource in the template
func Ref(logicalName string) string {
	i := `{ "Ref": "` + logicalName + `" }`
	return base64.StdEncoding.EncodeToString([]byte(i))
}

The following list of functions are available to use when creating templates:

  • 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)

Example usage:

template := &cloudformation.Template{
	Resources: map[string]interface{}{
		"TestBucket": cloudformation.AWSS3Bucket{
			BucketName: "test-bucket",
		},
		"TestBucketPolicy": cloudformation.AWSS3BucketPolicy{
			Bucket: cloudformation.Ref("TestBucket"),
		},
	},
}

There is then a post-processor that replaces the any intrinsics represented as b64 strings, with a proper object, just before the template is marshalled to JSON or YAML.

Pros:

  • No breaking API changes
  • Nested intrinsics are supported
  • Simpler API - consumers don't need to use cloudformation.NewString() and cloudformation.NewInteger() for every property
  • Simpler overall implementation?

Cons:

  • Intrinsic functions can only be placed in String fields, not Number fields

Fixes #12, #68, #90, #81, #31

@errordeveloper
Copy link

errordeveloper commented Sep 13, 2018

@PaulMaddox thanks for looking into this, I think it's definitely worse exploring!

I do see two additional limitations:

  • nested intrinsics, few typical examples:
    • {"Fn::ImportValue": {"Fn::Sub": "${NetworkStackNameParameter}-SecurityGroupID"}}
    • {"Fn::Base64": {"Fn::Join": ["", ["something=", {"Ref": "Something"}]]}}
  • parsing a template into a Go struct

Both of the above are actually important for eksctl use-case.

@PaulMaddox
Copy link
Contributor Author

Parsing a template with intrinsics (inc. nested) into a Go struct will work. This should work already.

Nesting intrinsics should work when going from Go->YAML too (I'll add a test case for this).

@PaulMaddox PaulMaddox changed the title POC: Support for CloudFormation references POC: Support for CloudFormation intrinsic functions when doing Go->YAML/JSON Sep 13, 2018
@PaulMaddox PaulMaddox changed the title POC: Support for CloudFormation intrinsic functions when doing Go->YAML/JSON Support for CloudFormation intrinsic functions for Go->YAML/JSON Sep 13, 2018
@PaulMaddox PaulMaddox changed the title Support for CloudFormation intrinsic functions for Go->YAML/JSON Support for CloudFormation intrinsic functions (Go->YAML/JSON) Sep 13, 2018
@PaulMaddox PaulMaddox merged commit 90ef940 into awslabs:master Sep 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants