Deploying Nodejs on AWS Lambda using NodejsFunction
Tags: aws, cdk, deployment, javascript, node • Categories: Web Development
I wanted to deploy a node lambda on AWS using CDK. The NodejsFunction
seemed like an improvement over using the standard Function
construct: the CDK SDK would bundle your code for you, in a docker container running the same version of node used in the lambda. Instead of defining a code
param you define an entry
file that is used for the compilation process. This seems like a great improvement over copy/pasting your local nodejs application (including the local node_modules
!) into the lambda.
However, I ran into trouble using the new NodejsFunction
with my folder structure:
├── aws
│ ├── bin
│ │ └── app.ts
│ ├── cdk.context.json
│ ├── cdk.json
│ ├── jest.config.js
│ ├── lib
│ │ └── app-stack.ts
│ ├── package-lock.json
│ ├── package.json
│ └── tsconfig.json
├── scraper
│ ├── index.js
│ ├── package-lock.json
│ ├── package.json
Here are some of the errors I ran into:
Error: Expected depsLockFilePath: /Users/mike/Projects/app/aws/package-lock.json to be under projectRoot: /Users/mike/Projects/app/scraper (../aws/package-lock.json)
Error: Cannot find entry file at ../../scraper/index.js
Error: Failed to bundle asset AppStack/lambdaName/Code/Stage, bundle output is located at /Users/mike/Projects/app/aws/cdk.out/bundling-temp-bf573289455d3d7a0be3d679feccc06baffacf40ec876dfab54c1a694020c731-error: Error: docker exited with status 1
What I found is that if you are creating a NodejsFunction
and it’s not in the same folder as the CDK application (which I find to be the most ergonomic) you have to define more than just entry
:
const lambdaAppDir = path.resolve(__dirname, '../../scraper')
const sourceLocationParams: aws_lambda_nodejs.NodejsFunctionProps = {
projectRoot: lambdaAppDir,
entry: path.join(lambdaAppDir, 'index.js'),
depsLockFilePath: path.join(lambdaAppDir, 'package-lock.json'),
}
const scrapeFunction = new aws_lambda_nodejs.NodejsFunction(this, "scraper", {
...sourceLocationParams,
runtime: aws_lambda.Runtime.NODEJS_18_X,
...
})