Lambda container deployment

Lambda Container deploy

For using containers as an deployment option, these steps have to be performed, if you already have a Lambda resource with configured container image deployment:

  • Call Docker to build the app and create the container image locally
  • upload the image to ECR - the AWS container registry
  • deploy the ECR stored image to lambda

All these steps will be performed by the CDK, see the chapter walkthrough for details.

The CDK Construct

See infra/lambda-go-arm.go from the source.

	awslambda.NewDockerImageFunction(stack,
		aws.String("RegisterHandlerAmd"),
		&awslambda.DockerImageFunctionProps{
			Architecture:                 awslambda.Architecture_X86_64(),
			FunctionName:                 aws.String("hellodockerx86"),
			MemorySize:                   aws.Float64(1024),
			Timeout:                      awscdk.Duration_Seconds(aws.Float64(300)),
			Code:                         awslambda.DockerImageCode_FromImageAsset(&dockerfile, &awslambda.AssetImageCodeProps{}),
		})

The CDK supports the new Architecture type and the container deployment.

The architecture which Lambda runs in the configured here:

Architecture: awslambda.Architecture_X86_64(),

And the deployment type is just defined here:

Code:awslambda.DockerImageCode_FromImageAsset(&dockerfile, &awslambda.AssetImageCodeProps{}),

The Dockerfile

See appx86/Dockerfile from the source.

  1 FROM public.ecr.aws/lambda/provided:al2 AS build
  2 ENV CGO_ENABLED=0
  3 RUN mkdir -p /opt/extensions
  4 RUN yum -y install go
  5 RUN go env -w GOPROXY=direct
  6 ADD go.mod go.sum ./
  7 RUN go mod download
  8 COPY . ${LAMBDA_TASK_ROOT}
  9 RUN env GOOS=linux GOARCH=amd64 go build -o=/main
 10 # copy artifacts to a clean image
 11 FROM public.ecr.aws/lambda/provided:al2
 12 COPY --from=build /main /main
 13 ENTRYPOINT [ "/main" ]

AWS has its own public registry and provides Lambda images, which is pulled in line 1: This images is based on Amazon Linux 2.

1 FROM public.ecr.aws/lambda/provided:al2 AS build

On some linux system you need to disable C GO. On my MAC it was not needed.

  2 ENV CGO_ENABLED=0

Get rid of the extension warning.

  3 RUN mkdir -p /opt/extensions

Install GO for the build process.

  4 RUN yum -y install go

You could also build locally and copy the binary. Using Docker makes it more predictable and repeatable on different machines.


Control how GO downloads sources.

  5 RUN go env -w GOPROXY=direct

Only copy (add) the GO package files and download (get) all GO modules.

  6 ADD go.mod go.sum ./
  7 RUN go mod download

This copies “everything”, which now is only main.go for the build. The task root is the directory where Lambda runs code.

  8 COPY . ${LAMBDA_TASK_ROOT}

Build binary with linux as target system and amd64 as the architecture - because that is what Lambda runs on.

  9 RUN env GOOS=linux GOARCH=amd64 go build -o=/main

The GO installation is quite large. To keep the image small we do a fresh start

 10 # copy artifacts to a clean image
 11 FROM public.ecr.aws/lambda/provided:al2

Then we only copy the binary, that runs without external dependencies.

 12 COPY --from=build /main /main

This tells lambda, which programm to start in invokation

 13 ENTRYPOINT [ "/main" ]

Go to the next chapter to see Container deployment with arm architecture


See also

See the full source on github.

Sources