How To Run a Container Images on AWS Lambda
By: Münir Karslı
Tags: Ecr, Docker Image, AWS, AWS Lambda, Java

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,

Code in an arbitrary programming language. Use custom OS and custom runtime versions Deploy large files and packages (up to 10 GB) Reuse existing base images 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 init SAM 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.html Which 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]: lambda Cloning 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-image WORKDIR “/task” COPY src/ src/ COPY pom.xml ./ RUN mvn -q clean install RUN mvn dependency:copy-dependencies -DincludeScope=compile FROM public.ecr.aws/lambda/java:8 COPY — 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–31 Description: > lambda Sample SAM Template for lambda # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 20 Resources: HelloWorldFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: PackageType: Image Events: HelloWorld: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: Path: /hello Method: get Metadata: DockerTag: java8-maven-v1 DockerContext: ./HelloWorldFunction Dockerfile: Dockerfile Outputs: # 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#api HelloWorldApi: 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.Arn HelloWorldFunctionIamRole: 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.