Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serverless - Lambda Layers "Cannot find module 'request'"

When I deploy my serverless api using:

serverless deploy

The lambda layer gets created but when I go to run the function is gives me this error:

"Cannot find module 'request'"

But if I upload the .zip file manually through the console (the exactly same file thats uploaded when I deploy), it works fine.

Any one have any idea why this is happening?

environment:
SLS_DEBUG: "*"

provider:
name: aws
runtime: nodejs8.10
stage: ${opt:api-type, 'uat'}-${opt:api, 'payment'}
region: ca-central-1
timeout: 30
memorySize: 128
role: ${file(config/prod.env.json):ROLE}
vpc:
    securityGroupIds:
    - ${file(config/prod.env.json):SECURITY_GROUP}
    subnetIds:
    - ${file(config/prod.env.json):SUBNET}
apiGateway:
    apiKeySourceType: HEADER
apiKeys:
    - ${file(config/${opt:api-type, 'uat'}.env.json):${opt:api, "payment"}-APIKEY}

functions:
- '${file(src/handlers/${opt:api, "payment"}.serverless.yml)}'

package:
# individually: true
exclude:
    - node_modules/**
    - nodejs/**

plugins:
- serverless-offline
- serverless-plugin-warmup
- serverless-content-encoding

custom:
contentEncoding:
    minimumCompressionSize: 0 # Minimum body size required for compression in bytes

layers:
nodejs:
    package:
    artifact: nodejs.zip
    compatibleRuntimes:
    - nodejs8.10
    allowedAccounts:
    - "*"

Thats what my serverless yaml script looks like.

like image 404
Mikerizzo Avatar asked Apr 05 '19 15:04

Mikerizzo


2 Answers

I was having a similar error to you while using the explicit layers keys that you are using to define a lambda layer.

My error (for the sake of web searches) was this:

Runtime.ImportModuleError: Error: Cannot find module <package name>

I feel this is a temporary solution b/c I wanted to explicitly define my layers like you were doing, but it wasn't working so it seemed like a bug.

I created a bug report in Serverless for this issue. If anyone else is having this same issue they can track it there.

SOLUTION

I followed this this post in the Serverless forums based on these docs from AWS.

I zipped up my node_modules under the folder nodejs so it looks like this when it is unzipped nodejs/node_modules/<various packages>.

Then instead of using the explicit definition of layers I used the package and artifact keys like so:

layers:
  test:
    package:
      artifact: test.zip

In the function layer it is referred to like this:

functions:
  function1:
    handler: index.handler
    layers:
      - { Ref: TestLambdaLayer }

The TestLambdaLayer is a convention of <your name of layer>LambdaLayer as documented here

like image 171
codeinaire Avatar answered Sep 21 '22 13:09

codeinaire


Make sure you run npm install inside your layers before deploying, ie:

cd ~/repos/repo-name/layers/utilityLayer/nodejs && npm install

Otherwise your layers will get deployed without a node_modules folder. You can download the .zip of your layer from the Lambda UI to confirm the contents of that layer.

like image 39
Elon Zito Avatar answered Sep 19 '22 13:09

Elon Zito