During Re:Invent 2020, AWS announced Container Image Support for AWS Lambda functions using the AWS Elastic Container Registry. Personally, I think this is a great feature. With supporting docker images, AWS Lambda has immutable deployment artifacts!
tl;dr: aws-lambda-docker-node on GitHub
Event-Driven Delivery
I build a Continuous Integration and Continuous Deployment setup for AWS Lambda functions with docker images using GitHub Actions. Together with Semantic Releases and Conventional Commits, you can focus on writing your code. Automation takes care everything else, the release cycle consists of three events:
- For every push to the main branch, a GitHub action will check the recent commit messages and create a new tag and release if needed: Semantic Releases With Github Actions
- For every new release, a GitHub action will build and tag a docker container image and push it to AWS ECR: Continuous Deployment With Github Action for AWS ECR
- Afterwards, a GitHub action will update the AWS Lambda function to use new image using a CloudFormation template: Update CloudFormation with GitHub Actions
The abstract concept is detailed in Event-Driven Delivery.
Dockerfile
The general setup for AWS Lambda, Docker images, and CloudFormation is not that complext; a typical Dockerfile for Node.js can look like this:
FROM amazon/aws-lambda-nodejs:12
ARG FUNCTION_DIR="/var/task"
RUN mkdir -p ${FUNCTION_DIR}
COPY package.json ${FUNCTION_DIR}
COPY src ${FUNCTION_DIR}/src
RUN npm install
CMD [ "src/handler.run" ]
After building and tagging an images using the docker CLI, you need to push the image to a container registry, like AWS Elastic Container Registry.
CloudFormation
To create a new AWS Lambda function with CloudFormation, you can simply reference the pushed image:
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Parameters:
ImageName:
Type: String
ImageTag:
Type: String
Resources:
Function:
Type: AWS::Serverless::Function
Properties:
ImageUri: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${ImageName}:${ImageTag}
PackageType: Image
The example project aws-lambda-docker-node on GitHub combines all resources and actions to build a Continuous Integration and Continuous Deployment setup.