You can package your Lambda function code and dependencies as a container image, using tools such as the Docker CLI. You can then upload the image to your container registry hosted on Amazon Elastic Container Registry (Amazon ECR).

AWS provides a set of open-source base images that you can use to create your container image. These base images include a runtime interface client to manage the interaction between Lambda and your function code.

 

Setup Pre-requisites:

1. Install AWS CLI v1 or v2. The command to invoke lambda will be different based on which version of CLI is used. Follow this doc to install CLI V2 – https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html

Check AWS CLI version – aws –version

AWS CLI v1 then the version will be something like – aws-cli/1.18.69

AWS CLI v2 version will be like – aws-cli/2.4.16

2. Configure CLI with IAM user who can access the account and perform actions.

3. Install Docker on Linux or Docker-Desktop on Windows. For this article, I have used Docker-desktop on Windows.

4. Create a role for the lambda and note the ARN of Role which is returned-

aws iam create-role --role-name lambda-container-image-execution --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, 
    "Action": "sts:AssumeRole"}]
  }'

 

 

Create ‘Hello World’ function (NodeJS) :

1. Create a new directory-

mkdir -p lambda
cd lambda

 

2. Create an helloworld.js file in folder lambda-

exports.handler = async (event) => {
    const response = {
	    statusCode: 200,
		body: JSON.stringify('Hello World'),
	};
	return response;
};

 

3. Initialize the NodeJS project. This will create a package.json file-

npm init -f

 

package.json

{
  "name": "lambda",
  "version": "1.0.0",
  "description": "",
  "main": "helloworld.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

 

4. Create Dockerfile with below content and build the Docker image –

FROM amazon/aws-lambda-nodejs:14
COPY helloworld.js package.json ./
RUN npm install
CMD [ "helloworld.handler" ]

Now lambda folder will have three files – Dockerfile, helloworld.js, and package.json

Docker build command-

docker build -t helloworld .

 

5. This will download the Amazon-provided image amazon/aws-lambda-nodejs:14 and image will be created.

 

Test the Docker Image Locally:

1. Start the container using the image created-

docker run --rm -p 8080:8080 helloworld

 

2. Run the below command to invoke the lambda-

Using AWS CLI V2-

aws lambda invoke --region eu-west-1 --endpoint http://localhost:8080 --no-sign-request --function-name function --cli-binary-format raw-in-base64-out --payload '{"a":"b"}' output.txt

 

Using AWS CLI V1-

aws lambda invoke --region eu-west-1 --endpoint http://localhost:8080 --no-sign-request --function-name function
  --payload '{"a":"b"}' output.txt

 

Both commands should show output in output.txt file-

{"statusCode":200,"body":"\"Hello World\""}

 

NOTE: You may observe errors like – Invalid base64: “{“a”:”b”}” if the wrong version of aws cli is used.

Push Docker Image to AWS ECR-

1. Use the following command to log in to AWS ECR (change the region as required)-

docker login -u AWS -p $(aws ecr get-login-password --region eu-west-1) xxxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com

 

2. Add a new tag to the helloworld image to push it to AWS ECR (ensure that repository by name helloworld is already created in AWS ERC)-

docker tag helloworld:latest 706949302588.dkr.ecr.eu-west-1.amazonaws.com/helloworld:latest

docker push 706949302588.dkr.ecr.eu-west-1.amazonaws.com/helloworld:latest

 

Create Lambda function in AWS Lambda-

1. Now run this command to create the lambda function in your region. REPLACE the ARN of the Role and Image URI –

aws lambda create-function \
 --package-type Image \
 --function-name helloworld \
 --role arn:aws:iam::xxxxxxxxxx:role/lambda-container-image-execution \
 --code ImageUri=xxxxxxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/helloworld:latest

 

2. Run the below command to invoke the lambda-

Using AWS CLI V2-

aws lambda invoke --region eu-west-1 --function-name helloworld --cli-binary-format raw-in-base64-out --payload '{"a":"b"}' output.txt

 

Using AWS CLI V1-

aws lambda invoke --region eu-west-1 --function-name helloworld
  --payload '{"a":"b"}' output.txt

 

Both commands should show output in output.txt file-

{"statusCode":200,"body":"\"Hello World\""}

 

Reference:

https://aws.amazon.com/blogs/aws/new-for-aws-lambda-container-image-support/

https://docs.aws.amazon.com/lambda/latest/dg/images-create.html