2022-02-25

Sharing node_modules folder between lambda using Lambda Layers + Cloud Formation

I have a project that uses serverless-framework (this) to define the AWS resources to be used. I have the various .yml files that describe each resource that the project needs to run.

Recently, I've had to install several NPM packages for my lambdas and they've become very large in megabytes (>3MB), so the code is no longer viewable from the console.

Since including node_modules in each lambda is not a best practice and they are very heavy this way, I was wondering about using a Lambda Layer to share node_modules between lambdas.

As .yml I have a shared structure between all of them called provider.yml, something like:

name: aws
runtime: nodejs14.x
lambdaHashingVersion: 20201221
region: ${opt:region, "eu-central-1"}
stage: ${opt:stage, "dev"}
profile: ${self:custom.profiles.${self:provider.stage}}
deploymentBucket:
 name: avatar-${self:provider.stage}-deploymentbucket
 versioning: true
 blockPublicAccess: true
environment:
 EXAMPLE_ENV_VAR: ${self:custom.baseResource}-envvar
USERPOOL:
 'Fn::ImportValue': ${self:custom.baseResource}-userPoolId
APP_CLIENT_ID:
 'Fn::ImportValue': ${self:custom.baseResource}-userPoolClientId
iamRoleStatements:
 - Effect: Allow
 Action:
  - dynamodb:Query
  - ...
Resource: "*"

Then I have a file that includes the provider.yml and all the lambdas (called serverless.yml) and is the file that I use to deploy:

service: listOfLambdas
app: appname
frameworkVersion: '2'
projectDir: ../../

provider: ${file(../../resources/serverless-shared-config/provider.yml)}

package:
 individually: true
 exclude:
  - "**/*"

functions:
 - ${file(./serverless-functions.yml)}

Finally, I have the serverless-functions.yml that contains the Lambdas structure:

lambdaName:
handler: src/handlers/auth/example.run
name: ${self:custom.base}lambdaName
description: Lambda description
events:
 - httpApi:
     method: POST
     path: /api/v1/example
package:
 include:
   - ../../node_modules/**

This includes the node_modules folder in the Lambda.

How can I create a resource with a YML template managed by Cloud Formation to create a Lambda Layer to which I can assign all my lambdas so that they share the node_modules folder. I expect to have to create a new serveless.yml inside the resources folder with the CloudFormation YML template to bind I guess somehow to my lambdas.

I need it to be managed by CloudFormation, so I can have a common stack with all the resources used by the project and so I can deploy it at start-up.

Where should the node_modules then be foldered in the project? Now the project is something like:

Root
|_ lib
|_ node_modules
|_ resources
   |_serverless-shared-config
     |_provider.yml
   |_s3
     |_serverless.yml
   |_apigateay 
   |_ ... 
|_ services
   |_ lambda
      |_ src
         |_ index.js
         |_ ...
      |_ serverless.yml
      |_ serverless-functions.yml

Where can I find a template in order to solve this problem? Or what is the best practice in order to share the node_modules between Lambdas?



No comments:

Post a Comment