Running/Testing AWS Lambda function locally in Golang

12th May, 2024 (49 days ago)
#aws#golang

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

Serverless Function Resource

Properties

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:

Terminal window
GOOS=linux CGO_ENABLED=0 go build -o bootstrap main.go

Invoking the function using SAM CLI:

Terminal window
sam local invoke

Output:

Terminal window
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