How to Build Both Kinds of AWS Lambda Layers. (Yes, There Are Two)
By: Allen Helton
Tags: Technology, Software Development, Serverless, Programming, AWS

Developer Ride-Along

Photo by Alvaro Reyes on Unsplash

It can be a little abstract following a guide on Medium. I’ve provided a complete working solution on GitHub for you to walk through with me.

Working examples have always helped me the most to get a hands-on approach to a problem. You might want to pause here to follow the prerequisites and make sure you’re set up.

The example I’ve provided is a small, serverless API that manages contacts and allows you to send them text messages through Twilio. You can add, update, and delete contacts, as well as send and view the messages that have gone to each contact.

Build a dependency layer

As stated before, dependency layers are useful for keeping your deployment packages small. A big situation in which this is helpful is if you have any expectation of using the AWS console to do any quick troubleshooting.

If a Lambda deployment package is larger than 3 MB, you cannot edit the code in the console.

So for our dependency layer in our contact example, we have a folder called dependencies at the root with a subfolder of nodejs. Lambda looks in specific directories for layer code based on the runtime. Since we are using Node in the example, we simply have to add a folder called nodejs .

For the complete list of all the directory names based on runtime, you can view the AWS documentation.

All we have in the nodejs folder is a package.json and a package-lock.json .

The package.json will only contain the dependencies we want to add in our layer.

In our SAM template, we want to add a LayerVersion and point it to the dependencies directory

That’s it for creating a dependency layer — super easy implementation, but not necessarily intuitive. Now on to creating a function layer.

Build a function layer

You might have more use cases for this type of layer, the layer that gives you the ability to provide shared code throughout your solution. This one is laid out similarly, but the consumption is slightly different.

Create a folder structure in the root called layers > nodejs . Again, the subfolder is because of the runtime we are using. It will be different for you if you are using Python, Ruby, etc.

Add the package.json and any file that is going to contain shared code. For our example, we have a database.js and an enums.js file.

Every file you add in this directory is a separate import in your Lambdas. This is nice because you get a reasonable separation of concerns for your shared code. It helps you stay a little more organized.

The resource declaration in the template yaml is going to be identical to the dependency layer, only this time it will point to the layers folder.

The implementation of the two types of layers is very similar, the only real difference being the files added to the layer directory. The main discrepancy between the two is how they are consumed by your functions.

Consuming a dependency layer

To make your layer available for consumption for a Lambda, you need to add it in the template yaml . If you want your layer available to all functions in your microservice, you can conveniently add it to the Globals section.

After you’ve made the layer available to the function, you need to pull the assets in. With dependency layers, it’s business as usual: simply add your require statement to pull it in. There is no change to how you build your function code.

Consuming a function layer

This is where your development will change slightly. Function layers get deployed to an opt directory, so to pull in your code, you must pull from opt/nodejs/<your filename> .