NodeJS “Runtime.ImportModuleError”尝试使用层访问AWS lambda函数中的npm包

9w11ddsr  于 2022-11-04  发布在  Node.js
关注(0)|答案(5)|浏览(224)

我想在AWS lambda函数中使用npm包“request”。
我尝试遵循本文中概述的步骤:https://medium.com/@anjanava.biswas/nodejs-runtime-environment-with-aws-lambda-layers-f3914613e20e
我创建了一个如下所示的目录结构:

nodejs
│   package-lock.json
│   package.json
└───node_modules

我的package.json看起来像这样:

{
  "name": "my-package-name",
  "version": "1.0.0",
  "description": "whatever",
  "author": "My Name",
  "license": "MIT",
  "dependencies": {
    "request": "^2.88.0"
  }
}

就我从文章中所了解到的,我应该做的就是运行npm i,压缩目录,将其作为一个层上传,并将该层添加到我的lambda函数中。

我已经完成了所有这些工作,但是当我尝试测试函数时,得到的结果是:

{
  "errorType": "Runtime.ImportModuleError",
  "errorMessage": "Error: Cannot find module 'request'\nRequire stack:\n- /var/task/index.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js",
  "trace": [
    "Runtime.ImportModuleError: Error: Cannot find module 'request'",
    "Require stack:",
    ...

...就好像该层从未被添加过一样。无论是否添加了该层,错误都是完全相同的。如果存在某种需要解决的权限问题,本文中没有任何内容指出这一点。
我尝试了几种不同的方法,比如.zip文件是否包含顶层目录“nodejs”,或者只包含其内容。我尝试将"main": "index.js",添加到package.json中,index.js文件如下所示:

export.modules.request = require('request');

......都无济于事。
我错过了什么?

kadbb459

kadbb4591#

哦,我不敢相信只是这样!
.zip文件的顶层目录必须命名为“nodejs“!我使用了不同的名称,只是在本文中将其改回“nodejs”以更通用,但目录名称沿着是真实的的问题。
叹了口气。

vecaoik1

vecaoik12#

通常情况下,它与文件夹/文件的名称有关。如果这些文件被引用到其他地方,它也会渗透到那里并抱怨。只要彻底检查文件夹结构,你就能抓住小偷。我挣扎了一天才弄明白,这是一个愚蠢的错字。

jyztefdp

jyztefdp3#

对我来说,导致这些问题的原因是有一个版本的package.json仍然在一个旧版本的.build文件夹中,这个文件夹也已经部署好了。一旦我删除了这个文件夹,包就可以按预期安装了。

hfyxw5xn

hfyxw5xn4#

我也得到了这个错误。src.zip文件应该直接有源代码,没有任何父文件夹。
例如,如果你想压缩src文件夹,你需要这样做。

cd src/ && zip -r ../src.zip .
frebpwbc

frebpwbc5#

使用带加密密钥(KMS)和环境变量的lambda函数访问RDS中的表数据
**步骤1:-**首先在KMS(密钥管理服务(KMS))中启用密钥x1c 0d1xx 1c 1d 1xx 1c 2d 1xx 1c 3d 1x

查看您的关键策略,并通过KMS创建完成!

{
"Id": "key-consolepolicy-3",
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "Enable IAM User Permissions",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::163806924483:root"
        },
        "Action": "kms:*",
        "Resource": "*"
    },
    {
        "Sid": "Allow access for Key Administrators",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::163806924483:user/User1@gmail.com"
        },
        "Action": [
            "kms:Create*",
            "kms:Describe*",
            "kms:Enable*",
            "kms:List*",
            "kms:Put*",
            "kms:Update*",
            "kms:Revoke*",
            "kms:Disable*",
            "kms:Get*",
            "kms:Delete*",
            "kms:TagResource",
            "kms:UntagResource",
            "kms:ScheduleKeyDeletion",
            "kms:CancelKeyDeletion"
        ],
        "Resource": "*"
    },
    {
        "Sid": "Allow use of the key",
        "Effect": "Allow",
        "Principal": {
            "AWS": [
                "arn:aws:iam::163806924483:user/User1@gmail.com",
                "arn:aws:iam::163806924483:user/User2@gmail.com",
                "arn:aws:iam::163806924483:user/User3@gmail.com"
            ]
        },
        "Action": [
            "kms:Encrypt",
            "kms:Decrypt",
            "kms:ReEncrypt*",
            "kms:GenerateDataKey*",
            "kms:DescribeKey"
        ],
        "Resource": "*"
    },
    {
        "Sid": "Allow attachment of persistent resources",
        "Effect": "Allow",
        "Principal": {
            "AWS": [
                "arn:aws:iam::163806924483:user/User1.dilip@gmail.com",
                "arn:aws:iam::163806924483:user/User2@gmail.com",
                "arn:aws:iam::163806924483:user/User3@gmail.com"
            ]
        },
        "Action": [
            "kms:CreateGrant",
            "kms:ListGrants",
            "kms:RevokeGrant"
        ],
        "Resource": "*",
        "Condition": {
            "Bool": {
                "kms:GrantIsForAWSResource": "true"
            }
        }
    }
]
}

x1c4d 1x指令集

步骤:- 2在IAM中为KMS创建策略并将每个lambda函数分配给您

"StringEquals": {
            "kms:EncryptionContext:LambdaFunctionName": [
                "LambdaFunction-1",
                "LambdaFunction-2",
                "LambdaFunction-3"
            ]
        }

**步骤3:-**将在步骤2中创建的策略分配给默认lambda角色(需要创建第一个Lambda以获取默认lambda角色)

**步骤4:-**创建lambda函数
Node.jslambda函数的代码

const mysql = require('mysql');
const aws = require("aws-sdk");

const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
let res;
let response={};
exports.handler = async(event) => {
reset_globals();

// load env variables
const rds_user = await kms_decrypt(process.env.RDS_USERNAME);
const rds_pwd = await kms_decrypt(process.env.RDS_PASSWORD)

// setup rds connection
var db_connection = await mysql.createConnection({
    host: process.env.RDS_HOSTNAME,
    user: rds_user,
    password: rds_pwd,
    port: process.env.RDS_PORT,
    database: process.env.RDS_DATABASE
});

var sqlQuery = `SELECT doc_id from documents`;
await getValues(db_connection,sqlQuery);

}

async function getValues(db_connection,sql) {
await new Promise((resolve, reject) => {
    db_connection.query(sql, function (err, result) {
        if (err) {
            response = {statusCode: 500, body:{message:"Database Connection Failed", 
             error: err}};
            console.log(response);
            resolve();
        }
        else {

            console.log("Number of records retrieved: " + JSON.stringify(result));
            res = result;

            resolve();
        }
    });
    });
}

async function kms_decrypt(encrypted) {
const kms = new aws.KMS();
const req = { CiphertextBlob: Buffer.from(encrypted, 'base64'), EncryptionContext: { 
LambdaFunctionName: functionName } };
const decrypted = await kms.decrypt(req).promise();
let cred = decrypted.Plaintext.toString('ascii');
return cred;
}

function reset_globals() {
res = (function () { return; })();
response = {};
}

现在,您应该在Lambda.

中看到KMS

**步骤5:-**设置环境变量并对其进行加密。

Lambda -〉函数-〉配置-〉环境变量-〉编辑
RDS_数据库文档
主机docrds-library.c1k3kcldebmp.us-east-1.rds.amazonaws.com
RDS_密码根目录123
RDS端口3306
RDS_用户名管理员


指令集
在Lambda函数中,使用以下代码解密加密的环境变量

function kms_decrypt(encrypted) {
const kms = new aws.KMS();
const req = { CiphertextBlob: Buffer.from(encrypted, 'base64'), EncryptionContext: { 
LambdaFunctionName: functionName } };
const decrypted = await kms.decrypt(req).promise();
let cred = decrypted.Plaintext.toString('ascii');
return cred;
}

我的RDS文档表如下所示:-


指令集
我正在lambda函数中使用sqlQuery访问doc_id列

var sqlQuery = `SELECT doc_id from documents`;

在测试lambda函数后,我得到了下面的输出。


文件
如果u得到SQL导入错误,那么可以必须添加一个层。

errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module 'mysql'\nRequire stack:\n- 
/var/task/index.js\n- /var/runtime/UserFunction.js\n- /var/runtime/index.js",
 "trace": [
"Runtime.ImportModuleError: Error: Cannot find module 'mysql'",

您可以将Lambda函数配置为使用层形式的附加代码和内容。层是包含库、自定义运行时或其他依赖项的ZIP归档文件。通过层,您可以在函数中使用库,而无需将它们包含在部署包中。
若要在层中包含库,请将它们放置在与您得编程语言对应得目录结构中.
节点. js-节点js/节点模块
Python-Python
Ruby-Ruby/宝石/2.5.0
Java - java/程式库
首先创建一个包含mysql archieve的zip archieve。
首先创建一个React项目
然后在终端$project-path〉npm init中
然后$project-path〉npm安装MySQL
您应该看到已创建node_modules文件夹。
压缩文件夹中的node_modules并上传到层上,如下所示。
然后,后藤Lambda--〉层--〉创建层。
第一次
第14天

相关问题