Integrating Lambda Layers into your Node.js Lambdas using pre-configured templates
Rob Cronin4 min read
AWS recently released the ability to add layers to your lambda functions.
These layers can be standalone code to be reused across multiple lambdas, library dependencies or custom runtimes.
This article will go through a setup for the first use case for a standard nodejs8.10
lambda using templates to generate the boilerplate.
The advantages of layers according to AWS are to:
- Enforce separation of concerns, between dependencies and your custom business logic.
- Make your function code smaller and more focused on what you want to build.
- Speed up deployments, because less code must be packaged and uploaded, and dependencies can be reused.
For more information about using layers to create a custom runtime see my colleague Ben’s article.
Ready to use templates
To ease the setup of layers with your lambda I’ve created two templates to set this up yourself here:
Both of these templates can be installed with serverless install
(or a git clone
) and provide the following out of the box:
- a quick
setUp.sh
script to customise it accordingly - deployable to your aws account in one command (
yarn deploy
) - local support for your lambda with
serverless-offline
and a script to get your layers working locally - configured to use the latest babel preset (
@babel/preset-env@7.23
) - ready to use with
jest
,eslint
andprettier
Both of these templates derive from AnomalyInnovations/serverless-nodejs-starter.
Sidenote: To see an example of what you can do after creating your templates see my last article about the setup and deployment of a lambda which interacted with github webhooks.
Layer Example
A layer can be useful for code you find yourself writing for every lambda you deploy.
One example is accessing ssm
parameters which is usually some variation of the following:
import Aws from 'aws-sdk';
const ssm = new Aws.SSM({
region: 'eu-west-1',
});
export default namesArray =>
new Promise((resolve, reject) => {
ssm.getParameters(
{
Names: namesArray,
WithDecryption: true,
},
(err, data) =>
err
? reject(err)
: resolve(data.Parameters.map(parameter => parameter.Value)),
);
});
While not particularly difficult to copy/paste in this case, it is one extra thing to do everytime you need to use credentials on your lambda.
You may find yourself with bigger use cases that require maintaining across projects.
If instead this code was deployed as a layer you could add the arn
(Amazon Resource Name) for your layer to your serverless.yml
config:
functions:
myLambda:
...
...
layers:
- arn:aws:lambda:eu-west-1:[ID]:layer:ssm-access:1
At runtime your lambda will now have access to your ssm
layer code in the /opt
directory and you could simply drop the following into your fresh lambda:
import { getSSMParameters } from '/opt/ssm-access';
const myFunction = async () => {
...
const secret = await getSSMParameters(['my_secret']);
...
}
Using the templates to recreate this
The templates will allow you to quickly recreate this (their respective README’s have more info):
See this repo for the ssm example as a reference if needed.
Pre-requisite: you have serverless
installed. If not: yarn global add serverless
.
Set up the layer
- Install layer template:
sls install --url https://github.com/robcronin/serverless-layer-template --name ssm-access
cd ssm-access
yarn
./setUp.sh
and follow prompts- Add your code to
src
- e.g. the ssm code above - Add any required tests to
tests
yarn deploy
(assuming your aws access keys are set up, see here if not)- On deployment you will be shown an
arn
for your new layer - Or see it in your aws console once deployed
Set up the lambda
- Install lambda template:
sls install --url https://github.com/robcronin/serverless-lambda-with-optional-layer-template --name myLambda
cd myLambda
yarn
./setUp.sh
and follow prompts (it will ask for your layer’s arn and tell you where to put it)- Add your lambda code to
handler.js
- Add
import { getSSMParameters } from '/opt/ssm-access'
etc to your lambda - Add any required tests
yarn deploy
- On deployment you will be shown an endpoint you can now use which will reference your layer when invoked
🎉 Done 🎉
Running locally
If we normally want to test a lambda locally we can use serverless-offline which sets up a server simulating what the API Gateway does for us (i.e. we can call our lambda from localhost
).
If our lambda uses layers it will try to access code from /opt
which won’t exist by default.
So the Layer template provides a local.sh
script which will package your code as if deploying it and then copy it to your local /opt
directory.
If you’re developing your layer, the layer template also provides a yarn watch
command to watch any changes to your layer and update your local /opt
directory as needed.
Using yarn start
(i.e. serverless offline start
) in the lambda directory will now work for your local lambda.
Closing
Depending on your use case, having lambda layers to share reusable code could save you a lot of set up time.
Combined with these templates you can have a working staging and production lambda that say, calls a payment service in 30 minutes!