AWS Certified Developer - Associate
Serverless
Lambda Layers Demo
In this lesson, we demonstrate how to use third-party libraries in AWS Lambda functions and create a Lambda layer to share these libraries across multiple functions. We will build a simple demo application where a user provides a password to the Lambda function, which then returns a hashed version of that password.
Setting Up the Application
When developing a Node.js application, third-party libraries are managed via NPM—similar to how pip works in Python. In this demo, we use the bcrypt.js library for hashing passwords.
Our project begins with a basic package manifest file (package.json
):
{
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
To add bcrypt.js to your project, navigate to your project folder in the terminal and run:
npm install bcryptjs
After execution, NPM creates a node_modules
folder that stores the source code for bcrypt.js along with its dependencies. The terminal output might look like this:
C:\Users\sanje\OneDrive\Documents\courses-sanjeev-desktop\aws-developer-associate\lambda\layers>npm install bcryptjs
added 1 package, and audited 2 packages in 566ms
found 0 vulnerabilities
C:\Users\sanje\OneDrive\Documents\courses-sanjeev-desktop\aws-developer-associate\lambda\layers>
Writing the Lambda Function Code
Next, build your Lambda function by importing bcrypt.js, extracting the password from the event object, hashing it, and returning the hashed password in the response. Below is the source code (index.js
) for the Lambda function:
import bcrypt from "bcryptjs";
export const handler = async (event) => {
const numSaltRounds = 8;
const password = event.password;
const hashedPassword = await bcrypt.hash(password, numSaltRounds);
const response = {
statusCode: 200,
body: JSON.stringify("Hashed Password: " + hashedPassword),
};
return response;
};
Deploying and Testing the Application
Follow these steps to deploy and test your Lambda function:
- Create a new AWS Lambda function (for example, "passwordHash") with the runtime set to Node.js.
- Copy and paste the above source code into the Lambda console.
- Deploy the changes.
- Configure a test event. Make sure to include a
password
property, as shown below:
{
"password": "123"
}
When you run the test, you might see an error similar to the following:
{
"errorType": "Error",
"errorMessage": "Cannot find package 'bcryptjs' imported from /var/task/index.mjs",
"trace": [
{
"Error": "ERR_MODULE_NOT_FOUND: Cannot find package 'bcryptjs' imported from /var/task/index.mjs",
"at packageResolve": "node:internal/modules/esm/resolve:858:9",
"at moduleResolve": "node:internal/modules/esm/resolve:915:20",
"at defaultResolve": "node:internal/modules/esm/resolve:1135:12",
"at ModuleLoader.defaultResolve": "node:internal/modules/esm/loader:961:12",
"at ModuleLoader.resolve": "node:internal/modules/esm/loader:365:14",
"at ModuleLoader.getModuleJob": "node:internal/modules/esm/module:240:83",
"at ModuleWrap.<anonymous>": "node:internal/modules/esm/module:198:21",
"at link": "node:internal/modules/esm/module:84:36"
}
]
}
Note
This error occurs because the Lambda function does not have access to the node_modules
folder that contains bcrypt.js.
Packaging the Application with Dependencies
To ensure that your Lambda function can find the bcrypt.js library, you must include the node_modules
folder along with your source code in a zip file. Follow these steps:
- Open your project folder containing both
index.js
and thenode_modules
folder. - Select both
index.js
and thenode_modules
folder. - Compress these into a zip file (for example,
hash_lambda.zip
). - Upload the zip file to your Lambda function using the "Upload from" option in the Lambda console.
- Save the changes.
After deploying, test the function again. You should receive a response similar to:
{
"statusCode": 200,
"body": "\"Hashed Password: $2a$08$572qij5n5l9C9txulrmmOSoi2/a9/EHKyDjnThkA2bUjEic\""
}
Introducing Lambda Layers
Including the complete node_modules
folder with every Lambda function can be redundant, especially when multiple functions share the same dependencies. Lambda layers allow you to share common libraries across functions without bundling them repeatedly.
Preparing the Lambda Layer
Delete the
node_modules
folder from your main source bundle and deploy to confirm that the error reappears.Create a new folder structure for the layer. For Node.js, the structure must include a folder named
Node.js
containing thenode_modules
folder:- Create a folder named
Node.js
. - Move your
node_modules
folder into theNode.js
folder.
Ensure that your folder structure now includes a
Node.js
folder with thenode_modules
folder inside it.- Create a folder named
Compress the
Node.js
folder into a zip file (for example,hash_layer.zip
).
Creating and Attaching the Layer in AWS Lambda
- Open the AWS Lambda console and navigate to the Layers section.
- Click "Add a new layer".
- Name your layer (e.g., "bcrypt") and upload the
hash_layer.zip
file. - Select the compatible runtime (e.g., Node.js 20.x) and create the layer.
- Attach the layer to your Lambda function via the Layers section in the Lambda console by following the on-screen instructions.
With the layer attached, your Lambda function will reference the bcrypt.js library from the layer instead of needing node_modules
within its deployment package.
Note
Before attaching the layer, your Lambda function may display errors due to the missing bcrypt.js package.
Testing with the Lambda Layer
After attaching the layer, test your Lambda function again. The function should now import bcrypt.js from the layer and return a hashed password successfully. A typical successful response might look like:
{
"statusCode": 200,
"body": "\"Hashed password: $2a$08$UlNbc6aTAUNkC7THD.DhE2XHhAy7dkRUC.CLETKSZghfBfabhUrK\""
}
Conclusion
In this lesson, we learned how to bundle a Node.js application with third-party libraries and deploy it as a Lambda function on AWS. We also explored using Lambda layers to simplify dependency management when multiple Lambda functions share the same external libraries. This approach not only reduces the size of your deployment package but also centralizes common dependencies for easier updates and maintenance.
Watch Video
Watch video content