Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda can't find modules from outer folders when deployed with CDK

I am deploying some apis to API Gateway using cdk. My problem is the file that contains the lambda(index.ts) can't import any files or npm modules outside that folder(folder named get-users).

I tried copying node_modules folder and other files (which were outside the folder get-users) to the folder get-users and it worked perfectly.

Example error when importing lodash is as follows,

"errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module 'lodash'",
"stack": [
    "Runtime.ImportModuleError: Error: Cannot find module 'lodash'",

I am importing lodash as follows,

import * as _ from "lodash";

I am importing shared files as follows,

import { validator } from "./shared/validators" // This one works

import { validator } from "../../shared/validators" // This one doesn't work
like image 665
Lasitha Yapa Avatar asked Aug 27 '19 12:08

Lasitha Yapa


People also ask

Can not find module Lambda?

The "Cannot find module" occurs when a lambda function is trying to access a module which is not available in the function's execution runtime. The most common causes for the error are: zipping the wrong files, e.g. zipping a directory instead of the contents of the directory.

How do I add Lambda to CDK?

Steps to create a Lambda Function in AWS CDKStep 1: Instantiate Function Class. Step 2: Add the code for the Lambda Function. Step 3: Adding IAM Permissions for Lambda Function. Step 4: Deploy the Function.

Can Lambda access local files?

You can configure a function to mount an Amazon Elastic File System (Amazon EFS) file system to a local directory. With Amazon EFS, your function code can access and modify shared resources safely and at high concurrency.

How do I resolve the unable to import module error that I receive when I run Lambda code in python?

This is because Lambda isn't prepackaged with all Python libraries. To resolve this error, create a deployment package or Lambda layer that includes the libraries that you want to use in your Python code for Lambda. Important: Make sure that you put the library that you import for Python inside the /python folder.


2 Answers

If your lambda function uses dependencies, you'll have to package everything into a ZIP file and tell CDK where to find the ZIP. It will then upload it for you to S3. But the packaging will be your responsibility. You need to include all the dependencies as well as your code.

CDK currently supports 3 kinds of "Assets":

  • InlineCode - useful for one-line-lambdas
  • AssetCode - one-file lambdas without dependencies
  • S3Code - existing lambda packages already uploaded in an S3 bucket

For your use-case, you'll need AssetCode, but instead of a directory, you'll point to local ZIP file.

Related answer: How to install dependencies of lambda functions upon cdk build with AWS CDK

Since quite a few people ask about this, I'll see if I can open-source my lambda packaging construct in Python. If yes, I'll link it here.

Edit: I opensourced a CDK construct which I use for lambda packaging with more than a hundred dependencies including NumPy.

https://gitlab.com/josef.stach/aws-cdk-lambda-asset

like image 119
0x32e0edfb Avatar answered Oct 22 '22 01:10

0x32e0edfb


After spending some time contemplating the very same issue I finally resorted to using webpack to build my lambda packages, which is definitely the way I would recommend.

What you would do in that case is to point your AssetCode to a directory where Webpack has previously packaged the whole thing e.g. src/your-function/build.

Additional benefit is that you can configure Webpack to minify the files, so you speed up your deployment, but also your lambda cold start.

like image 42
Milan Avatar answered Oct 22 '22 02:10

Milan