DEV Community

Cover image for Deploy your first Node 20 Lambda function on AWS!
Pierre Chollet for Serverless By Theodo

Posted on • Updated on

Deploy your first Node 20 Lambda function on AWS!

TL;DR

AWS released a public base image for Node 20 Lambda runtime last week. It is now possible to deploy Node 20 Lambda functions on AWS, by using this image with ECR (Elastic Container Registry). In this article, discover how to deploy your first Node 20 Lambda function on AWS, before the managed runtime is released! Stay tuned till the end to see the performance results.

I you want to stay in touch here is my twitter account. I often post or re-post interesting stuff about AWS and serverless, feel free to follow me!

Follow me on twitter 🚀

Quick announcement: I also work on a library called 🛡 sls-mentor 🛡. It is a compilation of 30 serverless best-practices, that are automatically checked on your AWS serverless projects (no matter the framework). It is free and open source, feel free to check it out!

Find sls-mentor on Github ⭐️

🚨 Last minute update: Node 20 managed runtime is now available, no need to use container images anymore 🚨

If you still want to learn how to deploy a Lambda function using a container image, back to the article ⬇️

How to deploy a pre-release Node 20 Lambda function on AWS?

Node 20 isn't officially supported by AWS Lambda yet. However, AWS released a public base image for Node 20 Lambda runtime last week. It is possible to use this base image to build a custom runtime with docker, and use it to deploy Lambda functions on AWS. This is achieved in three simple steps:

  • Build a Node 20 Lambda docker image based on the public AWS base image (done locally)
  • Push this image to ECR (Elastic Container Registry)
  • Create a Lambda function using this image

Build a Node 20 Lambda docker image

First step: create a dockerfile to build a Node 20 Lambda docker image.

FROM public.ecr.aws/lambda/nodejs:20.2023.11.12.08-arm64
COPY app.js ./
CMD [ "app.handler" ]
Enter fullscreen mode Exit fullscreen mode

This image is derived from the official public.ecr.aws/lambda/nodejs:20.2023.11.12.08-arm64 image. You can also use public.ecr.aws/lambda/nodejs:20.2023.11.12.08-x86_64 if the target Lambda architecture is x86_64. Then, it copies the app.js file to the image, and sets the CMD to app.handler. This means that we have to create a app.js file in the same directory as the dockerfile, and define a handler function in it.

To test if the image runs on Node 20, let's use a Node 20 only feature: the Array.prototype.toSorted method, which creates a new sorted array without modifying the original array. This new method is only available in Node 20, so if the image runs on Node 20, it should work. Here is the app.js file:

exports.handler = async () => {
  const table = [2, 3, 1, 9, 4];

  const sortedTable = table.toSorted(); // Only works on Node 20!

  return sortedTable; // [1, 2, 3, 4, 9]
};
Enter fullscreen mode Exit fullscreen mode

We are done! Lets build the image! I add a lambda-image:node-20 tag to the image, so that I can easily find it later.

docker build --platform linux/amd64 -t lambda-image:node-20 . # tag the image with your own tag
Enter fullscreen mode Exit fullscreen mode

Push the image to ECR (Elastic Container Registry)

Now that the image is built, we can push it to ECR. First, we need to create a repository in ECR. I will use the AWS CLI to do so. For all the following commands, replace <REPOSITORY_NAME> with the name you want to give to your repository, with your AWS account ID, and with the AWS region you want to use.

# create the ECR repository
aws ecr create-repository --repository-name <REPOSITORY_NAME> --image-scanning-configuration scanOnPush=true --region <AWS_REGION>

# login docker to ECR
aws ecr get-login-password | docker login --username AWS --password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com

# tag the image with the ECR repository URI
docker tag lambda-image:node-20 <AWS_ACCOUNT_ID>.dkr.ecr.eu-west-1.amazonaws.com/<REPOSITORY_NAME>:latest

# push the image to ECR
docker push <AWS_ACCOUNT_ID>.dkr.ecr.eu-west-1.amazonaws.com/<REPOSITORY_NAME>:latest
Enter fullscreen mode Exit fullscreen mode

We are done with Docker! Now, let's create a Lambda function using this image.

Create a Lambda function using this image

For this step, I will use the Web UI, for clarity. You can also use any programmatic way to create your Lambda function. The process is pretty straightforward:

Step 1

Step 2

Step 3

You are done! You can now test your Lambda function. If everything went well, you should see the following result:

Step 4

The Array.prototype.toSorted method worked as expected! This means that the Lambda function ran on Node 20.

Lambda Node 20 performance

In ran 50 cold and warm starts on this Lambda function, and measured the execution time. Here are the results, compared to a similar Lambda function running on the aws-managed Node 18 runtime:

Runtime Median execution time Average execution time Cold ⛄️ or warm 🔥
Node 18 177ms 175ms Cold ⛄️
Node 20 236ms 232ms Cold ⛄️
Node 18 2ms 11ms Warm 🔥
Node 20 2.5ms 28ms Warm 🔥

What can we learn from these results? Node 20 is slower than Node 18 on cold starts, and has similar performance on warm starts. This is not surprising, as Node 20 is still in pre-release and is deployed using a container image, which has slower cold starts.

Expect the performance to be better when the managed Node 20 runtime is released!

Let's connect!

I would really appreciate if you could react and share this article with your friends and colleagues. It will help me a lot to grow my audience. Also, don't forget to subscribe to be updated when the next article comes out!

I you want to stay in touch here is my twitter account. I often post or re-post interesting stuff about AWS and serverless, feel free to follow me!

Follow me on twitter 🚀

Top comments (11)

Collapse
 
fmcdev profile image
fmcdev

I'd like to add a suggestion that got me crazy when trying to migrate AWS Lambda functions from nodejs 16 to nodejs 20. The issue is that aws-sdk changed from V2 to V3 in the meanwhile and AWS.util.uuid.v4() is not available anymore. You can solve using:
const { randomUUID: AWS_util_uuid_v4 } = require('crypto');
and then use AWS_util_uuid_v4() where you used AWS.util.uuid.v4() before. Hope this can help. Bye

Collapse
 
jlgouwy profile image
Gouwy Jean-louis

Do we know if there is an "official" release date for this runtime ?
Because we plan to migrate to node 18 ... but if the 20 is coming in few weeks, it should worth to wait for it.

Collapse
 
pchol22 profile image
Pierre Chollet

It should be available in a few days / weeks, given that Node 20 became LTS two weeks ago.

I would suggest you to wait for Node 20 if you can afford to delay your migration for at least one more month, to avoid instabilities in the first releases of the official managed runtime.

Collapse
 
pchol22 profile image
Pierre Chollet

Update: AWS just released the Node 20 managed runtime, available right now! (at least in eu-west-1 where I checked)

Collapse
 
nienow profile image
Matthew Nienow

Can you have the Lambda functions update automatically when you push new docker images?

Collapse
 
pchol22 profile image
Pierre Chollet

There is no obvious way to do so, it surely can be achieved by using some frameworks like SAM...
What you can easily do yourself is run this kind of command in your terminal just after you pushed the image :

aws lambda update-function-code \
           --function-name my-lambda \
           --image-uri 123456789.dkr.ecr.eu-west-1.amazonaws.com/my-image:latest
Enter fullscreen mode Exit fullscreen mode

with the tag of the image you just pushed. It will update the lambda from your CLI

Collapse
 
nienow profile image
Matthew Nienow

thanks for this tip

Collapse
 
dsaga profile image
Dusan Petkovic

I haven't worked with AWS lambdas before, but does each function need to be added via the GUI in aws?

Collapse
 
dsaga profile image
Dusan Petkovic

If a configuration file could be added where multiple functions can be defined or something?

Collapse
 
pchol22 profile image
Pierre Chollet

Also, I am currently writing a series where I start from the beginning, and use the AWS CDK to deploy my lambda functions programmatically. You can find the first article here : dev.to/slsbytheodo/dont-miss-on-th...

Collapse
 
pchol22 profile image
Pierre Chollet

Yes are many ways to deploy Lambda function without the CLI. I advise you to check the serverless framework, the AWS CDK or SST, that allow to do this programmatically using JS or TS.