Following last week's fun with packaging Lambdas that use Python, here’s a little puzzle with Node.js.
I have an outdated project that uses a Lambda originally built on v2 of the AWS SDK for JavaScript and which ran on the Node.js 12.x runtime. The minimum supported runtime now is Node.js 18.x, and starting with that version v3 is shipped instead of v2. I spent some time digging into migrating the functionality from v2 to v3, determined that the change wasn’t trivial, and decided to buy myself some time by shipping v2 of the SDK with my Lambda function. I didn’t find any guides on how to do that within an AWS CDK project, hence this post.
The root of my project isn’t the Lambda function, but the project’s entire infrastructure, of which the Lambda function and its code is but a small piece. This is the typical structure:
1 | bin/ |
CDK will zip up the contents of a specified directory and handle deploying it:
1 | const yourFunction = new lambda.Function(this, 'LambdaFunction', { |
It feels ugly, but I solved this by creating a stub package.json
inside the folder-containing-lambda-function
directory and running yarn add aws-sdk@2
from there (thus avoiding the problem of it trying to use the package.json
from the parent directory). Here’s the package.json:
1 | { |
This creates a second node_modules
within lib/folder-containing-lambda-function
. Unlike the one at root, I actually want to version this for deployment purposes, so I modify the main .gitignore
to only exclude the top-level node_modules
:
1 | /node_modules/ |
Through this entire process I’m not altering the actual code in my Lambda function at all. The SDK (v2) will be unzipped at the root and available in the expected place:
1 | const AWS = require('aws-sdk') |
Under this approach node_modules
is 110 MB uncompressed and 15 MB compressed. I want to emphasize that this isn’t a great solution, but I was in a rush and needed to restore functionality, and it worked like a charm. For a proper resolution, I’m considering a few options, including building a Lambda layer with v2 SDK, or refactoring the whole thing using the boto3 library in Python.