How To Run a Container Images on AWS Lambda

Münir Karslı
5 min readDec 12, 2020

12 days ago lambda would provide deployment option that supports a zip archive of application code or binaries to developer but now we can deploy container images. This means that you can deploy a custom Docker or OCI image as an AWS Lambda function.

There are 2 ways for deploying images. One of them is using AWS image options with pre-installed runtimes. These base images will be patched and maintained by AWS. Currently, the runtimes supported include dotnetcore2.1, dotnetcore3.1, go1.x, java8, java8.al2, java11, nodejs12.x, nodejs10.x, python3.8, python3.7, python3.6, python2.7, ruby2.5, ruby2.7, provided.al2, and provided. Developers can also provide their own images based on Linux kernels. That means you can run any program that can be containerized on Lambda.

With the microservice and serverless architectures, development teams can choose their own programming language but now every developer can choose their own language and more. Because now we have these features,

  1. Code in an arbitrary programming language.
  2. Use custom OS and custom runtime versions
  3. Deploy large files and packages (up to 10 GB)
  4. Reuse existing base images
  5. Apply centralized container image building and packaging governance and security requirements

Let’s Try

I will use AWS SAM CLI for creating my lambda function and deploying it.

Create project

We can create our program with following commands

$ sam initSAM CLI now collects telemetry to better understand customer needs.You can OPT OUT and disable telemetry collection by setting the
environment variable SAM_CLI_TELEMETRY=0 in your shell.
Thanks for your help!
Learn More: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-telemetry.htmlWhich template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
What package type would you like to use?
1 - Zip (artifact is a zip uploaded to S3)
2 - Image (artifact is an image uploaded to an ECR image repository)
Package type: 2
Which base image would you like to use?
1 - amazon/nodejs12.x-base
2 - amazon/nodejs10.x-base
3 - amazon/python3.8-base
4 - amazon/python3.7-base
5 - amazon/python3.6-base
6 - amazon/python2.7-base
7 - amazon/ruby2.7-base
8 - amazon/ruby2.5-base
9 - amazon/go1.x-base
10 - amazon/java11-base
11 - amazon/java8.al2-base
12 - amazon/java8-base
13 - amazon/dotnetcore3.1-base
14 - amazon/dotnetcore2.1-base
Base image: 12
Which dependency manager would you like to use?
1 - maven
2 - gradle
Dependency manager: 1
Project name [sam-app]: lambdaCloning app templates from https://github.com/aws/aws-sam-cli-app-templates-----------------------
Generating application:
-----------------------
Name: lambda
Base Image: amazon/java8-base
Dependency Manager: maven
Output Directory: .
Next steps can be found in the README file at ./lambda/README.md

SAM CLI asks us some questions likewise its name, region for aws services, base image template and so on. After this initialization, some important file was created by the sam.

Dockerfile

The base image of Dockerfile is specified as an image provided by AWS.

FROM amd64/maven as build-imageWORKDIR “/task”COPY src/ src/COPY pom.xml ./RUN mvn -q clean installRUN mvn dependency:copy-dependencies -DincludeScope=compileFROM public.ecr.aws/lambda/java:8COPY — from=build-image /task/target/classes /var/task/COPY — from=build-image /task/target/dependency /var/task/lib# Command can be overwritten by providing a different command in the template directly.CMD [“helloworld.App::handleRequest”]

template.yaml

It contains some configs about our lambda functions.

In order to package with a container image, PackageType: Image must be specified.
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-packagetype

AWSTemplateFormatVersion: ‘2010–09–09’Transform: AWS::Serverless-2016–10–31Description: >lambdaSample SAM Template for lambda# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rstGlobals:Function:Timeout: 20Resources:HelloWorldFunction:Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunctionProperties:PackageType: ImageEvents:HelloWorld:Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#apiProperties:Path: /helloMethod: getMetadata:DockerTag: java8-maven-v1DockerContext: ./HelloWorldFunctionDockerfile: DockerfileOutputs:# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function# Find out more about other implicit resources you can reference within SAM# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#apiHelloWorldApi:Description: “API Gateway endpoint URL for Prod stage for Hello World function”Value: !Sub “https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"HelloWorldFunction:Description: “Hello World Lambda Function ARN”Value: !GetAtt HelloWorldFunction.ArnHelloWorldFunctionIamRole:Description: “Implicit IAM Role created for Hello World function”Value: !GetAtt HelloWorldFunctionRole.Arn

Build

We will use sam build command for build the container image. After build the image you can see it with $ docker image ls command.

Test

First we try to test on our local machine with 2 methods. One of them is running container with docker and the second one is sam local invoke method.

For test with docker try the following command

docker run -d -p 9000:8080 helloworldfunction:java8-maven-v1

For test with sam run the following command

sam local invoke

Deploy

In the last stage of our project. A repository must be created in advance to push the container image, but you can leave the image pushing to the SAM CLI!

First create the ecr repo and deploy your image to that repo.

$ aws ecr create-repository --repository-name lambda-container-test --profile personal$ sam deploy --guided --profile personal

The required resources will be created by the sam.

And now you can test your application on the aws lambda service.

Summary

To sum up, there are some stages for run container on aws lambda.

  1. Prepare a container
  2. Build the container image and publish it to Amazon Elastic Container Registry (ECR).
  3. Deploy an AWS Lambda, grant it access to the ECR, and point it to the container image.

--

--