

# 使用 .zip 文件归档部署 Ruby Lambda 函数
<a name="ruby-package"></a>

 AWS Lambda 函数的代码包含一个 .rb 文件，其中包含函数的处理程序代码，以及代码所依赖的任何其他依赖项（Gem）。要将此函数部署到 Lambda，您可以使用*部署包*。此包可以是 .zip 文件归档或容器映像。有关在 Ruby 中使用容器映像的更多信息，请参阅[使用容器映像部署 Ruby Lambda 函数](https://docs.aws.amazon.com/lambda/latest/dg/ruby-image.html)。

 要创建 .zip 文件归档格式的部署包，可以使用命令行工具内置的 .zip 文件归档实用工具或任何其他 .zip 文件实用工具（例如 [7zip](https://www.7-zip.org/download.html)）。以下各部分中显示的示例假设您在 Linux 或 macOS 环境中使用命令行 `zip` 工具。要在 Windows 中使用相同命令，您可以安装 [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10)，以获取 Windows 集成版本的 Ubuntu 和 Bash。

 请注意，Lambda 使用 POSIX 文件权限，因此在创建 .zip 文件归档之前，您可能需要[为部署包文件夹设置权限](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-deployment-package-errors/)。

以下部分中的示例命令使用 [Bundler](https://bundler.io/) 实用程序为部署包添加依赖项。要安装 Bundler，请运行以下命令：

```
gem install bundler
```

**Topics**
+ [Ruby 中的依赖项](#ruby-package-runtime-dependencies)
+ [创建不含依赖项的 .zip 部署包](#ruby-package-codeonly)
+ [创建含依赖项的 .zip 部署包](#ruby-package-dependencies)
+ [为依赖项创建 Ruby 层](#ruby-package-dependencies-layers)
+ [使用原生库创建 .zip 部署包](#ruby-package-native)
+ [使用 .zip 文件创建和更新 Ruby Lambda 函数](#ruby-package-create-functions)

## Ruby 中的依赖项
<a name="ruby-package-runtime-dependencies"></a>

对于使用 Ruby 运行时系统的 Lambda 函数，依赖项可以是任何 Ruby Gem。使用 .zip 存档部署函数时，可以使用函数代码或使用 Lambda 层将这些依赖项添加到 .zip 文件中。层是可以包含其他代码或其他内容的单独的 .zip 文件。要了解有关使用 Lambda 层的更多信息，请参阅 [使用层管理 Lambda 依赖项](chapter-layers.md)。

Ruby 运行时包括 适用于 Ruby 的 AWS SDK。如果您的函数使用开发工具包，则无需将其与代码捆绑。不过，如果您希望保持对依赖项的完全控制权或使用特定版本的开发工具包，则可将其添加到函数的部署包中。您可以将开发工具包包含在.zip 文件中，也可以使用 Lambda 层进行添加。.zip 文件或 Lambda 层中的依赖项优先于运行时系统中包含的版本。要查找运行时系统版本中包含哪个版本的 SDK for Ruby，请参阅 [包含运行时的 SDK 版本](lambda-ruby.md#ruby-sdk-included)。

 在 [AWS 责任共担模式](lambda-runtimes.md#runtimes-shared-responsibility)下，您负责管理函数部署包中的所有依赖项。这包括应用更新和安全补丁。要更新函数部署包中的依赖项，请先创建一个新的 .zip 文件，然后将其上传到 Lambda 中。有关更多信息，请参阅 [创建含依赖项的 .zip 部署包](#ruby-package-dependencies) 和 [使用 .zip 文件创建和更新 Ruby Lambda 函数](#ruby-package-create-functions)。

## 创建不含依赖项的 .zip 部署包
<a name="ruby-package-codeonly"></a>

如果您的函数代码没有依赖项，则 .zip 文件仅包含带有函数处理程序代码的 .rb 文件。使用首选 ZIP 实用工具创建一个 .zip 文件，并将 .rb 文件置于根目录中。如果 .rb 文件不在 .zip 文件的根目录下，Lambda 将无法运行代码。

要了解如何部署 .zip 文件以创建新的 Lambda 函数或更新现有函数，请参阅 [使用 .zip 文件创建和更新 Ruby Lambda 函数](#ruby-package-create-functions)。

## 创建含依赖项的 .zip 部署包
<a name="ruby-package-dependencies"></a>

如果函数代码依赖其他 Ruby Gem，您可以使用函数代码将这些依赖项添加到 .zip 文件中，也可以使用 [Lambda 层](chapter-layers.md)进行添加。本部分中的说明旨在向您展示如何将依赖项包含在 .zip 部署包中。有关如何将依赖项包含在层中的说明，请参阅 [为依赖项创建 Ruby 层](#ruby-package-dependencies-layers)。

假设函数代码保存在项目目录下名为 `lambda_function.rb` 的文件中。以下示例 CLI 命令将创建名为 `my_deployment_package.zip` 的 .zip 文件，其中包含函数代码及其依赖项。

**创建部署包**

1. 在项目目录中，创建 `Gemfile` 来指定其中的依赖项。

   ```
   bundle init
   ```

1. 使用首选文本编辑器对 `Gemfile` 进行编辑，从而指定函数的依赖项。例如，要使用 TZInfo Gem，请按照如下所示编辑 `Gemfile`。

   ```
   source "https://rubygems.org"
   gem "tzinfo"
   ```

1. 运行以下命令，将 `Gemfile` 中指定的 Gem 安装到项目目录中。此命令将 `vendor/bundle` 设置为 Gem 的默认安装路径。

   ```
   bundle config set --local path 'vendor/bundle' && bundle install
   ```

   您应该可以看到类似于如下所示的输出内容。

   ```
   Fetching gem metadata from https://rubygems.org/...........
   Resolving dependencies...
   Using bundler 2.4.13
   Fetching tzinfo 2.0.6
   Installing tzinfo 2.0.6
   ...
   ```
**注意**  
稍后想再次全局安装 Gem，请运行以下命令：  

   ```
   bundle config set --local system 'true'
   ```

1. 创建 .zip 文件存档，其中包含带有函数处理程序代码以及您在上一步中安装的依赖项的 `lambda_function.rb` 文件。

   ```
   zip -r my_deployment_package.zip lambda_function.rb vendor
   ```

   您应该可以看到类似于如下所示的输出内容。

   ```
   adding: lambda_function.rb (deflated 37%)
     adding: vendor/ (stored 0%)
     adding: vendor/bundle/ (stored 0%)
     adding: vendor/bundle/ruby/ (stored 0%)
     adding: vendor/bundle/ruby/3.2.0/ (stored 0%)
     adding: vendor/bundle/ruby/3.2.0/build_info/ (stored 0%)
     adding: vendor/bundle/ruby/3.2.0/cache/ (stored 0%)
     adding: vendor/bundle/ruby/3.2.0/cache/aws-eventstream-1.0.1.gem (deflated 36%)
   ...
   ```

## 为依赖项创建 Ruby 层
<a name="ruby-package-dependencies-layers"></a>

要了解如何将您的 Ruby 依赖项打包到 Lambda 层中，请参阅[使用 Ruby Lambda 函数的层](ruby-layers.md)。

## 使用原生库创建 .zip 部署包
<a name="ruby-package-native"></a>

许多常见的 Ruby Gem（例如 `nokogiri`、`nio4r` 和 `mysql`），都包含用 C 语言编写的本机扩展。将包含 C 代码的库添加到部署包时，必须正确构建程序包，确保其与 Lambda 执行环境兼容。

对于生产应用程序，建议您使用 AWS Serverless Application Model（AWS SAM）来构建和部署代码。在 AWS SAM 中，使用 `sam build --use-container` 选项在类似 Lambda 的 Docker 容器中构建函数。要了解有关使用 AWS SAM 来部署函数代码的更多信息，请参阅《AWS SAM 开发人员指南》**中的 [Building applications](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build.html)。

要在不使用 AWS SAM 的情况下创建包含带本机扩展的 Gem 的.zip 部署包，您也可以使用容器将依赖项捆绑到与 Lambda Ruby 运行时系统环境相同的环境中。要完成这些步骤，就必须在生成计算机上安装 Docker。要了解有关安装 Docker 的更多信息，请参阅 [Install Docker Engine](https://docs.docker.com/engine/install/)。

**在 Docker 容器中创建.zip 部署包**

1. 在本地生成计算机上创建文件夹来保存容器。在该文件夹中，创建一个名为 `dockerfile` 的文件，再将以下代码粘贴到该文件中。

   ```
   FROM public.ecr.aws/sam/build-ruby3.2:latest-x86_64
   RUN gem update bundler 
   CMD "/bin/bash"
   ```

1. 在您创建 `dockerfile` 的文件夹中，运行以下命令来创建 Docker 容器。

   ```
   docker build -t awsruby32 .
   ```

1. 导航到项目目录，其中包含带有函数处理程序代码以及指定函数依赖项的 `Gemfile` 的 `.rb` 文件。在该目录中，运行以下命令启动 Lambda Ruby 容器。

------
#### [ Linux/MacOS ]

   ```
   docker run --rm -it -v $PWD:/var/task -w /var/task awsruby32
   ```

**注意**  
在 MacOS 中，您可能会看到一条警告，告知您所请求映像的平台与检测到的主机平台不匹配。请忽略该警告。

------
#### [ Windows PowerShell ]

   ```
   docker run --rm -it -v ${pwd}:var/task -w /var/task awsruby32
   ```

------

   容器启动时，您应该会看到 bash 提示符。

   ```
   bash-4.2#
   ```

1. 配置捆绑实用程序，将 `Gemfile` 中指定的 Gem 安装到本地 `vendor/bundle` 目录中并安装依赖项。

   ```
   bash-4.2# bundle config set --local path 'vendor/bundle' && bundle install
   ```

1. 创建包含函数代码及其依赖项的 .zip 部署包。在此示例中，包含函数处理程序代码的文件名为 `lambda_function.rb`。

   ```
   bash-4.2# zip -r my_deployment_package.zip lambda_function.rb vendor
   ```

1. 退出容器并返回到本地项目目录。

   ```
   bash-4.2# exit
   ```

   现在，您可以使用.zip 文件部署包来创建或更新 Lambda 函数。请参阅 [使用 .zip 文件创建和更新 Ruby Lambda 函数](#ruby-package-create-functions)。

## 使用 .zip 文件创建和更新 Ruby Lambda 函数
<a name="ruby-package-create-functions"></a>

 创建 .zip 部署包后，您可以用其创建新的 Lambda 函数或更新现有的 Lambda 函数。您可以使用 Lambda 控制台、AWS Command Line Interface 和 Lambda API 部署 .zip 程序包。您也可以使用 AWS Serverless Application Model（AWS SAM）和 CloudFormation 创建和更新 Lambda 函数。

Lambda 的 .zip 部署包的最大大小为 250MB（已解压缩）。请注意，此限制适用于您上传的所有文件（包括任何 Lambda 层）的组合大小。

Lambda 运行时需要权限才能读取部署包中的文件。在 Linux 权限八进制表示法中，Lambda 对于不可执行文件（rw-r--r--）需要 644 个权限，对于目录和可执行文件需要 755 个权限（rwxr-xr-x）。

在 Linux 和 MacOS 中，使用 `chmod` 命令更改部署包中文件和目录的文件权限。例如，要为不可执行文件提供正确的权限，请运行以下命令。

```
chmod 644 <filepath>
```

要在 Windows 中更改文件权限，请参阅 Microsoft Windows 文档中的 [Set, View, Change, or Remove Permissions on an Object](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc731667(v=ws.10))。

**注意**  
如果您不向 Lambda 授予访问部署包中目录所需的权限，Lambda 会将这些目录的权限设置为 755（rwxr-xr-x）。

### 使用控制台通过 .zip 文件创建和更新函数
<a name="ruby-package-create-console"></a>

 要创建新函数，必须先在控制台中创建该函数，然后上传您的 .zip 归档。要更新现有函数，请打开函数页面，然后按照相同的步骤添加更新的 .zip 文件。

 如果您的 .zip 文件小于 50MB，则可以通过直接从本地计算机上传该文件来创建或更新函数。对于大于 50MB 的 .zip 文件，必须首先将您的程序包上传到 Amazon S3 存储桶。有关如何使用 AWS 管理控制台 将文件上传到 Amazon S3 存储桶的说明，请参阅 [Amazon S3 入门](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html)。要使用 AWS CLI 上传文件，请参阅《AWS CLI 用户指南**》中的[移动对象](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
您无法更改现有函数的[部署包类型](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-PackageType)（.zip 或容器映像）。例如，您无法将容器映像函数转换为使用 .zip 文件归档。您必须创建新函数。

**创建新函数（控制台）**

1. 打开 Lambda 控制台的[“函数”页面](https://console.aws.amazon.com/lambda/home#/functions)，然后选择**创建函数**。

1. 选择**从头开始创作**。

1. 在**基本信息**中，执行以下操作：

   1. 对于**函数名称**，输入函数的名称。

   1. 对于**运行时系统**，选择要使用的运行时系统。

   1. （可选）对于**架构**，选择要用于函数的指令集架构。默认架构为 x86\$164。确保您的函数的 .zip 部署包与您选择的指令集架构兼容。

1. （可选）在 **Permissions**（权限）下，展开 **Change default execution role**（更改默认执行角色）。您可以创建新的**执行角色**，也可以使用现有角色。

1. 选择 **Create function (创建函数)**。Lambda 使用您选择的运行时系统创建基本“Hello world”函数。

**从本地计算机上传 .zip 归档（控制台）**

1. 在 Lambda 控制台的[“函数”页面](https://console.aws.amazon.com/lambda/home#/functions)中，选择要为其上传 .zip 文件的函数。

1. 选择**代码**选项卡。

1. 在**代码源**窗格中，选择**上传自**。

1. 选择 **.zip 文件**。

1. 要上传 .zip 文件，请执行以下操作：

   1. 选择**上传**，然后在文件选择器中选择您的 .zip 文件。

   1. 选择**打开**。

   1. 选择**保存**。

**从 Amazon S3 存储桶上传 .zip 归档（控制台）**

1. 在 Lambda 控制台的[“函数”页面](https://console.aws.amazon.com/lambda/home#/functions)中，选择要为其上传新 .zip 文件的函数。

1. 选择**代码**选项卡。

1. 在**代码源**窗格中，选择**上传自**。

1. 选择 **Amazon S3 位置**。

1. 粘贴 .zip 文件的 Amazon S3 链接 URL，然后选择**保存**。

### 使用控制台代码编辑器更新 .zip 文件函数
<a name="ruby-package-console-edit"></a>

 对于某些带有 .zip 部署包的函数，您可以使用 Lambda 控制台的内置代码编辑器直接更新函数代码。要使用此功能，函数必须满足以下条件：
+ 函数必须使用一种解释性语言运行时系统（Python、Node.js 或 Ruby）
+ 函数的部署包必须小于 50 MB（未压缩状态）。

带有容器映像部署包的函数的代码不能直接在控制台中编辑。

**要使用控制台代码编辑器更新函数代码。**

1. 打开 Lambda 控制台的[“函数”页面](https://console.aws.amazon.com/lambda/home#/functions)，然后选择函数。

1. 选择**代码**选项卡。

1. 在**代码源**窗格中，选择源代码文件并在集成的代码编辑器中对其进行编辑。

1. 在**部署**部分，选择**部署**以更新函数的代码：  
![\[\]](http://docs.aws.amazon.com/zh_cn/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

### 使用 AWS CLI 通过 .zip 文件创建和更新函数
<a name="ruby-package-create-cli"></a>

 您可以使用 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 创建新函数或使用 .zip 文件更新现有函数。使用 [create-function](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 和 [update-function-code](https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html) 命令部署 .zip 程序包。如果您的 .zip 文件小于 50MB，则可以从本地生成计算机上的文件位置上传 .zip 程序包。对于较大的文件，必须从 Amazon S3 存储桶上传 .zip 程序包。有关如何使用 AWS CLI 将文件上传到 Amazon S3 存储桶的说明，请参阅《AWS CLI 用户指南**》中的[移动对象](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

**注意**  
如果您使用 AWS CLI 从 Amazon S3 存储桶上传 .zip 文件，则该存储桶必须与您的函数位于同一个 AWS 区域 中。

 要通过 AWS CLI 使用 .zip 文件创建新函数，则必须指定以下内容：
+ 函数的名称 (`--function-name`)
+ 函数的运行时系统 (`--runtime`)
+ 函数的[执行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html) (`--role`) 的 Amazon 资源名称（ARN）
+ 函数代码 (`--handler`) 中处理程序方法的名称

 还必须指定 .zip 文件的位置。如果 .zip 文件位于本地生成计算机上的文件夹中，请使用 `--zip-file` 选项指定文件路径，如以下示例命令所示。

```
aws lambda create-function --function-name myFunction \
--runtime ruby3.2 --handler lambda_function.lambda_handler \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--zip-file fileb://myFunction.zip
```

 要指定 .zip 文件在 Amazon S3 存储桶中的位置，请使用 `--code` 选项，如以下示例命令所示。您只需对版本控制对象使用 `S3ObjectVersion` 参数。

```
aws lambda create-function --function-name myFunction \
--runtime ruby3.2 --handler lambda_function.lambda_handler \
--role arn:aws:iam::111122223333:role/service-role/my-lambda-role \
--code S3Bucket=amzn-s3-demo-bucket,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion
```

 要使用 CLI 更新现有函数，请使用 `--function-name` 参数指定函数的名称。您还必须指定要用于更新函数代码的 .zip 文件的位置。如果 .zip 文件位于本地生成计算机上的文件夹中，请使用 `--zip-file` 选项指定文件路径，如以下示例命令所示。

```
aws lambda update-function-code --function-name myFunction \
--zip-file fileb://myFunction.zip
```

 要指定 .zip 文件在 Amazon S3 存储桶中的位置，请使用 `--s3-bucket` 和 `--s3-key` 选项，如以下示例命令所示。您只需对版本控制对象使用 `--s3-object-version` 参数。

```
aws lambda update-function-code --function-name myFunction \
--s3-bucket amzn-s3-demo-bucket --s3-key myFileName.zip --s3-object-version myObject Version
```

### 使用 Lambda API 通过 .zip 文件创建和更新函数
<a name="ruby-package-create-api"></a>

 要使用 .zip 文件归档创建和更新函数，请使用以下 API 操作：
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)
+ [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)

### 使用 AWS SAM 通过 .zip 文件创建和更新函数
<a name="ruby-package-create-sam"></a>

 AWS Serverless Application Model（AWS SAM）是一个工具包，可帮助简化在 AWS 上构建和运行无服务器应用程序的过程。您可以在 YAML 或 JSON 模板中为应用程序定义资源，并使用 AWS SAM 命令行界面（AWS SAM CLI）构建、打包和部署应用程序。当您通过 AWS SAM 模板构建 Lambda 函数时，AWS SAM 会使用您的函数代码和您指定的任何依赖项自动创建 .zip 部署包或容器映像。要了解有关使用 AWS SAM 构建和部署 Lambda 函数的更多信息，请参阅《AWS Serverless Application Model 开发人员指南**》中的 [AWS SAM 入门](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html)。

您可以使用 AWS SAM 创建使用现有 .zip 文件归档的 Lambda 函数。要使用 AWS SAM 创建 Lambda 函数，您可以将 .zip 文件保存在 Amazon S3 存储桶或生成计算机上的本地文件夹中。有关如何使用 AWS CLI 将文件上传到 Amazon S3 存储桶的说明，请参阅《AWS CLI 用户指南**》中的[移动对象](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

 在 AWS SAM 模板中，`AWS::Serverless::Function` 资源将指定 Lambda 函数。在此资源中，设置以下属性以创建使用 .zip 文件归档的函数：
+ `PackageType` – 设置为 `Zip`
+ `CodeUri` – 设置为函数代码的 Amazon S3 URI、本地文件夹的路径或 [FunctionCode](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-functioncode.html) 对象
+ `Runtime` – 设置为您选择的运行时系统

 使用 AWS SAM，如果 .zip 文件大于 50MB，则不需要先将其上传到 Amazon S3 存储桶。AWS SAM 可以从本地生成计算机上的某个位置上传最大允许大小为 250MB（已解压缩）的 .zip 程序包。

 要了解有关在 AWS SAM 中使用 .zip 文件部署函数的更多信息，请参阅《AWS SAM 开发人员指南**》中的 [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)。

### 使用 CloudFormation 通过 .zip 文件创建和更新函数
<a name="ruby-package-create-cfn"></a>

 您可以使用 CloudFormation 创建使用 .zip 文件归档的 Lambda 函数。要从 .zip 文件创建 Lambda 函数，必须先将您的文件上传到 Amazon S3 存储桶。有关如何使用 AWS CLI 将文件上传到 Amazon S3 存储桶的说明，请参阅《AWS CLI 用户指南**》中的[移动对象](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-move)。

在 CloudFormation 模板中，`AWS::Lambda::Function` 资源将指定 Lambda 函数。在此资源中，设置以下属性以创建使用 .zip 文件归档的函数：
+ `PackageType` – 设置为 `Zip`
+ `Code` – 在 `S3Bucket` 和 `S3Key` 字段中输入 Amazon S3 存储桶名称和 .zip 文件名。
+ `Runtime` – 设置为您选择的运行时系统

 CloudFormation 生成的 .zip 文件不能超过 4MB。要了解有关在 CloudFormation 中使用 .zip 文件部署函数的更多信息，请参阅《CloudFormation 用户指南**》中的 [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)。