Introduction#
GitHub this note shows
- Build executable on Amazon Linux 2023 then deploy
- Buindling in CDK
- CDK golang lambda alpha
Build Executable#
For Amazon Linux 2023 local and runtime on x86_64, let build an executable file
GOOS=linux GOARCH=amd64 go build -tags lambda.norpc -o bootstrap main.go
Then deploy it using zip or CDK stack. Please pay attention to naming convetion for handler, and the executable named bootstrap should be in lambda directory. Since local machine is Amazon Linux 2023, then run time should be the same.
export class LambdaDemoStack extends cdk.Stack {constructor(scope: Construct, id: string, props: cdk.StackProps) {super(scope, id, props)new cdk.aws_lambda.Function(this, 'LambdaGoDemo', {functionName: 'LambdaGoDemo',handler: 'bootstrap',code: cdk.aws_lambda.Code.fromAsset(path.join(__dirname, './../lambda/')),memorySize: 521,timeout: cdk.Duration.seconds(15),runtime: cdk.aws_lambda.Runtime.PROVIDED_AL2023,architecture: Architecture.X86_64})}}
Lambda logic
package mainimport ("context""fmt""github.com/aws/aws-lambda-go/lambda")type MyEvent struct {Name string `json:"name"`}func HandleRequest(ctx context.Context, event *MyEvent) (*string, error) {if event == nil {return nil, fmt.Errorf("received nil event")}message := fmt.Sprintf("Hello %s!", event.Name)return &message, nil}func main() {lambda.Start(HandleRequest)}
ECR Image#
Let create a stack
new cdk.aws_lambda.Function(this, 'LambdaGoEcr', {functionName: 'LamdbaGoEcr',code: cdk.aws_lambda.EcrImageCode.fromAssetImage(path.join(__dirname, './../lambda')),memorySize: 521,timeout: cdk.Duration.seconds(15),runtime: cdk.aws_lambda.Runtime.FROM_IMAGE,handler: cdk.aws_lambda.Handler.FROM_IMAGE,architecture: Architecture.X86_64})
Dockerfile
FROM golang:1.21.5 as buildWORKDIR /helloworld# Copy dependencies listCOPY go.mod go.sum ./# Build with optional lambda.norpc tagCOPY main.go .RUN go build -tags lambda.norpc -o main main.go# Copy artifacts to a clean imageFROM public.ecr.aws/lambda/provided:al2023COPY --from=build /helloworld/main ./mainENTRYPOINT [ "./main" ]
Lambda logic
package mainimport ("context""github.com/aws/aws-lambda-go/events""github.com/aws/aws-lambda-go/lambda")func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {response := events.APIGatewayProxyResponse{StatusCode: 200,Body: "\"Hello from Lambda!\"",}return response, nil}func main() {lambda.Start(handler)}
CDK Bundling#
Let create a lambda stack with bundling which means CDK will use an Docker image to bundle the go application
new cdk.aws_lambda.Function(this, 'LambdaGoBundling', {functionName: 'LambdaGoBundling',handler: 'bootstrap',code: cdk.aws_lambda.Code.fromAsset(path.join(__dirname, './../lambda/'), {bundling: {// image: cdk.aws_lambda.Runtime.PROVIDED_AL2023.bundlingImage,image: cdk.DockerImage.fromRegistry('golang:1.21.5'),command: ['bash','-c','GOCACHE=/tmp go mod tidy && GOCACHE=/tmp GOOS=linux GOARCH=amd64 go build -tags lambda.norpc -o /asset-output/bootstrap']}}),memorySize: 512,timeout: cdk.Duration.seconds(15),runtime: cdk.aws_lambda.Runtime.PROVIDED_AL2023,architecture: Architecture.X86_64})
Full lambda stack here
lambda-golang-stack.ts
import * as cdk from 'aws-cdk-lib'import { Architecture } from 'aws-cdk-lib/aws-lambda'import { Construct } from 'constructs'import * as path from 'path'export class LambdaDemoStack extends cdk.Stack {constructor(scope: Construct, id: string, props: cdk.StackProps) {super(scope, id, props)// deploy bin executablenew cdk.aws_lambda.Function(this, 'LambdaGoDemo', {functionName: 'LambdaGoDemo',handler: 'bootstrap',code: cdk.aws_lambda.Code.fromAsset(path.join(__dirname, './../lambda/')),memorySize: 521,timeout: cdk.Duration.seconds(15),runtime: cdk.aws_lambda.Runtime.PROVIDED_AL2023,architecture: Architecture.X86_64})// deploy via ecrnew cdk.aws_lambda.Function(this, 'LambdaGoEcr', {functionName: 'LamdbaGoEcr',code: cdk.aws_lambda.EcrImageCode.fromAssetImage(path.join(__dirname, './../lambda')),memorySize: 521,timeout: cdk.Duration.seconds(15),runtime: cdk.aws_lambda.Runtime.FROM_IMAGE,handler: cdk.aws_lambda.Handler.FROM_IMAGE,architecture: Architecture.X86_64})// cdk local bundlingnew cdk.aws_lambda.Function(this, 'LambdaGoBundling', {functionName: 'LambdaGoBundling',handler: 'bootstrap',code: cdk.aws_lambda.Code.fromAsset(path.join(__dirname, './../lambda/'),{bundling: {// image: cdk.aws_lambda.Runtime.PROVIDED_AL2023.bundlingImage,image: cdk.DockerImage.fromRegistry('golang:1.21.5'),command: ['bash','-c','GOCACHE=/tmp go mod tidy && GOCACHE=/tmp GOOS=linux GOARCH=amd64 go build -tags lambda.norpc -o /asset-output/bootstrap']}}),memorySize: 512,timeout: cdk.Duration.seconds(15),runtime: cdk.aws_lambda.Runtime.PROVIDED_AL2023,architecture: Architecture.X86_64})}}
And the main.go
main.go
package mainimport ("context""github.com/aws/aws-lambda-go/events""github.com/aws/aws-lambda-go/lambda")func handler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {response := events.APIGatewayProxyResponse{StatusCode: 200,Body: "\"Hello from Lambda!\"",}return response, nil}func main() {lambda.Start(handler)}