

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在中构建 Lambda 图层 AWS SAM
<a name="building-layers"></a>



您可以使用 AWS SAM 来构建自定义 Lambda 层。Lambda 层允许您从 Lambda 函数中提取代码，然后可以在多个 Lambda 函数中重复使用这些代码。仅构建 Lambda 层（而不是构建整个应用程序）可以在几个方面使您受益。它可以帮助您缩小部署包的大小，将核心函数逻辑与依赖项分开，并允许您在多个函数之间共享依赖项。有关层的信息，请参阅*《AWS Lambda 开发人员指南》*中的 [AWS Lambda 层](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html)。

## 如何在中构建 Lambda 层 AWS SAM
<a name="w2aac18c23c19c34b7"></a>

**注意**  
在构建 Lambda 层之前，必须先在模板中写一个 Lambda 层。 AWS SAM 有关执行此操作的信息和示例，请参阅[使用带有 Lambda 层的 Lambda 层来提高效率 AWS SAM](serverless-sam-cli-layers.md)。

要构建自定义层，请在您的 AWS Serverless Application Model (AWS SAM) 模板文件中对其进行声明，并在`Metadata`资源属性部分中`BuildMethod`加入一个条目。`BuildMethod` 的有效值是 [AWS Lambda 运行时系统](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html)或 `makefile` 的标识符。纳入一个 `BuildArchitecture` 条目以指定您的层支持的指令集架构。`BuildArchitecture` 的有效值是 [Lambda 指令集架构](https://docs.aws.amazon.com/lambda/latest/dg/foundation-arch.html)。

如果指定 `makefile`，请提供自定义 makefile，在其中声明包含层构建命令的表单 `build-layer-logical-id` 的构建目标。如有必要，您的 makefile 负责编译层，并将构建构件复制到工作流程中后续步骤所需的适当位置。Makefile 的位置由层资源的 `ContentUri` 属性指定，并且必须命名为 `Makefile`。

**注意**  
创建自定义图层时，需要 AWS Lambda 依靠环境变量来查找图层代码。Lambda 运行时系统包含将您的层代码复制到的 `/opt` 目录中的路径。项目的构建构件文件夹结构必须与运行时系统的预期文件夹结构相匹配，这样才能找到自定义层代码。  
例如，对于 Python，您可以将代码放在 `python/` 子目录中。对于 NodeJS，您可以将代码放在 `nodejs/node_modules/` 子目录中。  
有关更多信息，请参阅*《AWS Lambda 开发人员指南》*中的[在层中包括库依赖项](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-path)。

以下是 `Metadata` 资源属性部分的示例。

```
    Metadata:
      BuildMethod: python3.12
      BuildArchitecture: arm64
```

**注意**  
如果您不包括`Metadata`资源属性部分，则 AWS SAM 不构建图层。相反，它会从层资源 `CodeUri` 属性中指定的位置复制构建构件。有关更多信息，请参阅 `AWS::Serverless::LayerVersion` 资源类型中 [ContentUri](sam-resource-layerversion.md#sam-layerversion-contenturi) 属性。

当包含`Metadata`资源属性部分时，您可以使用`sam build`命令来构建层，既可以作为独立对象，也可以作为 AWS Lambda 函数的依赖项。
+ ****作为独立对象。****您可能只想构建层对象，例如，当您在本地测试层的代码更改并且不需要构建整个应用程序时。要独立构建层，请使用 `sam build layer-logical-id` 命令指定层资源。
+ **作为 Lambda 函数的依赖项。**当您在同一 AWS SAM 模板文件的 Lambda 函数的 `Layers` 属性中包含层的逻辑 ID 时，该层就是该 Lambda 函数的依赖项。当该层还包括带有 `BuildMethod` 条目的 `Metadata` 资源属性部分时，您可以通过使用 `sam build` 命令构建整个应用程序或使用 `sam build function-logical-id` 命令指定函数资源来构建该层。

## 示例
<a name="building-applications-examples"></a>

### 模板示例 1：针对 Python 3.12 运行时环境构建一个层
<a name="building-applications-examples-python"></a>

以下示例 AWS SAM 模板基于 Python 3.12 运行时环境构建了一个层。

```
Resources:
  MyLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: my_layer
      CompatibleRuntimes:
        - python3.12
    Metadata:
      BuildMethod: python3.12   # Required to have AWS SAM build this layer
```

### 模板示例 2：使用自定义 makefile 构建层
<a name="building-applications-examples-makefile"></a>

以下示例 AWS SAM 模板使用自定义模板`makefile`来构建图层。

```
Resources:
  MyLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      ContentUri: my_layer
      CompatibleRuntimes:
        - python3.12
    Metadata:
      BuildMethod: makefile
```

以下 `makefile` 包含构建目标和将要执行的命令。请注意，`ContentUri` 属性设置为 `my_layer`，因此 makefile 必须位于 `my_layer` 子目录的根目录中，并且文件名必须为 `Makefile`。另请注意，构建工件被复制到`python/`子目录中，以便 AWS Lambda 能够找到层代码。

```
build-MyLayer:
  mkdir -p "$(ARTIFACTS_DIR)/python"
  cp *.py "$(ARTIFACTS_DIR)/python"
  python -m pip install -r requirements.txt -t "$(ARTIFACTS_DIR)/python"
```

**注意**  
当调用 `makefile` 时，将触发相应目标，并应将构件复制到暴露的环境变量 `$ARTIFACTS_DIR` 中。有关更多信息，请参阅[aws-lambda-builders 中的 GitHub](https://github.com/aws/aws-lambda-builders/blob/develop/aws_lambda_builders/workflows/custom_make/DESIGN.md)。

### sam 构建命令示例
<a name="building-applications-examples-commands"></a>

以下 `sam build` 命令构建包含 `Metadata` 资源属性部分的层。

```
# Build the 'layer-logical-id' resource independently
$ sam build layer-logical-id
            
# Build the 'function-logical-id' resource and layers that this function depends on
$ sam build function-logical-id

# Build the entire application, including the layers that any function depends on
$ sam build
```