Integrating Lambda Layers into your Node.js Lambdas using pre-configured templates

Integrating Lambda Layers into your Node.js Lambdas using pre-configured templates

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 and prettier

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!


You liked this article? You'd probably be a good match for our ever-growing tech team at Theodo.

Join Us