How to Deploy a Docker Image as an AWS Lambda Function

Hemanta Sundaray

Published November 6, 2023


Learn how to upload your local Docker image to Amazon ECR and create a lambda function using AWS CLI.

Prerequisites

If you don’t have AWS CLI installed, then follow the instructions at the link: Install or update the latest version of the AWS CLI.

Step-1: Authenticate Local Docker CLI to Amazon ECR

The first step is to authenticate your Docker CLI to your Amazon ECR (Elastic Container Registry). Amazon ECR is a fully managed Docker container registry that makes it easy for you to store, manage and deploy Docker container images.

Run the following command:

aws ecr get-login-password --region <YOUR_AWS_REGION> | docker login --username AWS --password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com

Replace the following placeholders with your specific values:

This command is a combination of two commands connected by a pipe (|). The aws ecr get-login-password --region <AWS_REGION> command retrieves an authentication token that the docker login --username AWS --password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com command then uses to authenticate your local Docker CLI with Amazon ECR.

After running the command, you’ll see an output similar to the following:

Authenticate Local Docker CLI to Amazon ECR

Now you’re authenticated to push and pull images from your Amazon ECR repository.

Step-2: Create an ECR Repository

Now you create an Amazon ECR repository to host your Docker images.

Run the following command:

aws ecr create-repository --repository-name <REPO_NAME> --region <AWS_REGION> --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE

Replace the placeholders with your specific values:

Note that the --image-scanning-configuration scanOnPush=true flag enables automatic scanning of the pushed image to detect software vulnerabilities. And the --image-tag-mutability MUTABLE flag provides you the ability to re-use tags, so you can push new image versions with the same tag.

This is sometimes useful during development when you're iterating quickly, but it can be risky in production environments because you could accidentally overwrite a tag that's being used by running instances.

After running the command, you’ll see an output similar to the following:

Create an ECR repository

Copy the repositoryUri value; you’ll need it in the next step.

Step - 3: Tag Your Docker Image

Next, you tag your local Docker image to associate it with the ECR repository (created in the previous step).

Run the following command:

docker tag <LOCAL_IMAGE_NAME>:<LOCAL_IMAGE_TAG> <ECR_REPOSITORY_URI>:latest

Replace <LOCAL_IMAGE_NAME>:<LOCAL_IMAGE_TAG> with the name and tag of your local Docker image, and <ECR_REPOSITORY_URI> with the repositoryUri you copied from the output of Step 2. Make sure to include :latest at the end of the URI.

After running the command, you’ll see an output similar to the following:

Tag your Docker image

By running this command, you're basically telling Docker to take your local image and associate it with a new tag that points to your ECR repository. This step is necessary because you need to specify where (which registry and under what name) you want to store the image when you push it (in the next step).

Step-4: Push Docker Image to ECR

Now you upload, or "push", the image to ECR.

Run the following command:

docker push <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<REPO_NAME>:latest

Replace <AWS_ACCOUNT_ID>, <AWS_REGION>, and <REPO_NAME> with your AWS account ID, the AWS region where your ECR repository is located, and the name of your ECR repository, respectively. Make sure to include :latest at the end of the repository URI.

After running the command, you’ll see an output similar to the following:

Push Docker image to ECR

Step-5: Create an Execution Role for the Function

Before your Lambda function can interact with AWS services, it requires an identity in the form of an "execution role". This role is used to define a trust relationship between your Lambda function and AWS services.

Think of the execution role is like a badge that identifies your Lambda function within the AWS ecosystem. Without this badge, AWS has no way to authenticate or recognize your Lambda function, and consequently, it won't be able to perform any tasks. The actual permissions that dictate what tasks are allowed will be attached to this role in the following steps.

Run the following command:

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

Replace <NAME_OF_THE_EXECUTION_ROLE> with the actual name that you wish to assign to the execution role.

Note that we have specified the trust policy inline. You can also define the trust policy for the role using a JSON file.

The trust policy in this case is saying:

After running the command, you’ll see an output similar to the following:

Create an execution role for the Lambda function

Copy the ARN (Amazon Resource Name) of the role. You need it in the last step.

Step - 6: Add Permissions to the Role

After establishing an execution role for your Lambda function, the next crucial step is to define exactly what AWS resources and services this role has permission to access. This is done by attaching policies to the role. Think of the role as a user identity for your Lambda function, and the policies as the list of things this identity can do.

Run the following command:

aws iam attach-role-policy --role-name <NAME_OF_THE_EXECUTION_ROLE> --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

Here's what each part of the command does:

The AWSLambdaBasicExecutionRole is a predefined AWS policy that grants enough permissions for a Lambda function to run and log its activity, but not more than what's necessary. It’s a starting point. If your Lambda function needs to interact with other services like S3 or DynamoDB, you would then attach additional policies that grant access to those specific services.

After running the command, you’ll see an output similar to the following:

Add permission to the execution role

Step-7: Create the Lambda Function

To creates a Lambda function based on the Docker image you've pushed to ECR, run the following command:

aws lambda create-function \
 --function-name <FUNCTION_NAME> \
 --package-type Image \
 --code ImageUri=<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/<REPO_NAME>:latest \
 --role arn:aws:iam::<AWS_ACCOUNT_ID>:role/<NAME_OF_THE_EXECUTION_ROLE>

Here's a breakdown of the command:

Now you know hoe to create and deploy a Docker image as an AWS Lambda function.