使用 Node.js Lambda 函数的层 - AWS Lambda

使用 Node.js Lambda 函数的层

Lambda 层是包含补充代码或数据的 .zip 文件存档。层通常包含库依赖项、自定义运行时系统或配置文件。创建层涉及三个常见步骤:

  1. 打包层内容。此步骤需要创建 .zip 文件存档,其中包含要在函数中使用的依赖项。

  2. 在 Lambda 中创建层。

  3. 将层添加到函数。

本主题包含有关如何正确打包并创建具有外部库依赖项的 Node.js Lambda 层的步骤和指南。

先决条件

要完成本部分中的步骤,您必须满足以下条件:

在本主题中,我们引用了 aws-lambda-developer-guide GitHub 存储库中的 layer-nodejs 示例应用程序。该应用程序包含用于下载依赖项并将其打包到层中的脚本。该应用程序还包含相应的函数,函数使用来自层的依赖项。创建层后,即可部署并调用相应的函数来验证一切是否正常运行。该示例应用程序使用 Node.js 20 运行时。如果您在层中添加其他依赖项,则它们必须与 Node.js 20 兼容。

layer-nodejs 示例应用程序会将 lodash 库打包到 Lambda 层中。layer 目录包含用于生成层的脚本。function 目录包含示例函数,用于帮助测试该层是否正常工作。本文档将演示如何创建、打包、部署并测试该层。

Node.js 层与 Lambda 运行时环境的兼容性

在 Node.js 层中打包代码时,需要指定与该代码兼容的 Lambda 运行时环境。要评测代码与运行时的兼容性,请考虑代码是为哪些版本的 Node.js、操作系统和指令集架构设计的。

Lambda Node.js 运行时指定其 Node.js 版本和操作系统。在本文档中,您将使用基于 AL2023 的 Node.js 20 运行时。有关运行时版本的更多信息,请参阅支持的运行时。在创建 Lambda 函数时,您可以指定指令集架构。在本文档中,您将使用 arm64 架构。有关 Lambda 中的架构的更多信息,请参阅为 Lambda 函数选择和配置指令集架构

如果您使用软件包中提供的代码,每个软件包维护者都会独立定义其兼容性。大多数 Node.js 开发都是为了独立于操作系统和指令集架构而设计。此外,打破与新 Node.js 版本的不兼容性的情况并不常见。与评测软件包与 Node.js 版本、操作系统或指令集架构的兼容性相比,应该花更多的时间来评测软件包之间的兼容性。

有时,Node.js 包包含编译后的代码,这需要您考虑操作系统和指令集架构的兼容性。如果您确实需要评测软件包的代码兼容性,则需要检查软件包及其文档。NPM 中的软件包可以通过 package.json 清单文件的 enginesoscpu 字段来指定其兼容性。有关 package.json 文件的更多信息,请参阅 NPM 文档中的 package.json

Node.js 运行时的层路径

当您向函数添加层时,Lambda 会将层内容加载到执行环境中。如果您的层将依赖项打包到特定的文件夹路径中,Node.js 执行环境将识别这些模块,并且您可以从函数代码中引用这些模块。

为确保您的模块被拾取,请使用以下文件夹路径之一,将它们打包到层 .zip 文件中。这些文件存储在 /opt 中,并将文件夹路径加载到 PATH 环境变量中。

  • nodejs/node_modules

  • nodejs/nodeX/node_modules

例如,您在本教程中创建生成的层.zip 文件具有以下目录结构:

layer_content.zip └ nodejs └ node20 └ node_modules └ lodash └ <other potential dependencies> └ ...

您将把 lodash 库放在 nodejs/node20/node_modules 目录中。这可确保 Lambda 在函数调用期间可以找到该库。

打包层内容

在本示例中,您要将 lodash 库打包在一个层 .zip 文件中。完成以下步骤,安装并打包层内容。

安装并打包层内容
  1. 克隆 GitHub 存储库中的 aws-lambda-developer-guide,其中包含 sample-apps/layer-nodejs 目录中需要的示例代码。

    git clone https://github.com/awsdocs/aws-lambda-developer-guide.git
  2. 导航到 layer-nodejs 示例应用程序的 layer 目录。此目录包含用于正确创建并打包层的脚本。

    cd aws-lambda-developer-guide/sample-apps/layer-nodejs/layer
  3. 确保 package.json 文件列出 lodash。此文件定义了要包含在层中的依赖项。您可以更新此文件,纳入要包含在层中的任何依赖项。

    注意

    在您的依赖项上传到 Lambda 层后,此步骤中使用的 package.json 不会存储起来,也不会与依赖项一起使用。它仅在层打包过程中使用,不像 Node.js 应用程序或已发布包中的文件那样指定运行命令和兼容性。

  4. 确保您拥有运行 layer 目录中脚本的 shell 权限。

    chmod 744 1-install.sh && chmod 744 2-package.sh
  5. 使用以下命令运行 1-install.sh 脚本:

    ./1-install.sh

    此脚本将运行 npm install,它会读取您的 package.json 并下载其中定义的依赖项。

    例 1-install.sh
    npm install .
  6. 使用以下命令运行 2-package.sh 脚本:

    ./2-package.sh

    此脚本将内容从 node_modules 目录复制到名为 nodejs/node20 的新目录中,随后将 nodejs 目录的内容压缩到一个名为 layer_content.zip 的文件中。这便是层的 .zip 文件。您可以解压缩文件,验证是否包含正确的文件结构,如 Node.js 运行时的层路径部分所示。

    例 2-package.sh
    mkdir -p nodejs/node20 cp -r node_modules nodejs/node20/ zip -r layer_content.zip nodejs

创建层

获取在上一部分中生成的 layer_content.zip 文件,将其作为 Lambda 层上传。您可以使用 AWS Management Console 上传层,也可以通过 AWS Command Line Interface(AWS CLI)使用 Lambda API 上传层。上传层 .zip 文件时,在以下 PublishLayerVersion AWS CLI 命令中,将 nodejs20.x 指定为兼容的运行时系统,并将 arm64 指定为兼容的架构。

aws lambda publish-layer-version --layer-name node-lodash-layer \ --zip-file fileb://layer_content.zip \ --compatible-runtimes nodejs20.x \ --compatible-architectures "arm64"

注意响应中的 LayerVersionArn,与 arn:aws:lambda:us-east-1:123456789012:layer:node-lodash-layer:1 类似。在本教程的下一步中,在将层添加到函数时,您要用到此 Amazon 资源名称(ARN)。

将层添加到函数

部署在函数代码中使用 lodash 库的示例 Lambda 函数,然后附加创建的层。要部署该函数,您需要一个执行角色。有关更多信息,请参阅 使用执行角色定义 Lambda 函数权限。如果目前没有执行角色,则按照可折叠部分中的步骤操作。若有,则跳至下一部分来部署函数。

创建执行角色
  1. 在 IAM 控制台中,打开 Roles(角色)页面

  2. 选择创建角色

  3. 创建具有以下属性的角色。

    • Trusted entity(可信任的实体)– Lambda

    • Permissions(权限)– AWSLambdaBasicExecutionRole

    • Role name(角色名称)– lambda-role

    AWSLambdaBasicExecutionRole 策略具有函数将日志写入 CloudWatch Logs 所需的权限。

示例函数代码使用 lodash _.findLastIndex 方法来读取对象数组。它将对象与标准进行比较,以找到匹配项的索引。然后,它会返回 Lambda 响应中对象的索引和值。

import _ from "lodash" export const handler = async (event) => { var users = [ { 'user': 'Carlos', 'active': true }, { 'user': 'Gil-dong', 'active': false }, { 'user': 'Pat', 'active': false } ]; let out = _.findLastIndex(users, function(o) { return o.user == 'Pat'; }); const response = { statusCode: 200, body: JSON.stringify(out + ", " + users[out].user), }; return response; };
部署 Lambda 函数
  1. 导航到 function/ 目录。如果当前在 layer/ 目录中,请运行以下命令:

    cd ../function-js
  2. 使用以下命令创建 .zip 文件部署包:

    zip my_deployment_package.zip index.mjs
  3. 部署函数。在以下 AWS CLI 命令中,将 --role 参数替换为执行角色 ARN:

    aws lambda create-function --function-name nodejs_function_with_layer \ --runtime nodejs20.x \ --architectures "arm64" \ --handler index.handler \ --role arn:aws:iam::123456789012:role/lambda-role \ --zip-file fileb://my_deployment_package.zip
  4. 将层附加到函数。在以下 AWS CLI 命令中,将 --layers 参数替换为之前记下的层版本 ARN:

    aws lambda update-function-configuration --function-name nodejs_function_with_layer \ --cli-binary-format raw-in-base64-out \ --layers "arn:aws:lambda:us-east-1:123456789012:layer:nodejs-lodash-layer:1"
  5. 调用函数,使用以下 AWS CLI 命令验证它是否可以正常工作:

    aws lambda invoke --function-name nodejs_function_with_layer \ --cli-binary-format raw-in-base64-out \ --payload '{}' response.json

    应看到类似如下内容的输出:

    { "StatusCode": 200, "ExecutedVersion": "$LATEST" }

    输出 response.json 文件包含有关响应的详细信息。

除非您想要保留为本教程创建的资源,否则可立即将其删除。通过删除您不再使用的 AWS 资源,可防止您的 AWS 账户 产生不必要的费用。

删除 Lambda 层
  1. 打开 Lambda 控制台的 Layers page(层页面)。

  2. 选择您创建的层。

  3. 选择删除,然后再次选择删除

删除 Lambda 函数
  1. 打开 Lamba 控制台的 Functions(函数)页面

  2. 选择您创建的函数。

  3. 依次选择操作删除

  4. 在文本输入字段中键入 delete,然后选择 Delete(删除)。