cesarpachon
cesarpachon

Reputation: 1213

aws lambda layer shared library in node_modules not accesible in function

I recently changed my lambda functions to use the new aws Lambda Layer functionality, to share all the node_modules folder. I created the zip with the following structure:

nodejs/node_modules/<libraries, like 'async' and others..>
nodejs/package.json

I also linked the lambda function to the layer, and it succeed (checked both in the CLI and in the web console), see output below.. but anyway, always the lambda function fails on the require:

in lambda: require('async')

output: "errorMessage":"Cannot find module 'async'"

output of the update-function call:

aws lambda update-function-configuration --function-name MY_LAMBDA --layers arn:aws:lambda:us-west-2:MY_ID:layer:MY_LAYER:4
{
"Layers": [
{
"CodeSize": 21482560,
"Arn": "arn:aws:lambda:us-west-2:MY_ID:layer:MY_LAYER:4"
}
],
"FunctionName": "MY_LAMBDA",
"LastModified": "2018-12-18T23:44:34.062+0000",
"RevisionId": "f55a6ab7-7b0b-494a-840c-87fb8371a117",
"MemorySize": 128,
"Version": "$LATEST",
"Role": "arn:aws:iam::MY_ID:role/service-role/MY_ROLE",
"Timeout": 30,
"Runtime": "nodejs4.3",
"TracingConfig": {
"Mode": "PassThrough"
},
"CodeSha256": "hajYdqb+...=",
"Description": "",
"VpcConfig": { ... lot of stuff here .. },
"CodeSize": 429123,
"FunctionArn": "arn:aws:lambda:MY_ZONE:MY_ID:function:MY_LAMBDA",
"Handler": "MY_HANDLER"
}

notes: 1. my layer is in version 4. 2. I set the layer to all three node.js environments for support. 3. I checked the zip and it has all the node_modules content as expected.

any suggestion about what else to check is welcomed!

Upvotes: 9

Views: 5905

Answers (3)

MattC
MattC

Reputation: 6344

I was having an issue with this as well. Turns out you need to make sure you have your zip file set up correctly, using 'nodejs' as the folder name. If you create a folder named 'nodejs' with just your package.json, run npm install, and then zip that up, then you can use 'require' normally.

In my case, I am using the NPM packages axios, aws-sdk, and http. Here's the steps I took:

  • Create a 'nodejs' directory
  • Copy your package.json file into it
  • Run npm install in the nodejs directory
  • From one level up, zip the directory. On a Mac: zip nodejs.zip nodejs/ -r
  • Create a layer in AWS, import the zip, and give the layer the Node.js runtime
  • Add the layer to your lambda

Now I can use my require statements normally.

const axios = require('axios')
const AWS = require('aws-sdk');
const http = require('http');

Also note that your lambda's role, under Basic Settings, should have lambda permissions. For example, if your role has the AWSLambdaFullAccess policy attached, or another policy with the correct lambda permissions (like "lambda:*"), then you are fine.

Upvotes: 6

shailesh sahu
shailesh sahu

Reputation: 157

I have also stuck in this problem and not able to figure it out because I have applied all mentioned things like permission and node zip but was n't successful after a while I used the const lodash = require('/opt/nodejs/node_modules/lodash') It works for me.

Upvotes: 9

Chetan
Chetan

Reputation: 6901

You able to create the Layer and it's version properly and also able to retrieve information about them without any issues.

Even after that Lambda function is not able to use the libraries from the Layer, looks like the Lambda function is not able to access the Layer because it does not have the permission to do so.

You can confirm this by checking if the role associated with the Lambda is having any policy attached to it which allows lambda:GetLayerVersion permission.

If not you need to create a new policy with following JSON and some meaningful name.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "lambda:GetLayerVersion",
            "Resource": "*"
        }
    ]
}

Now you need to add attach this policy to the role arn:aws:iam::MY_ID:role/service-role/MY_ROLE which associated with the Lambda function.

Both of the above actions can be performed from AWS Console.

Once this is done, the Lambda function will have permission to get the layer version and should be able access the libraries from the Layer.

I hope this would help you resolve your issue. Feel free to ask if you need any clarifications.

Upvotes: 5

Related Questions