Building CloudFormation Custom Resources in Go

AWS LambdaRecently Amazon announced support for the Go programming language (also known as GoLang) in AWS Lambda. Go is unusual amongst modern languages (such as Java, C#, or JavaScript) because it isn’t interpreted or compiled into bytecode that runs within a container (like the .Net Runtime or Java Virtual Machine). Instead, Go compiles into executable machine code. This avoids the startup cost of Java and runs much faster than Python or Node.js. So, how do we go about Building CloudFormation Custom Resources in Go?

Building CloudFormation Custom Resources in Go

There are basically two phases:

  1. First we’ll install the Go based Lambda function, and then,
  2. We’ll upload and execute the CloudFormation template.

Since Custom Resources in CloudFormation is quite an advanced topic, some aspects of this tutorial will be very high level. In particular, creating Lambda functions in general, creating IAM roles, and working with CloudFormation.

Installing a Go based Lambda Function

Installing Go is quite simple. Navigate to https://golang.org/dl/ and follow the instructions there. By default, Go likes a directory called “go” in the home directory, (we’re all about taking the defaults), so create a directory in your home directory called “go”. Next, we need to install some additional packages:

Then, copy the Go program listed below into that directory:

The code consists of six main parts:

  1. Request struct. The Request struct represents the incoming request. Details of the format of this data can be found here. There’s a few parts missing from the Go structure because no parameters are passed in this simple example.
  2. Response struct. The Response struct represents the response from the Lambda function. Note that this response isn’t returned to the caller, but instead gets uploaded to Amazon Simple Storage Service (S3) at a location specified in the Request struct.
  3. Handler. The Handler function performs the work. It receives a Request struct as a parameter.
  4. doPut. The doPut function writes the Response struct to the S3 bucket.
  5. buildResponse. The buildResponse func creates a Response struct.
  6. main. The main func registers the Handler function for use with CloudFormation.

We need to compile the source code into an executable. If you’re running this on Linux, it’s easy to build the executable using go build -o main. On my Mac, I need to build a Linux executable. Go makes this really easy:

GOOS=linux go build -o main

Next, we need to create a ZIP file. The command on the Mac is:

zip -v deployment.zip main

Create a new role which should include the AWSLambdaBasicExecutionRole policy.

Finally, we need to upload the code into AWS Lambda. Use the following command and replace <arn> with the ARN identifier for the role just created, labelled “Role ARN”.

aws --region us-east-1 lambda create-function --function-name GoCloudFormationCustomResource --zip-file fileb://./deployment.zip --runtime go1.x --role <arn> --handler main

Upload and Execute the CloudFormation Template

The following YAML CloudFormation template is as simple as it gets:

The <acct> must be replaced with your account number.

Create a new (or reuse an existing) Amazon Simple Storage Service (S3) bucket and upload the CloudFormation template to it. Then, create the stack.

If everything worked as expected, the stack should complete successfully, and there should be an output called “Value” set to “Hello, from Go!”. Now, you know how to go about building CloudFormation Custom Resources in Go.

Share
3 comments
  1. Cool! Thanks 🙂 Will give this a try.

    To complete this do you need to implement ‘update’ and ‘delete’ for the custom resource – given it is stateless this doenst really do anything, but I assume cloudF needs a reponse written to the signed URL still?

    Also be nice to see some json request variable passed.

    Awesome thanks super useful!

  2. aws–region us-east-1 lambda create-function –function-name GoCloudFormationCustomResource –zip-file fileb://./deployment.zip –runtime go1.x –role –handler main

    this command is incomplete.

    • Good catch! There was a space missing in “aws–region” which I’ve now corrected. It should read “aws –region us-east-1 lambda create-function –function-name GoCloudFormationCustomResource –zip-file fileb://./deployment.zip –runtime go1.x –role –handler main”

Add Comment

Required fields are marked *. Your email address will not be published.