Important
As of July 2023 Amazon Web Services has deprecated the go1.x
runtime and recommends users to switch to the provided.al2
runtime. This project is less relevant as a result, but can still aid in error reporting.
More easily run Golang ARM (arm64
) binaries as Lambda functions.
This project is an overwrought shell one-liner that solves the very specific problem of normalizing the specification, in CloudFormation or otherwise, of Golang AWS Lambda functions that use the arm64
(Graviton2) architecture.
- Lambda does not directly support (as of December 2022) the combination of the
go1.x
runtime and thearm64
architecture. - Using the AWS Graviton2 processor for Lambda workloads potentially saves double-digit percentages on Lambda costs and has a positive performace impact.
- Go is a special case in that it is compiled and contains both the function code and runtime in a single executable. See more below under Prerequisites.
- Hacking around the issue repeatedly is annoying.
A bootstrap
script is provided as a Lambda layer to make use of the Lambda's specified handler. When included in deployed Lambda functions this layer provides the "runtime" for the Go binary and does some basic error checking before executing the script. This ensures:
- You can specify a "handler" like you would for
x86_64
(Intel) Golang binaries. - Clear error logs are emitted when the handler is an invalid path.
That's basically it.
To make use of this project the following must be true for your Lambda deployments:
- Your Lambda must use the
arm64
architecture and theprovided.al2
runtime (only Amazon Linux 2 supports thearm64
architecture). - Your Lambda function must include the provided Lambda layer.
- The Golang executable must use the
aws-lambda-go
module.
There are two methods of installation:
-
Use the pre-packaged layer content from my
ary.pub-lambda-community
S3 bucket. This is the default in the provided CloudFormation stack template.aws cloudformation deploy --template-file runtime/layer.yaml --stack-name go-arm-runtime
-
Host the layer content yourself by overriding the
ContentS3Bucket
andContentS3Key
parameters in the layer stack template when deploying into your AWS account(s).aws cloudformation deploy \ --template-file runtime/layer.yaml --stack-name go-arm-runtime \ --parameter-overrides 'ContentS3Bucket=my-s3-bucket,ContentS3Key=my/path/layer-content.zip'
Once installed the Lambda layer ARN is availalble as the <stack-name>:runtime-layer-arn
output.
Using the Lambda layer enables the architecture to be specified as arm64
and the handler to be the name of your Go binary. The runtime must be set to provided.al2
. This can be done via the command line, AWS Console, CloudFormation, or any other tool of your choice.
When specifying these values in a CloudFormation template it looks something like:
Type: AWS::Lambda::Function
Properties:
Architectures:
- arm64
Code:
S3Bucket: !Ref CodeS3Bucket
S3Key: !Ref CodeS3Key
Handler: example-func
Layers:
- !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:golang-arm-runtime:1"
MemorySize: 128
PackageType: Zip
Role: ...
Runtime: provided.al2
Timeout: 15
See the example-function
folder for a simple Golang function and CloudFormation template.
- Making your Go workloads up to 20% faster with Go 1.18 and AWS Graviton
- AWS Lambda Functions Powered by AWS Graviton2 Processor
- Go on Graviton
- Migrating AWS Lambda functions to Arm-based AWS Graviton2 processors
- cgo for ARM64 Lambda Functions
- Deploying Golang Lambdas on ARM with AWS Serverless Application Model (SAM)