AWS Lambda is a well known and great cloud Function as a Service (FaaS). And Google’s GoLang is a statically typed, compiled programming language. It is widely popular for it is being super fast and it’s built-in concurrency.
In this blog post, we will discuss how we can use GoLang in the AWS Lambda function. In this demonstration, I’m using Go1.15. Following things are assumed:
- You know how to setup GoLang for development in Unix systems
- You are familiar with AWS Lambda
As Go is a compiled language, we cannot use the Lambda Function’s editor to edit the GoLang source code which we can do it in the case of scripting languages like Python, NodeJS, etc. In the case of Go, we will build the main function’s (the main function starts the lambda handler) file (cmd/main.go) which will create a compiled executable that is to be deployed to AWS Lambda. Let’s see step by step how a GoLang function can be created and deployed to AWS Lambda. We will use the following project structure in this demo, but you can use any structure at your convenience.
lambda-function-in-golang/ cmd/ main.go main_test.go ... deploy/ ... scripts/ ... go.mod go.sum
Lambda Handler
Let’s look at how
cmd/main.go look like:
package main import ( "fmt" "github.com/aws/aws-lambda-go/lambda" ) type LambdaEvent struct { Name string `json:"name"` Age int `json:"age"` } type LambdaResponse struct { Message string `json:"message"` } func LambdaHandler(event LambdaEvent) (LambdaResponse, error) { return LambdaResponse { Message: fmt.Sprintf("%s is %d years old.", event.Name, event.Age), }, nil } func main () { lambda.Start(LambdaHandler) }
github.com/aws/aws-lambda-go/lambda
is the AWS SDK for GoLang. LambdaEvent
is used to store the event and this is a custom event. Instead of using this custom event, different AWS service specific events can be used. For AWS service specific events, github.com/aws/aws-lambda-go/events
this package can be used. LambdaResponse
is used to store the response to be returned.
Some rules regarding the Lambda Handler are as follows:
- The Handler must be a function.
- The handler may take 0 to 2 arguments.
- If there is only one argument, it can be the context. Context, or an event from
github.com/aws/aws-lambda-go/events
this package or any custom event. - If there are 2 arguments used, the first one must be
context.Context
. - The handler may return 0 to 2 value.
- If there is only one value, it must implement
error
. - If there are 2 return values, the second value must implement
error
.
Valid Lambda Handler function signature:
- func ()
- func () error
- func () (TOut, error)
- func (TIn), error
- func (context.Context) error
- func (TIn) (TOut, error)
- func (context.Context) (TOut, error)
- func (context.Context, TIn) error
- func (context.Context, TIn) (TOut, error)
Here, TIn
and TOut
represent the event and response respectively.
NOTE: Global variables that are independent of your Lambda function’s handler code can be declared and modified. The handler may declare an init
a function that is executed when your handler is loaded.
Create Compiled Executable And Prepare It For AWS Lambda
- To build the executable, run the following command in the project root directory.
GOOS=linux go build cmd/main.go
GOOS=linux
will ensure that the compiled executable is Linux environment compatible, even if it is built/compiled in a non-Linux environment. This command will create a compiled executable named main in the project root directory.
- Zip the compiled executable main.
zip function.zip main
Create The Function
- Create the lambda function using the following command.
aws lambda --profile craftsmen --region us-east-2 create-function --function-name lambda-go --runtime go1.x --zip-file fileb://function.zip --handler main --role arn:aws:iam::{account-id}:role/service-role/basic_lambda_execution
Replace {account-id}
in the above command with your actual account id. You can use your own role ARN too.
Test The Function
- Configure test event as follows
{ "name": "Rayhan", "age": 25 }
- Test the function. This will give { “message”: “Rayhan is 25 years old.” } as a response.
Lambda Layers
You may wonder that external package(s) (AWS GoLang SDK) has been used, but there are no Lambda Layers for the external packages. Actually, when the application is compiled, the compiled executable includes all the external packages used. To get benefit from the AWS Lambda Layer, GoLang Plugins can be used. Golang Plugins is the feature released in the Go1.8. It allows you to dynamically load shared libraries (.so
files). It gives you an opportunity to export some of your code to a separate library or use the plugin prepared and compiled by someone else.
The full project source code along with the Terraform configuration can be found HERE.