Lambda 层是包含补充代码或数据的 .zip 文件存档。层通常包含库依赖项、自定义运行时系统或配置文件。创建层涉及三个常见步骤:
-
打包层内容。此步骤需要创建 .zip 文件存档,其中包含要在函数中使用的依赖项。
-
在 Lambda 中创建层。
-
将层添加到函数。
本主题包含有关如何正确打包并创建具有外部库依赖项的 Ruby Lambda 层的步骤和指南。
先决条件
要完成本部分中的步骤,您必须满足以下条件:
-
Ruby 3.3
与 gem
包安装程序一起分发。
在整个主题中,我们会引用 awsdocs GitHub 存储库中的 layer-ruby
在 layer-ruby
示例应用程序中,您应将 tzinfo
layer/
目录包含用于生成层的脚本。function/
目录包含示例函数,用于帮助测试该层是否正常工作。本教程的大部分内容将演示如何创建并打包该层。
Ruby 层与 Lambda 运行时环境的兼容性
在 Ruby 层中打包代码时,需要指定与该代码兼容的 Lambda 运行时环境。要评测代码与运行时的兼容性,请考虑代码是为哪些版本的 Ruby、操作系统和指令集架构设计的。
Lambda Ruby 运行时指定其 Ruby 版本和操作系统。在本文档中,您将使用基于 AL2023 的 Ruby 3.3 运行时。有关运行时版本的更多信息,请参阅支持的运行时。在创建 Lambda 函数时,您可以指定指令集架构。在本文档中,您将使用 x86_64
架构。有关 Lambda 中的架构的更多信息,请参阅为 Lambda 函数选择和配置指令集架构。
如果您使用软件包中提供的代码,每个软件包维护者都会独立定义其兼容性。大多数 Gem 完全使用 Ruby 编写,并且与任何使用兼容 Ruby 语言版本的运行时兼容。
有时,Gem 会使用名为扩展的 Ruby 功能来编译代码或在安装过程中包含预编译的代码。如果您依赖带有本机扩展的 Gem,则必须评估操作系统和指令集架构的兼容性。要评估 Gem 和 Ruby 运行时之间的兼容性,需要检查 Gem 及其文档。您可以通过检查 Gem 规范中是否定义了 extensions
,来确定 Gem 是否使用扩展。Ruby 通过 RUBY_PLATFORM
全局常量识别其运行的平台。Lambda Ruby 运行时会将平台定义为 aarch64-linux
(在 arm64
架构上运行时),或定义为 x86_64-linux
(在 x86_64
架构上运行时)。无法保证可以检查 Gem 是否与这些平台兼容,但是部分 Gem 通过 platform
Gem 规范属性声明了其支持的平台。
Ruby 运行时的层路径
当您向函数添加层时,Lambda 会将层内容加载到该执行环境的 /opt
目录中。对于每个 Lambda 运行时系统,PATH
变量都包括 /opt
目录中的特定文件夹路径。为确保 Lambda 能够获取层内容,层 .zip 文件应在以下文件夹路径中具有依赖项:
-
ruby/gems/
,其中 x 是运行时上的 Ruby 版本,例如x
3.3.0
。 -
ruby/lib/
本文档使用 ruby/gems/
路径。Lambda 要求此目录的内容与 Bundler 安装目录的结构相对应。将 Gem 依赖项与其他元数据子目录一起存储在层路径的 x
/gems
子目录中。例如,您在本教程中创建生成的层.zip 文件具有以下目录结构:
layer_content.zip
└ ruby
└ gems
└ 3.3.0
└ gems
└ tzinfo-2.0.6
└ <other_dependencies> (i.e. dependencies of the tzinfo package)
└ ...
└ <metadata generated by bundle>
tzinfo
库位于 ruby/gems/3.3.0/
目录中,位置正确。这可确保 Lambda 在函数调用期间可以找到该库。
打包层内容
在此示例中,您要将 Ruby tzinfo
库打包在一个层 .zip 文件中。完成以下步骤,安装并打包层内容。
安装并打包层内容
-
克隆
aws-lambda-developer-guide
GitHub 存储库,其中包含 sample-apps/layer-ruby
目录中需要的示例代码。git clone https://github.com/awsdocs/aws-lambda-developer-guide.git
-
导航到
layer-ruby
示例应用程序的layer
目录。此目录包含用于正确创建并打包层的脚本。cd aws-lambda-developer-guide/sample-apps/layer-ruby/layer
-
检查
Gemfile
。此文件定义了要包含在层中的依赖项,即 tzinfo
库。您可以更新此文件,纳入要包含在层中的任何依赖项。例 Gemfile
source "https://rubygems.org" gem "tzinfo"
-
确保拥有运行这两个脚本的权限。
chmod 744 1-install.sh && chmod 744 2-package.sh
-
使用以下命令运行
1-install.sh
脚本: ./1-install.sh
此脚本将捆绑程序配置为在项目目录中安装依赖项。随后在
vendor/bundle/
目录中安装所有必需的依赖项。例 1-install.sh
bundle config set --local path 'vendor/bundle' bundle install
-
使用以下命令运行
2-package.sh
脚本: ./2-package.sh
此脚本将内容从
vendor/bundle
目录复制到名为ruby
的新目录中,随后将ruby
目录的内容压缩到一个名为layer_content.zip
的文件中。这便是层的 .zip 文件。您可以解压缩文件,验证是否包含正确的文件结构,如 Ruby 运行时的层路径部分所示。例 2-package.sh
mkdir -p ruby/gems/3.3.0 cp -r vendor/bundle/ruby/3.3.0/* ruby/gems/3.3.0/ zip -r layer_content.zip ruby
创建层
在本部分,您会获取在上一部分中生成的 layer_content.zip
文件,将其作为 Lambda 层上传。您可以使用 AWS Management Console 上传层,也可以通过 AWS Command Line Interface(AWS CLI)使用 Lambda API 上传层。上传层 .zip 文件时,在以下 PublishLayerVersion AWS CLI 命令中,将 ruby3.3
指定为兼容的运行时系统,并将 arm64
指定为兼容的架构。
aws lambda publish-layer-version --layer-name ruby-requests-layer \ --zip-file fileb://layer_content.zip \ --compatible-runtimes ruby3.3 \ --compatible-architectures "arm64"
注意响应中的 LayerVersionArn
,与 arn:aws:lambda:us-east-1:
类似。在本教程的下一步中,在将层添加到函数时,您要用到此 Amazon 资源名称(ARN)。123456789012
:layer:ruby-requests-layer:1
将层添加到函数
在本部分,您要部署在函数代码中使用 tzinfo
库的示例 Lambda 函数,然后附加该层。要部署该函数,您需要一个 使用执行角色定义 Lambda 函数权限。如果目前没有执行角色,则按照可折叠部分中的步骤操作。
创建执行角色
-
在 IAM 控制台中,打开 Roles(角色)页面
。 -
选择创建角色。
-
创建具有以下属性的角色。
-
Trusted entity(可信任的实体)– Lambda。
-
Permissions(权限)– AWSLambdaBasicExecutionRole。
-
Role name(角色名称)–
lambda-role
。
AWSLambdaBasicExecutionRole 策略具有函数将日志写入 CloudWatch Logs 所需的权限。
-
Lambda 函数代码tzinfo
库,然后返回状态码和本地化的日期字符串。
require 'json'
require 'tzinfo'
def lambda_handler(event:, context:)
tz = TZInfo::Timezone.get('America/New_York')
{ statusCode: 200, body: tz.to_local(Time.utc(2018, 2, 1, 12, 30, 0)) }
end
部署 Lambda 函数
-
导航到
function/
目录。如果当前在layer/
目录中,请运行以下命令:cd ../function
-
使用以下命令创建 .zip 文件部署包:
zip my_deployment_package.zip lambda_function.rb
-
部署函数。在以下 AWS CLI 命令中,将
--role
参数替换为执行角色 ARN:aws lambda create-function --function-name ruby_function_with_layer \ --runtime ruby3.3 \ --architectures "arm64" \ --handler lambda_function.lambda_handler \ --role
arn:aws:iam::
\ --zip-file fileb://my_deployment_package.zip123456789012
:role/lambda-role -
接下来,将层附加到函数。在以下 AWS CLI 命令中,将
--layers
参数替换为之前记下的层版本 ARN:aws lambda update-function-configuration --function-name ruby_function_with_layer \ --cli-binary-format raw-in-base64-out \ --layers "
arn:aws:lambda:us-east-1:
"123456789012
:layer:ruby-requests-layer:1 -
最后,尝试使用以下 AWS CLI 命令调用函数:
aws lambda invoke --function-name ruby_function_with_layer \ --cli-binary-format raw-in-base64-out \ --payload '{ "key": "value" }' response.json
应看到类似如下内容的输出:
{ "StatusCode": 200, "ExecutedVersion": "$LATEST" }
输出
response.json
文件包含有关响应的详细信息。
除非您想要保留为本教程创建的资源,否则可立即将其删除。通过删除您不再使用的 AWS 资源,可防止您的 AWS 账户 产生不必要的费用。
删除 Lambda 层
-
打开 Lambda 控制台的 Layers page
(层页面)。 -
选择您创建的层。
-
选择删除,然后再次选择删除。
删除 Lambda 函数
-
打开 Lamba 控制台的 Functions(函数)页面
。 -
选择您创建的函数。
-
依次选择操作和删除。
-
在文本输入字段中键入
confirm
,然后选择 Delete(删除)。