Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda Layer - Typescript - Runtime.ImportModuleError

hope you are doing well. I am having an issue with employing lambda layers on a lambda that I have set up. I have tried 6 ways to Sunday to get this right, but have not been able to get anything working.

I can tell this is a fairly typical error, because I've encountered a number of articles on here, google etc.. about it. Regardless, there is something that is escaping me because despite how I apply those solutions, they are not working.

Please note, I am using Windows.

The error I am encountering is,

{
    "errorType": "Runtime.ImportModuleError",
    "errorMessage": "Error: Cannot find module 'aws-sdk'\nRequire stack:\n- /var/task/index.js\n- /var/runtime/index.mjs",
    "stack": [
        "Runtime.ImportModuleError: Error: Cannot find module 'aws-sdk'",
        "Require stack:",
        "- /var/task/index.js",
        "- /var/runtime/index.mjs",
        "    at _loadUserApp (file:///var/runtime/index.mjs:1061:17)",
        "    at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1093:21)",
        "    at async start (file:///var/runtime/index.mjs:1256:23)",
        "    at async file:///var/runtime/index.mjs:1262:1"
    ]
}

The lambda code, though I don't think it will help is below:

var AWS = require('aws-sdk');
AWS.config.update({region: 'US-East-1'})
var DynamoDBObject = new AWS.DynamoDB({apiVersion: '2012-08-10'})

exports.main = async function(event, context){
    console.log(event['Details']['ContactData']['CustomerEndpoint']['Address'])
    const numberNumber = parseInt(event['Details']['ContactData']['CustomerEndpoint']['Address'].replace("+1",""))

    console.log("I\'m working! Look at me: ", numberNumber)

    var params = {
        TableName: '{MyTableName}',
        Item: {
            'PhoneNumber': numberNumber
        }
    }
    DynamoDBObject.putItem(params, function(error, data){
        if(error){
            console.log("Error: ", error)
        } else {
            console.log("Success: ", data)
        }
    })
}

The architecture/deployment of the lambda and the information about the layer (which I set up manually in the console) is here:


import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as s3 from "aws-cdk-lib/aws-s3";
import path from "path";

export class LambdaService extends Construct {
    constructor(scope: Construct, id: string){
        super(scope, id);

        //comment

        const codeContainer = new s3.Bucket(this, "LambdaContainer")

        const lambdaLayer = lambda.LayerVersion.fromLayerVersionArn(this, "mylambdalayer", "{LayerARN}")

        new lambda.Function(this, "PhoneNumberInsert2", {
            code: lambda.Code.fromAsset(path.join(__dirname,"../../Lambdas")),
            runtime: lambda.Runtime.NODEJS_18_X,
            handler: "index.main",
            logRetention: 1,
            description: "Lambda that enters a new phone number into DynamoDB",
            environment: {
              BUCKET: codeContainer.bucketName
            },
            layers:[lambdaLayer]
          });
    }
}

And lastly, of course, here is the file structure of the layer I configured in AWS.

**'TOP' Directory**: nodejs.zip
**Second Directory**: nodejs (why is it that when you zip, it adds this directory on top?)
**Third Directory Layer**:
 1. Directory: 'node_modules'
 2. File: package.json
 3. File: package-lock.json

Any help would be greatly appreciated. Wishing you a great day!

like image 672
Steve Avatar asked Sep 08 '26 18:09

Steve


1 Answers

If you're running node18 or higher, the lambda runtime doesn't contain the aws-sdk anymore by default, it has @aws-sdk modules instead. If this is the case, you have a couple of options:

  1. downgrade to nodejs16.x. Caveat: nodejs16.x has a deprecation date of Jun 12, 2024
  2. Refactor your lambda to use the new version of @aws-sdk. This is the proposed solution, if you don't have a lot of legacy refactoring to do.
  3. Create an additional layer, which has the aws-sdk inside it, and then when you include both your layers you have aws-sdk available for import again. The caveat here is, that the additional layer increases the package size of your individual lambdas.
like image 160
JSir Avatar answered Sep 11 '26 06:09

JSir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!