To create a GO app the see Chapter Simple programm.
Let`s look at the source in /lambda-go/simple-lambda-al2
1: package main
2:
3: import (
4: "context"
5: "fmt"
6: "github.com/aws/aws-lambda-go/lambda"
7: )
8:
9: type MyEvent struct {
10: Name string `json:"name"`
11: }
12:
13: func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
14: return fmt.Sprintf("Hiho %s!", name.Name), nil
15: }
16:
17: func main() {
18: lambda.Start(HandleRequest)
19: }
20:
1: package main
2:
3: import (
4: "context"
5: "fmt"
6: "github.com/aws/aws-lambda-go/lambda"
7: )
8:
9: type MyEvent struct {
10: Name string `json:"name"`
11: }
12:
13: func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
14: return fmt.Sprintf("Hiho %s!", name.Name), nil
15: }
16:
17: func main() {
18: lambda.Start(HandleRequest)
19: }
20:
In line 18 the main function calls the lambda handler. This function is imported in line 6 from “github.com/aws/aws-lambda-go/lambda”.
This handler, here in line 13 is then called with a context and a JSON event.
The input for HandleRequest is a context, from which we can get the lambdacontext. The context stores things like the FunctionName, the AwsRequestID and other things.
The input, which is the payload of the invocation has to be defined in a struct, here MyEvent in line 9.
If you invoke Lambda with an AWS event, all the events are defined in AWS Event definitions.
Working with own events, you define the struct.
So with:
9 type MyEvent struct {
10 Name string `json:"name"`
11 }
the input event could be:
{
"name": "megaproaktiv"
}
Download dependencies
In the directory with main go do:
go mod init simplelambda
go mod tidy
This downloads the dependencies.
Build
mkdir -p dist
env GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -tags lambda.norpc -ldflags="-s -w" -o ./dist/bootstrap main.go
change file execution permission
chmod +x ./dist/bootstrap
package the file in a zip
Lambda upload only accept zipped files, so zip it:
cd ./dist && zip bootstrap.zip bootstrap && cd ..
Output:
updating: bootstrap (deflated 59%)
Part | meaning |
---|---|
env GOOS=linux | build for linux operation system |
GOARCH=arm64 | build for arm. You need this e.g. if you are working with an intel mac, which is intel based |
go build | build call |
-ldflags="-s -w" | See go help build , omit the symbol table, debug information to get a smaller binary |
-o ./dist/bootstrap | ouput in directory “dist” (short for distribution), file bootstrap |
main.go | the go file to build |
You may need to compile packages with CGO_ENABLED=0 set on Linux.
The bootstrap
file ist the first file Lambda is calling. You will see the bootstrap
binary also in the Lambda web console.
With go you can build the binary for different operations systems (os). Without any GOOS/GOARCH GO will take the current os and architecture, so that the app runs on your machine.
With AWS Lambda, the GOOS is always linux. The GOARCH can be amd64 for intel or arm for Gravition.
We deploy the code directly from the AWS CLI with:
Deploy with AWS CLI
aws lambda update-function-code --function-name gosimple --zip-file fileb://./dist/bootstrap.zip
The name gosimple has to be exactly the name you set on the creation of the lambda function.
Output:
{
"FunctionName": "gosimple",
"FunctionArn": "arn:aws:lambda:eu-central-1:123456789012:function:gosimple",
"Runtime": "provided.al2",
"Role": "arn:aws:iam::123456789012:role/service-role/gosimple-role-s84ouowk",
"Handler": "main",
"CodeSize": 1950171,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2023-08-13T17:22:33.000+0000",
"CodeSha256": "04S8R+trBPigZXxquMTaYIs8kQK3lwqaZar+871UBkA=",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "5b3bbea4-5e10-4d76-b3ae-a79a2d14a5e7",
"State": "Active",
"LastUpdateStatus": "InProgress",
"LastUpdateStatusReason": "The function is being created.",
"LastUpdateStatusReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"arm64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:eu-central-1::runtime:904c897d14442788d50f990427bbbf4e8df27838f33ffdc86013c6c1389b2bd4"
}
}
The direct deployment has limits on the file size. Deploy from S3 or with Container images for larger files. See AWS Lambda limits for size limits.
If you prefer the console, you find the upload button in the “code” tab:
In the source code, there is a json file in testdata/event.json
.
We give the AWS CLI Lambda invoke call the payload event.json as input parameter. Because we use the fileb:
function, it does not have to be base64 encoded.
So this call invokes the lambda from the AWS CLI:
aws lambda invoke --function-name gosimple --payload fileb://testdata/event.json testdata/lambda.out
You get the output from the AWS Lambda invoke call as on output:
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
This is not the answer from the Lambda function, but the answer from the Lambda services, which tells you, that the invocation succeeded.
The output from the Lambda function is in `testdata/lambda.out``
cat testdata/lambda.out
"Hiho megaproaktiv!"%
In the source dir there ist the Taskfile.yml
.
The calls are included there, so you can:
Deploy
task deploy
For deploy i define a variable NAME, because the function name is often used in the task file. And you can also get this name from AWS Systems Manager Parameter Store or CloudFormation output.
1: vars:
2: NAME: gosimple
3:
4: deploy:
5: desc: Deploy only Lambda function
6: deps: [build]
7: cmds:
8: - aws lambda update-function-code --function-name gosimple --zip-file fileb://./dist/bootstrap.zip
This depends on the build task:
1: build:
2: desc: build go
3: cmds:
4: - mkdir -p dist
5: - env GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ./dist/bootstrap main.go
6: - chmod +x ./dist/main
7: - cd ./dist && zip bootstrap.zip bootstrap
Invoke
task invoke
The creation and deployment with the CDK, see the Chapter Lambda with CDK overview is much better suited for complex deployments. But as you have seen here, the setup for single functions is faster.
To create a go app: Chapter Simple programm
See the full source on github.