Running/Testing AWS Lambda function locally in Golang
Running and testing AWS Lambda functions locally in Golang allows developers to catch bugs and issues early, ensuring smooth deployment. It involves setting up a local environment, writing the Lambda function.
AWS Lambda is a serverless computing service provided by Amazon Web Services (AWS). With AWS Lambda, you can run your code without provisioning or managing servers.
What exactly is Serverless Architecture?
Serverless architecture, also known as Function-as-a-Service (FaaS), is a cloud computing execution model where the cloud provider dynamically manages the allocation and provisioning of servers. In a serverless architecture, developers don’t have to worry about provisioning, scaling, or managing servers.
Why is it important to test AWS Lambda functions locally?
Testing AWS Lambda functions locally in Golang is crucial as it helps identify and resolve potential build or runtime mismatches between the local and cloud environments.
For example, when building a Golang Lambda function binary on a macOS machine with an Apple Silicon (ARM64) architecture, the resulting binary is compatible with the ARM64 instruction set. However, the AWS Lambda execution environment currently runs on Amazon Linux, which uses an x86-64 (AMD64) architecture.
If you attempt to upload and run the ARM64 binary built on your macOS machine directly on AWS Lambda, it will fail due to the architecture mismatch.
To resolve this issue, you would need to cross-compile the Golang code to produce an x86-64 binary compatible with the AWS Lambda execution environment. This can typically be done by setting the appropriate environment variables (e.g., GOOS=linux, GOARCH=amd64) before building the binary on your macOS machine.
Dependencies for running Lambda function locally
Defining configuration for running Lambda
AWS Lambda functions require a specific configuration to define how they should run and what resources they need. While you can provide this configuration through the AWS Management Console or AWS CLI, using a template file makes it easier to version control and manage your Lambda function’s configuration alongside your code.
Example:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Hello World Function
Resources:
lambdasftp:
Type: AWS::Serverless::Function
Properties:
CodeUri: .
Description: ''
MemorySize: 1024
Timeout: 3
Handler: main
Runtime: provided.al2023
CodeUri: .
Architectures:
- arm64
Template Overview
- AWSTemplateFormatVersion: Specifies the version of the CloudFormation template language.
- Transform: Indicates the use of AWS SAM capabilities to simplify serverless resource definitions.
- Description: Provides a brief description of the template’s purpose.
Serverless Function Resource
- Resources: Defines the AWS resources to be deployed.
- MyLambdaFunction: A serverless function named
MyLambdaFunction— in this case it islambdasftp.- Type: Specifies the resource type (
AWS::Serverless::Functionfor Lambda function).
- Type: Specifies the resource type (
- MyLambdaFunction: A serverless function named
Properties
- CodeUri: Path to the function code (
.indicates current directory). - Handler: Entry point for the function (
mainfunction). - Runtime: Custom runtime environment (
provided.al2023based on Amazon Linux 2). - MemorySize: Memory allocated to the function (1024 MB).
- Timeout: Maximum execution time for the function (3 seconds).
- Architectures: Supported architectures (ARM64).
Writing a lambda function in Go
package main
import (
"context"
"fmt"
"github.com/aws/aws-lambda-go/lambda"
)
func handler(ctx context.Context) {
fmt.Println("Hello World!")
}
func main() {
lambda.Start(handler)
}
Building the go function using:
GOOS=linux CGO_ENABLED=0 go build -o bootstrap main.go
- GOOS=linux: This is an environment variable that specifies the target operating system for the compiled binary. In this case, it’s set to linux, which means the resulting binary will be executable on Linux systems.
- CGO_ENABLED=0: This environment variable disables the use of CGO (C Go) when building the Go program. CGO allows Go code to call C code, but it can make the binary larger and more complex. Setting CGO_ENABLED=0 produces a pure Go binary without any external C dependencies.
- bootstrap: The name of the generated binary.
Invoking the function using SAM CLI:
sam local invoke
Output:
Invoking main (provided.al2023)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/provided:al2023-rapid-arm64.
Mounting /Users/randomsumit/dev/aws-lambda-go-example
as /var/task:ro,delegated, inside runtime container
START RequestId: 8e49ebaf-98b4-4ccd-be32-a4effc1b56db
Version: $LATEST
Hello World!
END RequestId: 56a83226-b92b-4a74-9a8e-6fa410b1afd1
REPORT RequestId: 56a83226-b92b-4a74-9a8e-6fa410b1afd1
Init Duration: 0.14 ms Duration: 13.67 ms
Billed Duration: 14 ms Memory Size: 1024 MB
Max Memory Used: 1024 MB
null
Thanks for reading the blog. Checkout code at Github.