Search code examples
amazon-web-servicesaws-lambdamiddlewareaws-lambda-layers

Can I use AWS Lambda Layers as a Middleware before my Lambda Function executes?


Context

I am currently working on a large system built on AWS, deployed with Terraform and has hundreds of lambdas. We received a new requirement recently that would require us to update all lambda events before they undergo processing. As there are hundreds of lambdas, this means I need to make the changes across multiple codebases, which is time consuming and I am likely to miss a few.

Problem

I want an easy and guaranteed way to add my code changes to every single lambda without having to do change every single codebase.

Possible Solution

Currently I’m looking to create an AWS Lambda Layer, which will have a function to perform my middleware logic and subsequently call the lambda handler’s function.

I can then set the entry function to be the lambda layer’s middleware function for all lambdas.

Question

Can I use lambda layers this way, should I, and why?


Solution

  • Currently I’m looking to create an AWS Lambda Layer, which will have a function to perform my middleware logic and subsequently call the lambda handler’s function.

    I can then set the entry function to be the lambda layer’s middleware function for all lambdas.

    A Lambda layer is a bunch of files that get mounted under /opt on the Lambda runtime container. It can contain libraries, config files and whatever else you might want to put there, but there is no way to have lambda call this code instead of the lambda handler. It's just sitting there.

    The handler itself is always loaded from $LAMBDA_TASK_ROOT (which is usually set to /var/task, not that it's any of your business per AWS).

    The only special treatment for the layers you get from your runtime is that the runtime-specific path (/opt/nodejs for node, /opt/python for Python etc.) gets added to the runtime's default library search path. You can do something like import * from "module" in your lambda handler, and it will look in the layers' folders as well.

    Of course, you can change the code of every single one of your lambdas and have it call the middleware from the layer as the first order of business when it runs, but I assume that's not something you had in mind.

    If you can repackage your lambdas as Docker images, it will become easier: you can just COPY your function elsewhere in the Dockerfile and replace the actual entrypoint with your wrapper. But, of course, it will require changing every lambda in a significant way as well.

    Another option would be piping your events through an EventBridge pipe with a transformer on it. It uses Apache VTL as a transformation template language, which is not that powerful but can handle basic tasks like adding a field of something like that.

    EventBridge Pipes support just about anything as an event source and Lambda as an event target, so it should not be hard to use them as a drop-in replacement for SQS, S3, Kinesis and other common event sources.