In the context of AWS (Amazon Web Services), a Lambda Layer refers to a distribution mechanism for reusable libraries, custom runtimes, or other function dependencies in AWS Lambda. Lambda Layers provide a way to manage and share code or dependencies across multiple Lambda functions.
There are a couple of reasons why you would consider using a lambda layer with your lambda functions, some of which include:
When creating a new lambda function, you would typically attach the lambda layer to it. When the lambda function is invoked, AWS Lambda automatically mounts the contents of the attached layers in the /opt
directory of the functions execution environment.
In your lambda function you would then import dependencies, modules or functions from the /opt
path. The structure inside the /opt
directory corresponds to the structure of the Lambda Layer. For example, if your lambda layer zip file contains a assets directory, you would access it in your function as /opt/assets
.
Let's use AWS CDK to see how we would attach a lambda layer to a lambda function.
To start, create a new cdk lambda stack.
// lambda-stack.tsimport * as cdk from "aws-cdk-lib";class LambdaStack extends cdk.Stack {constructor(scope, id, props) {super(scope, id, props);}}
Now let's add the code to create a new lambda function
// lambda-stack.tsimport * as cdk from "aws-cdk-lib";import * as lambda from "aws-cdk-lib/aws-lambda";class LambdaStack extends cdk.Stack {constructor(scope, id, props) {super(scope, id, props);// Create new lambda functionconst newLambda = new lambda.Function(this,`LambdaFunction`,{functionName: `LambdaFunction`,runtime: lambda.Runtime.NODEJS_18_X,handler: "index.handler",timeout: cdk.Duration.seconds(250),code: lambda.Code.fromAsset("path-to-lambda-code"), // replace with the path to the directory of your lambda code or the zip file.});}}
Now let's create our lambda layer and attach to the lambda function
// lambda-stack.tsimport * as cdk from "aws-cdk-lib";import * as lambda from "aws-cdk-lib/aws-lambda";class LambdaStack extends cdk.Stack {constructor(scope, id, props) {super(scope, id, props);// Create new lambda layerconst newLayer = new lambda.LayerVersion(this,`LambdaLayer`,{layerVersionName: `LambdaLayer`,code: lambda.Code.fromAsset("path-to-layer-code"), // replace with the path to the directory of your lambda layer code or the zip file.compatibleRuntimes: [lambda.Runtime.NODEJS_18_X],description: "Lambda Layer for test",});const newLambda = new lambda.Function(this,`LambdaFunction`,{functionName: `LambdaFunction`,runtime: lambda.Runtime.NODEJS_18_X,handler: "index.handler",timeout: cdk.Duration.seconds(250),layers: [newLayer],code: lambda.Code.fromAsset("path-to-lambda-code"), // replace with the path to the directory of your lambda code or the zip file.});}}
That's it. You can then deploy this stack with the rest of your infrastructure by running cdk deploy
Create a directory where the code for your layer function would live and create an index.js file inside. This is the same directory you referenced when creating the layer.
We would write a test function which we can export from the layer to be accessed by our lambda function. You can also install external package dependencies.
// layer/index.jsconst addFunction = (num1, num2) => num1 + num2export { addFunction }
Let's try to access the addFunction
in our lambda function
//lambda/index.jsimport { addFunction } from '/opt'// use addFunction here
As we can see from above, we can access code defined in our lambda layer inside the lambda function.
If you are using typescript locally, importing from the /opt
directory would cause type errors so you should create a link in your tsconfig.json
file so that typescript is aware such a path exists
{"paths": {"/opt": ["path-to-layer-code" // define path to your layer code relative to your lambda function],},}
Note that you might also want to exclude the /opt
path from being compiled given that it is now an external package
{"paths": {"/opt": ["path-to-layer-code" // define path to your layer code relative to your lambda function],},"exclude": ["/opt/**/*"]}
If you are using a bundler like webpack for example, in your webpack.config.js
you would also want to specify the /opt
directory as an external module to prevent it from being bundled together with your source code
// webpack.config.jsmodule.exports = {externals: {"/opt": "commonjs /opt",},}
There you have it folks. You can now use lambda layers in your next project.
If you need help or have questions, you can reach me on Twitter or shoot me an email at david.ajayi.anu@gmail.com.
Thanks for reading! 🙂