

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

# 使用构建您的应用程序 AWS SAM
<a name="serverless-building"></a>

将基础设施即代码 (IaC) 添加到 AWS SAM 模板后，就可以开始使用**sam build**命令构建应用程序了。此命令根据应用程序项目目录中的文件（即 AWS SAM 模板文件、应用程序代码以及任何适用的语言特定文件和依赖项）创建构建构件。这些构建工件为您的无服务器应用程序做好准备，以备应用程序开发的后续步骤，例如本地测试和部署到 AWS 云端。测试和部署都使用构建构件作为输入。

您可以使用 **sam build** 来构建整个无服务器应用程序。此外，您可以创建自定义构建，例如具有特定函数、层或自定义运行时的构建。要详细了解您使用 **sam build** 的方式和原因，请参阅本节中的主题。有关使用该 `sam build` 命令的简介，请参见 [搭建简介 AWS SAM](using-sam-cli-build.md)。

**Topics**
+ [搭建简介 AWS SAM](using-sam-cli-build.md)
+ [默认版本使用 AWS SAM](serverless-sam-cli-using-build.md)
+ [使用自定义构建 AWS SAM](building-lambda-functions.md)

# 搭建简介 AWS SAM
<a name="using-sam-cli-build"></a>

使用 AWS Serverless Application Model Command Line Interface (AWS SAMCLI) `sam build` 命令为开发工作流程中的后续步骤做好准备，例如本地测试或部署到。 AWS 云此命令会创建 `.aws-sam` 目录，该目录将以 `sam local` 和 `sam deploy` 所要求的格式和位置来编排应用程序的结构。
+ 有关简介 AWS SAMCLI，请参阅[那是什么 AWS SAMCLI？](what-is-sam-overview.md#what-is-sam-cli)。
+ 有关 `sam build` 命令选项的列表，请参阅 [sam build](sam-cli-command-reference-sam-build.md)。
+ 有关在典型开发工作流程中使用 `sam build` 的示例，请参阅[第 2 步：构建应用程序](serverless-getting-started-hello-world.md#serverless-getting-started-hello-world-build)。

**注意**  
使用 `sam build` 时，您需要从开发计算机上无服务器应用程序的基本组件开始。这包括 AWS SAM 模板、 AWS Lambda 函数代码以及任何特定于语言的文件和依赖关系。要了解更多信息，请参阅[在中创建您的应用程序 AWS SAM](using-sam-cli-init.md)。

**Topics**
+ [使用 sam build 构建应用程序](#using-sam-cli-build-apps)
+ [本地测试和部署](#using-sam-cli-build-test-deploy)
+ [最佳实践](#using-sam-cli-build-best)
+ [sam build 的选项](#using-sam-cli-build-options)
+ [问题排查](#using-sam-cli-build-troubleshooting)
+ [示例](#using-sam-cli-build-examples)
+ [了解详情](#using-sam-cli-build-learn)

## 使用 sam build 构建应用程序
<a name="using-sam-cli-build-apps"></a>

使用 `sam build` 之前，请考虑配置以下各项：

1. **Lambda 函数和层** - `sam build` 命令可以构建 Lambda 函数和层。要了解有关 Lambda 层的更多信息，请参阅 [在中构建 Lambda 图层 AWS SAM](building-layers.md)。

1. **Lambda 运行时** – *运行时*提供在调用时在执行环境中运行函数的语言特定环境。您可以配置本机运行时和自定义运行时。

   1. **本机运行时** - 在受支持的 Lambda 运行时系统中编写 Lambda 函数，并构建函数以在 AWS 云中使用原生 Lambda 运行时。

   1. **自定义运行时** - 使用任何编程语言编写 Lambda 函数，并使用在 makefile 或第三方生成器（例如 esbuild）中定义的自定义流程来构建运行时。要了解更多信息，请参阅[在中使用自定义运行时构建 Lambda 函数 AWS SAM](building-custom-runtimes.md)。

1. **Lambda 包类型** - Lambda 函数可以打包成以下 Lambda 部署包类型：

   1. **.zip 文件归档** – 包括您的应用程序代码及其依赖项。

   1. **容器印象** – 包括基本操作系统、运行时系统、Lambda 扩展、应用程序代码及其依赖项。

可在使用 `sam init` 初始化应用程序时配置这些应用程序设置。
+ 要了解有关使用 `sam init` 的更多信息，请参阅 [在中创建您的应用程序 AWS SAM](using-sam-cli-init.md)。
+ 要了解有关在应用程序中配置这些设置的更多信息，请参阅 [默认版本使用 AWS SAM](serverless-sam-cli-using-build.md)。

**构建应用程序**

1. `cd` 到项目的根目录。此位置与您的 AWS SAM 模板相同。

   ```
   $ cd sam-app
   ```

1. 运行以下命令：

   ```
   sam-app $ sam build <arguments> <options>
   ```
**注意**  
常用选项是 `--use-container`。要了解更多信息，请参阅[在提供的容器内构建 Lambda 函数](#using-sam-cli-build-options-container)。

   下面是 AWS SAM CLI 输出的一个示例：

   ```
   sam-app $ sam build
   Starting Build use cache
   Manifest file is changed (new hash: 3298f1304...d4d421) or dependency folder (.aws-sam/deps/4d3dfad6-a267-47a6-a6cd-e07d6fae318c) is missing for (HelloWorldFunction), downloading dependencies and copying/building source
   Building codeuri: /Users/.../sam-app/hello_world runtime: python3.12 metadata: {} architecture: x86_64 functions: HelloWorldFunction
   Running PythonPipBuilder:CleanUp
   Running PythonPipBuilder:ResolveDependencies
   Running PythonPipBuilder:CopySource
   Running PythonPipBuilder:CopySource
   
   Build Succeeded
   
   Built Artifacts  : .aws-sam/build
   Built Template   : .aws-sam/build/template.yaml
   
   Commands you can use next
   =========================
   [*] Validate SAM template: sam validate
   [*] Invoke Function: sam local invoke
   [*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
   [*] Deploy: sam deploy --guided
   ```

1.  AWS SAM CLI 会创建 `.aws-sam` 构建目录。以下是示例：

   ```
   .aws-sam
   ├── build
   │   ├── HelloWorldFunction
   │   │   ├── __init__.py
   │   │   ├── app.py
   │   │   └── requirements.txt
   │   └── template.yaml
   └── build.toml
   ```

根据应用程序的配置， AWS SAM CLI 会执行以下操作：

1. 在 `.aws-sam/build` 目录中下载、安装和组织依赖项。

1. 准备 Lambda 代码。这可能包括编译代码，创建可执行二进制文件，以及构建容器映像。

1. 将构建构件复制到 `.aws-sam` 目录中。格式因应用程序包类型而异。

   1. 对于 .zip 包类型，构件尚未压缩，因此可用于本地测试。使用 `sam deploy` 时， AWS SAM CLI 会压缩应用程序。

   1. 对于容器映像包类型，容器映像将在本地创建，在 `.aws-sam/build.toml` 文件中被引用。

1. 将 AWS SAM 模板复制到`.aws-sam`目录中，并在必要时使用新的文件路径对其进行修改。

以下是构成 `.aws-sam` 目录中的构建构件的主要组件：
+ **构建目录** - 包含在结构上彼此独立的 Lambda 函数和层。这使得 `.aws-sam/build` 目录中的每个函数或层都有唯一的结构。
+ ** AWS SAM 模板**-根据构建过程中的更改使用更新的值进行修改。
+ **build.toml 文件** — 包含使用的编译设置的配置文件。 AWS SAMCLI

## 本地测试和部署
<a name="using-sam-cli-build-test-deploy"></a>

使用 `sam local` 执行本地测试或使用 `sam deploy` 进行部署时， AWS SAM CLI 会执行以下操作：

1. 它首先检查`.aws-sam`目录是否存在以及 AWS SAM 模板是否位于该目录中。如果满足这些条件， AWS SAM CLI 会将该目录视为应用程序的根目录。

1. 如果不满足这些条件，则 AWS SAMCLI会将 AWS SAM 模板的原始位置视为应用程序的根目录。

开发时，如果对原始应用程序文件进行了更改，请在进行本地测试之前运行 `sam build` 以更新 `.aws-sam` 目录。

## 最佳实践
<a name="using-sam-cli-build-best"></a>
+ 不要编辑 `.aws-sam/build` 目录下的任何代码。而是应更新项目文件夹中的原始源代码，然后运行 `sam build` 以更新 `.aws-sam/build` 目录。
+ 修改原始文件时，运行 `sam build` 以更新 `.aws-sam/build` 目录。
+ 您可能希望 AWS SAM CLI 引用项目的原始根目录而不是 `.aws-sam` 目录，例如，在使用 `sam local` 进行开发和测试时。删除`.aws-sam`目录或`.aws-sam`目录中的 AWS SAM 模板，以便将您的原始项目目录 AWS SAMCLI识别为根项目目录。准备就绪后，再次运行 `sam build` 以创建 `.aws-sam` 目录。
+ 运行 `sam build` 时，`.aws-sam/build` 目录每次都会被覆盖。`.aws-sam` 目录不会被覆盖。如果您想要存储文件（例如日志），请将其存储在 `.aws-sam` 中，以防止它们被覆盖。

## sam build 的选项
<a name="using-sam-cli-build-options"></a>

### 构建单个资源
<a name="using-sam-cli-build-options-resource"></a>

提供资源的逻辑 ID，以仅构建该资源。以下是示例：

```
$ sam build HelloWorldFunction
```

要构建嵌套应用程序或堆栈的资源，请使用格式 `<stack-logical-id>/<resource-logical-id>` 提供应用程序或堆栈逻辑 ID 和资源逻辑 ID：

```
$ sam build MyNestedStack/MyFunction
```

### 在提供的容器内构建 Lambda 函数
<a name="using-sam-cli-build-options-container"></a>

通过 `--use-container` 选项可以下载容器映像，并使用下载的映像来构建 Lambda 函数。然后在 `.aws-sam/build.toml` 文件中引用本地容器。

此选项需要安装 Docker。有关说明，请参阅[安装 Docker](install-docker.md)。

以下是该命令的示例：

```
$ sam build --use-container
```

您可以通过 `--build-image` 选项指定要使用的容器映像。以下是示例：

```
$ sam build --use-container --build-image amazon/aws-sam-cli-build-image-nodejs20.x
```

要指定用于单个函数的容器映像，请提供函数逻辑 ID。以下是示例：

```
$ sam build --use-container --build-image Function1=amazon/aws-sam-cli-build-image-python3.12
```

### 传递环境变量给构建容器
<a name="using-sam-cli-build-options-env"></a>

使用 `--container-env-var` 传递环境变量给构建容器。以下是示例：

```
$ sam build --use-container --container-env-var Function1.GITHUB_TOKEN=<token1> --container-env-var GLOBAL_ENV_VAR=<global-token>
```

要传递文件中的环境变量，请使用 `--container-env-var-file` 选项。以下是示例：

```
$ sam build --use-container --container-env-var-file <env.json>
```

`env.json` 文件示例：

```
{
  "MyFunction1": {
    "GITHUB_TOKEN": "TOKEN1"
  },
  "MyFunction2": {
    "GITHUB_TOKEN": "TOKEN2"
  }
}
```

### 加快构建包含多个函数的应用程序
<a name="using-sam-cli-build-options-speed"></a>

在具有多个函数的应用程序上运行 `sam build` 时， AWS SAM CLI 会逐个构建每个函数。要加快构建过程，请使用 `--parallel` 选项。这样可以同时构建所有函数和层。

以下是该命令的示例：

```
$ sam build —-parallel
```

### 通过在源文件夹中构建项目来加快构建时间
<a name="using-sam-cli-build-options-source"></a>

对于受支持的运行时和构建方法，您可以使用 `--build-in-source` 选项直接在源文件夹中生成项目。默认情况下，在临时目录中 AWS SAM CLI构建，其中包括复制源代码和项目文件。使用`--build-in-source`， AWS SAM CLI可以直接在源文件夹中进行构建，无需将文件复制到临时目录，从而加快构建过程。

有关支持的运行时和构建方法的列表，请参阅 `--build-in-source`。

## 问题排查
<a name="using-sam-cli-build-troubleshooting"></a>

要排除故障 AWS SAMCLI，请参阅[AWS SAM CLI 故障排除](sam-cli-troubleshooting.md)。

## 示例
<a name="using-sam-cli-build-examples"></a>

### 构建使用原生运行时和 .zip 包类型的应用程序
<a name="using-sam-cli-build-examples-tutorial1"></a>

对于本示例，请参阅 [教程：使用以下命令部署 Hello World 应用程序 AWS SAM](serverless-getting-started-hello-world.md)。

### 构建使用原生运行时和映像包类型的应用程序
<a name="using-sam-cli-build-examples-image"></a>

首先，运行 `sam init` 以初始化新的应用程序。在交互式流程中，选择 `Image` 包类型。以下是示例：

```
$ sam init
...
Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        4 - Scheduled task
        5 - Standalone function
        6 - Data processing
        7 - Hello World Example With Powertools
        8 - Infrastructure event management
        9 - Serverless Connector Hello World Example
        10 - Multi-step workflow with Connectors
        11 - Lambda EFS example
        12 - DynamoDB Example
        13 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: ENTER

Which runtime would you like to use?
        ...
        10 - java8
        11 - nodejs20.x
        12 - nodejs18.x
        13 - nodejs16.x
        ...
Runtime: 12

What package type would you like to use?
        1 - Zip
        2 - Image
Package type: 2

Based on your selections, the only dependency manager available is npm.
We will proceed copying the template using npm.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: ENTER

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: ENTER

Project name [sam-app]: ENTER

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Base Image: amazon/nodejs18.x-base
    Architectures: x86_64
    Dependency Manager: npm
    Output Directory: .
    Configuration file: sam-app/samconfig.toml

    Next steps can be found in the README file at sam-app/README.md
    
...
```

初 AWS SAMCLI始化应用程序并创建以下项目目录：

```
sam-app
├── README.md
├── events
│   └── event.json
├── hello-world
│   ├── Dockerfile
│   ├── app.mjs
│   ├── package.json
│   └── tests
│       └── unit
│           └── test-handler.mjs
├── samconfig.toml
└── template.yaml
```

然后，运行 `sam build` 以构建应用程序：

```
sam-app $ sam build
Building codeuri: /Users/.../build-demo/sam-app runtime: None metadata: {'DockerTag': 'nodejs18.x-v1', 'DockerContext': '/Users/.../build-demo/sam-app/hello-world', 'Dockerfile': 'Dockerfile'} architecture: arm64 functions: HelloWorldFunction
Building image for HelloWorldFunction function
Setting DockerBuildArgs: {} for HelloWorldFunction function
Step 1/4 : FROM public.ecr.aws/lambda/nodejs:18
 ---> f5b68038c080
Step 2/4 : COPY app.mjs package*.json ./
 ---> Using cache
 ---> 834e565aae80
Step 3/4 : RUN npm install
 ---> Using cache
 ---> 31c2209dd7b5
Step 4/4 : CMD ["app.lambdaHandler"]
 ---> Using cache
 ---> 2ce2a438e89d
Successfully built 2ce2a438e89d
Successfully tagged helloworldfunction:nodejs18.x-v1

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
```

### 构建包含已编译编程语言的应用程序
<a name="using-sam-cli-build-examples-compiled"></a>

在此示例中，我们使用 Go 运行时构建一个包含 Lambda 函数的应用程序。

首先，使用 `sam init` 初始化新的应用程序，并将应用程序配置为使用 Go：

```
$ sam init

...

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        ...
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: ENTER

Which runtime would you like to use?
        ...
        4 - dotnetcore3.1
        5 - go1.x
        6 - go (provided.al2)
        ...
Runtime: 5

What package type would you like to use?
        1 - Zip
        2 - Image
Package type: 1

Based on your selections, the only dependency manager available is mod.
We will proceed copying the template using mod.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: ENTER

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: ENTER

Project name [sam-app]: ENTER

Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Runtime: go1.x
    Architectures: x86_64
    Dependency Manager: mod
    Application Template: hello-world
    Output Directory: .
    Configuration file: sam-app/samconfig.toml
    
    Next steps can be found in the README file at sam-app-go/README.md
        
...
```

初 AWS SAMCLI始化应用程序。下面是应用程序目录结构的示例：

```
sam-app
├── Makefile
├── README.md
├── events
│   └── event.json
├── hello-world
│   ├── go.mod
│   ├── go.sum
│   ├── main.go
│   └── main_test.go
├── samconfig.toml
└── template.yaml
```

引用 `README.md` 文件以明确此应用程序的要求。

```
...
## Requirements
* AWS CLI already configured with Administrator permission
* [Docker installed](https://www.docker.com/community-edition)
* [Golang](https://golang.org)
* SAM CLI - [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
...
```

然后，运行 `sam local invoke` 以测试函数。由于本地计算机上未安装 Go，此命令出错：

```
sam-app $ sam local invoke
Invoking hello-world (go1.x)
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-go1.x
Building image.................................................................................................................................................................................................................................................
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.

Mounting /Users/.../Playground/build/sam-app/hello-world as /var/task:ro,delegated inside runtime container
START RequestId: c6c5eddf-042b-4e1e-ba66-745f7c86dd31 Version: $LATEST
fork/exec /var/task/hello-world: no such file or directory: PathError
null
END RequestId: c6c5eddf-042b-4e1e-ba66-745f7c86dd31
REPORT RequestId: c6c5eddf-042b-4e1e-ba66-745f7c86dd31  Init Duration: 0.88 ms  Duration: 175.75 ms Billed Duration: 176 ms Memory Size: 128 MB     Max Memory Used: 128 MB
{"errorMessage":"fork/exec /var/task/hello-world: no such file or directory","errorType":"PathError"}%
```

然后，运行 `sam build` 以构建应用程序。由于本地计算机上未安装 Go，我们遇到错误：

```
sam-app $ sam build
Starting Build use cache
Cache is invalid, running build and copying resources for following functions (HelloWorldFunction)
Building codeuri: /Users/.../Playground/build/sam-app/hello-world runtime: go1.x metadata: {} architecture: x86_64 functions: HelloWorldFunction

Build Failed
Error: GoModulesBuilder:Resolver - Path resolution for runtime: go1.x of binary: go was not successful
```

虽然我们可以通过配置本地计算机来正确构建函数，但我们改为将 `--use-container` 选项与 `sam build` 结合使用。 AWS SAMCLI下载容器镜像，使用原生镜像构建我们的函数 GoModulesBuilder，然后将生成的二进制文件复制到我们的`.aws-sam/build/HelloWorldFunction`目录中。

```
sam-app $ sam build --use-container
Starting Build use cache
Starting Build inside a container
Cache is invalid, running build and copying resources for following functions (HelloWorldFunction)
Building codeuri: /Users/.../build/sam-app/hello-world runtime: go1.x metadata: {} architecture: x86_64 functions: HelloWorldFunction

Fetching public.ecr.aws/sam/build-go1.x:latest-x86_64 Docker container image.....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Mounting /Users/.../build/sam-app/hello-world as /tmp/samcli/source:ro,delegated inside runtime container
Running GoModulesBuilder:Build

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
```

以下是 `.aws-sam` 目录的示例：

```
.aws-sam
├── build
│   ├── HelloWorldFunction
│   │   └── hello-world
│   └── template.yaml
├── build.toml
├── cache
│   └── c860d011-4147-4010-addb-2eaa289f4d95
│       └── hello-world
└── deps
```

然后，运行 `sam local invoke`。这样就成功调用了函数：

```
sam-app $ sam local invoke
Invoking hello-world (go1.x)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/go:1-rapid-x86_64.

Mounting /Users/.../Playground/build/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: cfc8ffa8-29f2-49d4-b461-45e8c7c80479 Version: $LATEST
END RequestId: cfc8ffa8-29f2-49d4-b461-45e8c7c80479
REPORT RequestId: cfc8ffa8-29f2-49d4-b461-45e8c7c80479  Init Duration: 1.20 ms  Duration: 1782.46 ms        Billed Duration: 1783 ms        Memory Size: 128 MB     Max Memory Used: 128 MB
{"statusCode":200,"headers":null,"multiValueHeaders":null,"body":"Hello, 72.21.198.67\n"}%
```

## 了解详情
<a name="using-sam-cli-build-learn"></a>

要了解有关使用 `sam build` 命令的更多信息，请参阅以下内容：
+ **[学习 AWS SAM：sam build](https://www.youtube.com/watch?v=fDhYKp4op_g)** — Serverless Land “学习 AWS SAM” 系列开启。YouTube
+ **[学习 AWS SAM \$1 sam build \$1 E3](https://www.youtube.com/watch?v=vsAvRyLnB7Y)** — Serverless Land “学习 AWS SAM” 系列开启。YouTube
+ **[AWS SAM 构建：它如何为部署提供工件（带有 SAM S2E8 的会话）](https://www.youtube.com/watch?v=bNbBd6XoDHg)**— 开启系列的 AWS SAM 会话。YouTube
+ **[AWS SAM 自定义构建：如何使用 Makefile 在 SAM (S2E9) 中自定义构建](https://www.youtube.com/watch?v=wpccutnSbAk)** — 开启系列的会话。 AWS SAM YouTube

# 默认版本使用 AWS SAM
<a name="serverless-sam-cli-using-build"></a>

要构建无服务器应用程序，请使用 `sam build` 命令。此命令还会收集应用程序依赖项的构建构件，并将其以适当的格式和位置放置以供后续步骤（例如本地测试、打包和部署）使用。

您可以在清单文件（例如 `requirements.txt` (Python) 或 `package.json` (Node.js)）中指定应用程序的依赖项，也可以使用函数资源的 `Layers` 属性来指定。`Layers` 属性包含 Lambda 函数所依赖的 [AWS Lambda 层](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html)资源列表。

应用程序构建构件的格式取决于每个函数的 `PackageType` 属性。此属性的选项有：
+ **`Zip`** – .zip 文件归档，包括您的应用程序代码及其依赖项。如果您将代码打包为 .zip 文件存档，则必须为函数指定 Lambda 运行时。
+ **`Image`** – 容器映像，除了应用程序代码及其依赖项之外，还包括基本操作系统、运行时和扩展。

有关 Lambda 包类型的更多信息，请参阅《AWS Lambda 开发人员指南》**中的 [Lambda 部署包](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-package.html)。

**Topics**
+ [创建 .zip 文件存档](#build-zip-archive)
+ [构建容器映像](#build-container-image)
+ [容器环境变量文件](#serverless-sam-cli-using-container-environment-file)
+ [通过在源文件夹中构建项目来加快构建时间](#serverless-sam-cli-using-build-in-source)
+ [示例](#building-applications-examples)
+ [在外部构建函数 AWS SAM](#building-applications-skip)

## 创建 .zip 文件存档
<a name="build-zip-archive"></a>

要将无服务器应用程序构建为 .zip 文件存档，请为无服务器函数声明 `PackageType: Zip`。

AWS SAM 针对您指定的[架构](sam-resource-function.md#sam-function-architectures)构建应用程序。如果您未指定架构，则`x86_64`默认 AWS SAM 使用。

如果 Lambda 函数依赖于具有本地编译程序的包，请使用 `--use-container` 标志。此标志在本地将您的函数编译到一个行为类似于 Lambda 环境的容器中，因此当您将它们部署到云端时，它们的格式是正确的。 AWS 

当您使用该`--use-container`选项时，默认情况下会从 [Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/public/what-is-ecr.html) Public 中 AWS SAM 提取容器映像。如果您想从其他存储库或特定版本的 AWS SAM CLI 中提取容器映像，则可以使用`--build-image`选项并提供备用容器镜像的 URI。以下是使用来自特定版本的 AWS SAM CLI 的容器镜像构建应用程序的两个示例命令：

```
# Build a Node.js 20 application using a container image for a specific version of AWS SAM CLI (1.136.0)
sam build --use-container --build-image public.ecr.aws/sam/build-nodejs22.x:1.136.0

# Build a function resource using the Python 3.13 container image from a specific version of AWS SAM CLI (1.136.0)(
sam build --use-container --build-image Function1=public.ecr.aws/sam/build-python3.13:1.136.0
```

有关构建 .zip 文件存档应用程序的其他示例，请参阅本主题后面的“示例”部分。

## 构建容器映像
<a name="build-container-image"></a>

要将无服务器应用程序构建为容器映像，请为无服务器函数声明 `PackageType: Image`。您还必须使用以下条目声明 `Metadata` 资源属性：

`Dockerfile`  
与 Lambda 函数关联的 Dockerfile 的名称。

`DockerContext`  
Dockerfile 的位置。

`DockerTag`  
（可选）应用于已构建映像的标签。

`DockerBuildArgs`  
为构建设置参数。  
 AWS SAMCLI 不会对包含在 `DockerBuildArgs` 参数中的任何信息进行编辑或模糊处理。我们强烈建议您不要使用此部分存储敏感信息，例如密码或密钥。

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

```
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./hello_world
      DockerTag: v1
```

要下载配置了 `Image` 软件包类型的示例应用程序，请参阅[教程：使用以下命令部署 Hello World 应用程序 AWS SAM](serverless-getting-started-hello-world.md)。当系统提示您要安装哪种软件包类型时，选择 `Image`。

**注意**  
如果您在 Dockerfile 中指定了多架构基础镜像，则需要为主机的架构 AWS SAM 构建容器镜像。要针对不同的架构进行构建，请指定使用特定目标架构的基础映像。

## 容器环境变量文件
<a name="serverless-sam-cli-using-container-environment-file"></a>

要为构建容器提供包含环境变量的 JSON 文件，请在 `sam build` 命令中使用 `--container-env-var-file` 参数。您可以提供适用于所有无服务器资源的单个环境变量，也可以为每种资源提供不同的环境变量。

### Format
<a name="serverless-sam-cli-using-container-environment-file-format"></a>

向构建容器传递环境变量的格式取决于您为资源提供的环境变量的数量。

要为所有资源提供单个环境变量，请指定如下所示的 `Parameters` 对象：

```
{
  "Parameters": {
    "GITHUB_TOKEN": "TOKEN_GLOBAL"
  }
}
```

要为每种资源提供不同的环境变量，请如下所示为每种资源指定对象：

```
{
  "MyFunction1": {
    "GITHUB_TOKEN": "TOKEN1"
  },
  "MyFunction2": {
    "GITHUB_TOKEN": "TOKEN2"
  }
}
```

将您的环境变量另存为文件，例如名为 `env.json`。以下命令使用此文件将环境变量传递到构建容器：

```
sam build --use-container --container-env-var-file env.json
```

### 优先级
<a name="serverless-sam-cli-using-container-environment-file-precedence"></a>
+ 您为特定资源提供的环境变量优先于所有资源的单个环境变量。
+ 您在命令行中提供的环境变量优先于文件中的环境变量。

## 通过在源文件夹中构建项目来加快构建时间
<a name="serverless-sam-cli-using-build-in-source"></a>

对于受支持的运行时和构建方法，您可以使用 `--build-in-source` 选项直接在源文件夹中生成项目。默认情况下，在临时目录中 AWS SAM CLI构建，其中包括复制源代码和项目文件。使用`--build-in-source`， AWS SAM CLI可以直接在源文件夹中进行构建，无需将文件复制到临时目录，从而加快构建过程。

有关支持的运行时和构建方法的列表，请参阅 `--build-in-source`。

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

### 示例 1：.zip 文件存档
<a name="examples-zip-archives"></a>

以下 `sam build` 命令可创建 .zip 文件存档：

```
# Build all functions and layers, and their dependencies
sam build

# Run the build process inside a Docker container that functions like a Lambda environment
sam build --use-container

# Build a Node.js 20 application using a container image for a specific version of AWS SAM CLI (1.136.0)
sam build --use-container --build-image public.ecr.aws/sam/build-nodejs22.x:1.136.0

# Build a function resource using the Python 3.13 container image from a specific version of AWS SAM CLI (1.136.0)(
sam build --use-container --build-image Function1=public.ecr.aws/sam/build-python3.13:1.136.0

# Build and run your functions locally
sam build && sam local invoke

# For more options
sam build --help
```

### 示例 2：容器映像
<a name="examples-container-image-1"></a>

以下 AWS SAM 模板以容器镜像的形式构建：

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      ImageConfig:
        Command: ["app.lambda_handler"]
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: ./hello_world
      DockerTag: v1
```

以下是 Dockerfile 的示例：

```
FROM public.ecr.aws/lambda/python:3.12

COPY app.py requirements.txt ./

RUN python3.12 -m pip install -r requirements.txt

# Overwrite the command by providing a different command directly in the template.
CMD ["app.lambda_handler"]
```

### 示例 3：npm ci
<a name="examples-npm-ci"></a>

对于 Node.js 应用程序，您可以使用 `npm ci` 代替 `npm install` 来安装依赖项。要使用 `npm ci`，请在 Lambda 函数的 `Metadata` 资源属性中的 `BuildProperties` 下指定 `UseNpmCi: True`。要使用 `npm ci`，您的应用程序必须在 Lambda 函数的 `CodeUri` 中存在 `package-lock.json` 或 `npm-shrinkwrap.json` 文件。

以下示例使用 `npm ci` 在运行 `sam build` 时安装依赖项：

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.handler
      Runtime: nodejs20.x
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
    Metadata:
      BuildProperties:
        UseNpmCi: True
```

### Python 父软件包
<a name="building-applications-python-parent-packages"></a>

对于 Python 应用程序，您可以在构建过程中保留软件包结构，从而启用绝对导入。保留软件包结构，请在您 Lambda 函数的 `Metadata` 资源属性的 `BuildProperties` 下指定 `ParentPackageMode`。

以下示例在您运行 `sam build` 时保留 `app` 软件包结构：

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.main.handler
      Runtime: python3.12
      Architectures:
        - x86_64
    Metadata:
      BuildProperties:
        ParentPackageMode: explicit
        ParentPackages: app
```

通过此配置，您的代码可以使用 `from app.utils import logger` 这样的绝对导入，而非 `from .utils import logger` 这样的相对导入。

## 在外部构建函数 AWS SAM
<a name="building-applications-skip"></a>

默认情况下，当您运行时**sam build**， AWS SAM 会生成所有函数资源。其他选项包括：
+ **在之外构建所有函数资源 AWS SAM** — 如果您手动或通过其他工具构建所有函数资源，**sam build**则不需要这样做。您可以跳过 **sam build** 并继续执行流程的下一步，例如执行本地测试或部署应用程序。
+ **在外部构建一些函数资源 AWS SAM** — 如果您 AWS SAM 想构建一些函数资源，同时在外部构建其他函数资源 AWS SAM，则可以在 AWS SAM 模板中指定这一点。

### 在之外构建一些函数资源 AWS SAM
<a name="building-applications-skip-some"></a>

要在使用时 AWS SAM 跳过某个函数**sam build**，请在 AWS SAM 模板中配置以下内容：

1. 向函数添加 `SkipBuild: True` 元数据属性。

1. 指定您构建的函数资源的路径。

以下是将 `TestFunction` 配置为跳过的示例。它的构建资源位于 `built-resources/TestFunction.zip`。

```
TestFunction:
  Type: AWS::Serverless::Function
  Properties:
    CodeUri: built-resources/TestFunction.zip
    Handler: TimeHandler::handleRequest
    Runtime: java11
  Metadata:
    SkipBuild: True
```

现在，当你跑步时**sam build**， AWS SAM 将执行以下操作：

1. AWS SAM 将跳过配置的函数`SkipBuild: True`。

1. AWS SAM 将构建所有其他函数资源并将其缓存在`.aws-sam`构建目录中。

1. 对于跳过的函数，它们在 `.aws-sam` 构建目录中的模板将自动更新，以引用您构建的函数资源的指定路径。

   以下是 `.aws-sam` 构建目录中 `TestFunction` 的缓存模板的示例：

   ```
   TestFunction:
     Type: AWS::Serverless::Function
     Properties:
       CodeUri: ../../built-resources/TestFunction.zip
       Handler: TimeHandler::handleRequest
       Runtime: java11
     Metadata:
       SkipBuild: True
   ```

# 使用自定义构建 AWS SAM
<a name="building-lambda-functions"></a>

您可以自定义构建以包含特定的 Lambda 函数或 Lambda 层。函数是一种资源，您可以对其调用以在 Lambda 中运行您的代码。Lambda 层允许您从 Lambda 函数中提取代码，然后可以跨多个 Lambda 函数中重复使用这些代码。当您想专注于开发和部署单个无服务器函数，且免于管理共享依赖项或资源的复杂性时，则可以选择使用特定的 Lambda 函数自定义构建。此外，您可以选择构建 Lambda 层来帮助您缩小部署包的大小，将核心函数逻辑与依赖项分开，并允许您在多个函数之间共享依赖项。

本节中的主题探讨了您可以用来构建 Lambda 函数的一些不同方法。 AWS SAM其中包括使用客户运行时构建 Lambda 函数和构建 Lambda 层。自定义运行时允许您安装和使用开发人员指南中 Lambda 运行时中 AWS Lambda 未列出的语言。这样，您可以创建用于运行无服务器函数和应用程序的专业执行环境。仅构建 Lambda 层（而不是构建整个应用程序）可以在几个方面使您受益。它可以帮助您缩小部署包的大小，将核心函数逻辑与依赖项分开，并允许您在多个函数之间共享依赖项。

有关函数的更多信息，请参阅《AWS Lambda 开发人员指南》**中的 [Lambda 概念](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-concepts.html)。

**Topics**
+ [在 esbuild 中构建 Node.js Lambda 函数 AWS SAM](serverless-sam-cli-using-build-typescript.md)
+ [使用原生 AOT 编译功能构建.NET Lambda 函数 AWS SAM](build-dotnet7.md)
+ [使用 in 构建 Rust Lambda 函数 Cargo Lambda AWS SAM](building-rust.md)
+ [使用输入构建 Python Lambda 函数 uv AWS SAM](building-python-uv.md)
+ [在中使用自定义运行时构建 Lambda 函数 AWS SAM](building-custom-runtimes.md)
+ [在中构建 Lambda 图层 AWS SAM](building-layers.md)

# 在 esbuild 中构建 Node.js Lambda 函数 AWS SAM
<a name="serverless-sam-cli-using-build-typescript"></a>

要构建和打包 Node.js AWS Lambda 函数，可以将与 esbuild JavaScript 捆绑器 AWS SAMCLI一起使用。esbuild 捆绑器支持你写入的 Lambda 函数。 TypeScript

要使用 esbuild 构建 Node.js Lambda 函数，请向您的 `AWS:Serverless::Function` 资源添加一个 `Metadata` 对象并为 `BuildMethod` 指定 `esbuild`。当你运行**sam build**命令时， AWS SAM 使用 esbuild 来捆绑你的 Lambda 函数代码。

## 元数据属性
<a name="serverless-sam-cli-using-build-typescript-metadata"></a>

`Metadata` 对象针对 esbuild 支持以下属性：

### BuildMethod
<a name="serverless-sam-cli-using-build-typescript-metadata-buildmethod"></a>

为应用程序指定捆绑程序。`esbuild` 是唯一受支持的值。

### BuildProperties
<a name="serverless-sam-cli-using-build-typescript-metadata-buildproperties"></a>

为 Lambda 函数代码指定构建属性。

`BuildProperties` 对象针对 esbuild 支持以下属性：所有属性均为可选属性。默认情况下， AWS SAM 使用您的 Lambda 函数处理程序作为入口点。

**EntryPoints**  
为应用程序指定入口点。

**外部**  
指定要从构建中省略的程序包列表。有关更多信息，请参阅 *esbuild 网站*上的[外部](https://esbuild.github.io/api/#external)。

**Format**  
指定应用程序中生成 JavaScript 文件的输出格式。有关更多信息，请参阅 *esbuild 网站*中的[格式](https://esbuild.github.io/api/#format)。

**加载程序**  
指定用于加载给定文件类型的数据的配置列表。

**MainFields**  
指定解析程序包时要尝试导入哪些 `package.json` 字段。默认值为 `main,module`。

**缩小**  
指定是否缩小捆绑的输出代码。默认值为 `true`。

**OutExtension**  
自定义 esbuild 生成的文件的扩展名。有关更多信息，请参阅 *esbuild 网站*上的[向外扩展](https://esbuild.github.io/api/#out-extension)。

**源映射**  
指定捆绑程序是否生成源映射文件。默认值为 `false`。  
如果设置为 `true`，则 `NODE_OPTIONS: --enable-source-maps` 会附加到 Lambda 函数的环境变量中，生成源映射并将其包含在函数中。  
或者，如果 `NODE_OPTIONS: --enable-source-maps` 包含在函数的环境变量中，则 `Sourcemap` 会自动设置为 `true`。  
发生冲突时，`Sourcemap: false` 优先于 `NODE_OPTIONS: --enable-source-maps`。  
默认情况下，Lambda 使用 AWS Key Management Service (AWS KMS) 加密所有静态环境变量。使用源映射时，要成功部署，您的函数的执行角色必须具有执行 `kms:Encrypt` 操作的权限。

**SourcesContent**  
指定是否在源映射文件中包含源代码。当 `Sourcemap` 设置为 `'true'` 时，可配置此属性。  
+ 指定 `SourcesContent: 'true'` 包含所有源代码。
+ 指定 `SourcesContent: 'false'` 排除所有源代码。这样可以缩小源映射文件的大小，缩短启动时间，从而在生产中非常有用。但是，调试器中将无法使用源代码。
默认值为 `SourcesContent: true`。  
有关更多信息，请参阅 *esbuild 网站*中的[源内容](https://esbuild.github.io/api/#sources-content)。

**Target**  
指定目标 ECMAScript 版本。默认值为 `es2020`。

## TypeScript Lambda 函数示例
<a name="serverless-sam-cli-using-build-typescript-example"></a>

以下示例 AWS SAM 模板片段使用 esbuild 根据中的代码创建 Node.js Lambda 函数。 TypeScript `hello-world/app.ts`

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.handler
      Runtime: nodejs20.x
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api 
          Properties:
            Path: /hello
            Method: get
      Environment:
        Variables:
          NODE_OPTIONS: --enable-source-maps
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        Format: esm
        Minify: false
        OutExtension:
          - .js=.mjs
        Target: "es2020"
        Sourcemap: true
        EntryPoints: 
          - app.ts
        External:
          - "<package-to-exclude>"
```

# 使用原生 AOT 编译功能构建.NET Lambda 函数 AWS SAM
<a name="build-dotnet7"></a>

使用 AWS Serverless Application Model (AWS SAM) 构建和打包您的.NET 8 AWS Lambda 函数，利用原生 Ahead-of-Time (AOT) 编译来缩短 AWS Lambda 冷启动时间。

**Topics**
+ [.NET 8 本机 AOT 概览](#build-dotnet7-overview)
+ [AWS SAM 与您的.NET 8 Lambda 函数一起使用](#build-dotnet7-sam)
+ [安装必备组件](#build-dotnet7-prerequisites)
+ [在模板中定义.NET 8 Lambda 函数 AWS SAM](#build-dotnet7-sam-define)
+ [使用 AWS SAM CLI 构建应用程序](#build-dotnet7-sam-build)
+ [了解详情](#build-dotnet7-learn-more)

## .NET 8 本机 AOT 概览
<a name="build-dotnet7-overview"></a>

过去，.NET Lambda 函数的冷启动时间会影响无服务器应用程序的用户体验、系统延迟和使用成本。凭借 .NET 本机 AOT 编译，您可以缩短 Lambda 函数的冷启动时间。要了解有关.NET 8 原生 AOT 的更多信息，请参阅在 D [otnet 存储库中使用原生 A](https://github.com/dotnet/runtime/tree/main/src/coreclr/nativeaot#readme) *O GitHub * T。

## AWS SAM 与您的.NET 8 Lambda 函数一起使用
<a name="build-dotnet7-sam"></a>

执行以下操作，使用 AWS Serverless Application Model （AWS SAM）配置 .NET 8 Lambda 函数：
+ 在开发计算机上安装必备组件。
+ 在模板中定义.NET 8 Lambda 函数。 AWS SAM 
+ 使用构建您的应用程序 AWS SAMCLI。

## 安装必备组件
<a name="build-dotnet7-prerequisites"></a>

以下是所需的先决条件：
+ 的 AWS SAMCLI
+ .NET Core CLI
+ Amazon.Lambda.Tools .NET Core Global Tool
+ Docker

**安装 AWS SAM CLI**

1. 要检查是否已安装 AWS SAM CLI，请运行以下命令：

   ```
   sam --version
   ```

1. 要安装 AWS SAMCLI，请参阅[安装 AWS SAM CLI](install-sam-cli.md)。

1. 要升级的已安装版本 AWS SAMCLI，请参阅[升级 AWS SAM CLI](manage-sam-cli-versions.md#manage-sam-cli-versions-upgrade)。

**安装 .NET Core CLI**

1. 要下载和安装 .NET Core CLI，请参阅从 Microsoft 网站[下载 .NET](https://dotnet.microsoft.com/download)。

1. 有关 .NET Core CLI 的更多信息，请参阅*《AWS Lambda 开发人员指南》*中的 [.NET Core CLI](https://docs.aws.amazon.com/lambda/latest/dg/csharp-package-cli.html)。

**安装 Amazon.Lambda.Tools .NET Core Global Tool**

1. 运行如下命令：

   ```
   dotnet tool install -g Amazon.Lambda.Tools
   ```

1. 如果您已安装该工具，请确保该工具是使用以下命令的最新版本：

   ```
   dotnet tool update -g Amazon.Lambda.Tools
   ```

1. 有关 Amazon.Lambda.Tools .NET 核心全球工具的更多信息，请参阅上的.NE [T CLI 存储AWS 库](https://github.com/aws/aws-extensions-for-dotnet-cli)扩展。 GitHub

**安装 Docker**
+ 使用本机 AOT 进行构建需要安装 Docker。有关安装说明，请参阅[安装 Docker 以与 AWS SAM CLI 一起使用](install-docker.md)。

## 在模板中定义.NET 8 Lambda 函数 AWS SAM
<a name="build-dotnet7-sam-define"></a>

要定义. NET8 在您的 AWS SAM 模板中使用 Lambda 函数，请执行以下操作：

1. 从您选择的起始目录运行以下命令：

   ```
   sam init
   ```

1. 选择 `AWS Quick Start Templates` 以选择起始模板。

1. 选择 `Hello World Example`模板。

1. 通过输入 `n`，选择不使用最流行的运行时和包类型。

1. 对于运行时，选择 `dotnet8`。

1. 对于包类型，选择 `Zip`。

1. 对于您的入门模板，选择 `Hello World Example using native AOT`。

**安装 Docker**
+ 使用本机 AOT 进行构建需要安装 Docker。有关安装说明，请参阅[安装 Docker 以与 AWS SAM CLI 一起使用](install-docker.md)。

```
Resources:
HelloWorldFunction:
  Type: AWS::Serverless::Function
  Properties:
    CodeUri: ./src/HelloWorldAot/
    Handler: bootstrap
    Runtime: dotnet8
    Architectures:
      - x86_64
    Events:
      HelloWorldAot:
        Type: Api 
        Properties:
          Path: /hello
          Method: get
```

**注意**  
如果的`Event`属性设置`AWS::Serverless::Function`为`Api`，但未指定该`RestApiId`属性，则 AWS SAM 生成`AWS::ApiGateway::RestApi` CloudFormation 资源。

## 使用 AWS SAM CLI 构建应用程序
<a name="build-dotnet7-sam-build"></a>

 在您的项目根目录中，运行 `sam build` 命令以开始构建应用程序。如果 `PublishAot` 属性已在 .NET 8 项目文件中定义，则 AWS SAM CLI 将使用本机 AOT 编译进行构建。要了解有关 `PublishAot` 属性的更多信息，请参阅 Microsoft *.NET 文档*中的[本机 AOT 部署](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/)。

要构建您的函数， AWS SAM CLI 会调用使用 Amazon.Lambda.Tools .NET Core Global Tool 的 .NET Core CLI。

**注意**  
构建时，如果项目所在目录或父目录中存在 `.sln` 文件，则包含该 `.sln` 文件的目录将挂载到容器中。如果找不到 `.sln` 文件，则只会挂载项目文件夹。因此，如果您要构建多项目应用程序，请确保 `.sln` 文件位于属性中。

## 了解详情
<a name="build-dotnet7-learn-more"></a>

有关构建 .NET 8 Lambda 函数的更多信息，请参阅 [Introducing the .NET 8 runtime for AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-net-8-runtime-for-aws-lambda/)。

有关 **sam build** 命令的参考，请参阅 [sam build](sam-cli-command-reference-sam-build.md)。

# 使用 in 构建 Rust Lambda 函数 Cargo Lambda AWS SAM
<a name="building-rust"></a>


|  | 
| --- |
| 此功能为预览版 AWS SAM ，可能会发生变化。 | 

使用 AWS Serverless Application Model 命令行界面 (AWS SAMCLI) 和 Rust AWS Lambda 函数。

**Topics**
+ [先决条件](#building-rust-prerequisites)
+ [配置 AWS SAM 为与 Rust Lambda 函数一起使用](#building-rust-configure)
+ [示例](#building-rust-examples)

## 先决条件
<a name="building-rust-prerequisites"></a>

**Rust 语言**  
要安装 Rust，请参阅 *Rust 语言网站*上的[安装 Rust](https://www.rust-lang.org/tools/install)。

**Cargo Lambda**  
 AWS SAM CLI 要求安装 [https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html](https://www.cargo-lambda.info/guide/what-is-cargo-lambda.html)，是 Cargo 的子命令。有关安装说明，请参阅 *Cargo Lambda 文档*中的[安装](https://www.cargo-lambda.info/guide/installation.html)。

**Docker**  
构建和测试 Rust Lambda 函数需要 Docker。有关安装说明，请参阅[安装 Docker](install-docker.md)。

**选择加入 AWS SAM CLI 测试版功能**  
由于此功能为预览版，因此您必须使用以下方法之一选择加入：  

1. 使用环境变量：`SAM_CLI_BETA_RUST_CARGO_LAMBDA=1`。

1. 在您的 `samconfig.toml` 文件中添加以下内容：

   ```
   [default.build.parameters]
   beta_features = true
   [default.sync.parameters]
   beta_features = true
   ```

1. 使用支持的 AWS SAM CLI 命令时使用 `--beta-features` 选项。例如：

   ```
   $ sam build --beta-features
   ```

1. 当 AWS SAM CLI 提示您选择加入时，请选择选项 `y`。以下是示例：

   ```
   $ sam build
   Starting Build use cache
   Build method "rust-cargolambda" is a beta feature.
   Please confirm if you would like to proceed
   You can also enable this beta feature with "sam build --beta-features". [y/N]: y
   ```

## 配置 AWS SAM 为与 Rust Lambda 函数一起使用
<a name="building-rust-configure"></a>

### 第 1 步：配置您的 AWS SAM 模板
<a name="building-rust-configure-template"></a>

使用以下内容配置您的 AWS SAM 模板：
+ **二进制** – 可选。指定模板何时包含多个 Rust Lambda 函数。
+ **BuildMethod** – `rust-cargolambda`.
+ **CodeUri**— `Cargo.toml` 文件路径。
+ **处理程序** – `bootstrap`.
+ **运行时系统** – `provided.al2`.

要了解有关自定义运行时的更多信息，请参阅《*AWS Lambda 开发者*指南[AWS Lambda 》中的自定义运行时](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html)。

以下是已配置 AWS SAM 模板的示例：

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: rust-cargolambda
      BuildProperties: function_a
    Properties:
      CodeUri: ./rust_app
      Handler: bootstrap
      Runtime: provided.al2
...
```

### 第 2 步：将 AWS SAM CLI 与 Rust Lambda 函数一起使用
<a name="building-rust-configure-cli"></a>

在 AWS SAM 模板中使用任意 AWS SAMCLI命令。有关更多信息，请参阅 [AWS SAM CLI](using-sam-cli.md)。

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

### Hello World 示例
<a name="building-rust-examples-hello"></a>

**在此示例中，我们使用 Rust 作为运行时系统来构建示例 Hello World 应用程序。**

首先，我们使用 `sam init` 初始化新的无服务器应用程序。在交互式流程中，我们选择 **Hello World 应用程序**并选择 **Rust** 运行时系统。

```
$ sam init
...
Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        ...
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: ENTER

Which runtime would you like to use?
        1 - dotnet8
        2 - dotnet6
        3 - go (provided.al2)
        ...
        18 - python3.11
        19 - python3.10
        20 - ruby3.3
        21 - ruby3.2
        22 - rust (provided.al2)
        23 - rust (provided.al2023)
Runtime: 22

Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.

Based on your selections, the only dependency manager available is cargo.
We will proceed copying the template using cargo.

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: ENTER

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: ENTER

Project name [sam-app]: hello-rust

    -----------------------
    Generating application:
    -----------------------
    Name: hello-rust
    Runtime: rust (provided.al2)
    Architectures: x86_64
    Dependency Manager: cargo
    Application Template: hello-world
    Output Directory: .
    Configuration file: hello-rust/samconfig.toml
    
    Next steps can be found in the README file at hello-rust/README.md
        

Commands you can use next
=========================
[*] Create pipeline: cd hello-rust && sam pipeline init --bootstrap
[*] Validate SAM template: cd hello-rust && sam validate
[*] Test Function in the Cloud: cd hello-rust && sam sync --stack-name {stack-name} --watch
```

以下是 Hello World 应用程序的结构：

```
hello-rust
├── README.md
├── events
│   └── event.json
├── rust_app
│   ├── Cargo.toml
│   └── src
│       └── main.rs
├── samconfig.toml
└── template.yaml
```

在我们的 AWS SAM 模板中，我们的Rust函数定义如下：

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function 
    Metadata:
      BuildMethod: rust-cargolambda 
    Properties:
      CodeUri: ./rust_app 
      Handler: bootstrap   
      Runtime: provided.al2
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
            Path: /hello
            Method: get
```

接下来，运行 `sam build` 以构建应用程序并准备部署。 AWS SAM CLI 创建一个 `.aws-sam` 目录并在其中整理构建构件。函数是使用 Cargo Lambda 构建，并以可执行二进制文件的形式存储于 `.aws-sam/build/HelloWorldFunction/bootstrap`。

**注意**  
如果您计划在 MacOS 中运行 **sam local invoke** 命令，则需要在调用之前构建不同的函数。要执行此操作，请使用以下命令：  
**SAM\$1BUILD\$1MODE=debug sam build**
仅在完成本地测试时才需要此命令。在为部署构建时，不建议这样做。

```
hello-rust$ sam build
Starting Build use cache
Build method "rust-cargolambda" is a beta feature.
Please confirm if you would like to proceed
You can also enable this beta feature with "sam build --beta-features". [y/N]: y

Experimental features are enabled for this session.
Visit the docs page to learn more about the AWS Beta terms https://aws.amazon.com/service-terms/.

Cache is invalid, running build and copying resources for following functions (HelloWorldFunction)
Building codeuri: /Users/.../hello-rust/rust_app runtime: provided.al2 metadata: {'BuildMethod': 'rust-cargolambda'} architecture: x86_64 functions: HelloWorldFunction
Running RustCargoLambdaBuilder:CargoLambdaBuild
Running RustCargoLambdaBuilder:RustCopyAndRename

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
```

接下来，使用 `sam deploy --guided` 部署应用程序。

```
hello-rust$ sam deploy --guided

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Found
        Reading default arguments  :  Success

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [hello-rust]: ENTER
        AWS Region [us-west-2]: ENTER
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [Y/n]: ENTER
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: ENTER
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: ENTER
        HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]: ENTER
        SAM configuration file [samconfig.toml]: ENTER
        SAM configuration environment [default]: ENTER

        Looking for resources needed for deployment:

        ...

        Uploading to hello-rust/56ba6585d80577dd82a7eaaee5945c0b  817973 / 817973  (100.00%)

        Deploying with following values
        ===============================
        Stack name                   : hello-rust
        Region                       : us-west-2
        Confirm changeset            : True
        Disable rollback             : False
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisam-s3-demo-bucket-1a4x26zbcdkqr
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {}
        Signing Profiles             : {}

Initiating deployment
=====================

        Uploading to hello-rust/a4fc54cb6ab75dd0129e4cdb564b5e89.template  1239 / 1239  (100.00%)


Waiting for changeset to be created..

CloudFormation stack changeset
---------------------------------------------------------------------------------------------------------
Operation                  LogicalResourceId          ResourceType               Replacement              
---------------------------------------------------------------------------------------------------------
+ Add                      HelloWorldFunctionHelloW   AWS::Lambda::Permission    N/A                      
                           orldPermissionProd                                                             
...                    
---------------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:us-west-2:012345678910:changeSet/samcli-deploy1681427201/f0ef1563-5ab6-4b07-9361-864ca3de6ad6


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2023-04-13 13:07:17 - Waiting for stack create/update to complete

CloudFormation events from stack operations (refresh every 5.0 seconds)
---------------------------------------------------------------------------------------------------------
ResourceStatus             ResourceType               LogicalResourceId          ResourceStatusReason     
---------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS         AWS::IAM::Role             HelloWorldFunctionRole     -                        
CREATE_IN_PROGRESS         AWS::IAM::Role             HelloWorldFunctionRole     Resource creation        
...
---------------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
---------------------------------------------------------------------------------------------------------
Outputs                                                                                                 
---------------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole                                                           
Description         Implicit IAM Role created for Hello World function                                  
Value               arn:aws:iam::012345678910:role/hello-rust-HelloWorldFunctionRole-10II2P13AUDUY      

Key                 HelloWorldApi                                                                       
Description         API Gateway endpoint URL for Prod stage for Hello World function                    
Value               https://ggdxec9le9.execute-api.us-west-2.amazonaws.com/Prod/hello/                  

Key                 HelloWorldFunction                                                                  
Description         Hello World Lambda Function ARN                                                     
Value               arn:aws:lambda:us-west-2:012345678910:function:hello-rust-HelloWorldFunction-       
yk4HzGzYeZBj                                                                                            
---------------------------------------------------------------------------------------------------------


Successfully created/updated stack - hello-rust in us-west-2
```

为了进行测试，我们可以使用 API 端点调用 Lambda 函数。

```
$ curl https://ggdxec9le9.execute-api.us-west-2.amazonaws.com/Prod/hello/
Hello World!%
```

要在本地测试函数，首先我们要确保函数的 `Architectures` 属性与本地计算机相匹配。

```
...
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Metadata:
      BuildMethod: rust-cargolambda # More info about Cargo Lambda: https://github.com/cargo-lambda/cargo-lambda
    Properties:
      CodeUri: ./rust_app   # Points to dir of Cargo.toml
      Handler: bootstrap    # Do not change, as this is the default executable name produced by Cargo Lambda
      Runtime: provided.al2
      Architectures:
        - arm64
...
```

由于我们在此示例中将基础设施从 `x86_64` 修改为 `arm64`，因此我们运行 `sam build` 以更新构建构件。然后运行 `sam local invoke` 在本地调用函数。

```
hello-rust$ sam local invoke
Invoking bootstrap (provided.al2)
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-provided.al2
Building image.....................................................................................................................................
Using local image: public.ecr.aws/lambda/provided:al2-rapid-arm64.

Mounting /Users/.../hello-rust/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container
START RequestId: fbc55e6e-0068-45f9-9f01-8e2276597fc6 Version: $LATEST
{"statusCode":200,"body":"Hello World!"}END RequestId: fbc55e6e-0068-45f9-9f01-8e2276597fc6
REPORT RequestId: fbc55e6e-0068-45f9-9f01-8e2276597fc6  Init Duration: 0.68 ms  Duration: 130.63 ms     Billed Duration: 131 ms     Memory Size: 128 MB     Max Memory Used: 128 MB
```

### 单个 Lambda 函数项目
<a name="building-rust-examples-single"></a>

**以下是一个包含单个 Rust Lambda 函数的无服务器应用程序的示例。**

项目目录结构：

```
.
├── Cargo.lock
├── Cargo.toml
├── src
│   └── main.rs
└── template.yaml
```

AWS SAM 模板：

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: rust-cargolambda
    Properties:
      CodeUri: ./             
      Handler: bootstrap
      Runtime: provided.al2
...
```

### 多个 Lambda 函数项目
<a name="building-rust-examples-multiple"></a>

**以下是一个包含多个 Rust Lambda 函数的无服务器应用程序的示例。**

项目目录结构：

```
.
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── function_a.rs
│   └── function_b.rs
└── template.yaml
```

AWS SAM 模板：

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  FunctionA:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: rust-cargolambda
      BuildProperties:
        Binary: function_a 
    Properties:
      CodeUri: ./           
      Handler: bootstrap     
      Runtime: provided.al2
  FunctionB:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: rust-cargolambda
      BuildProperties:
        Binary: function_b
    Properties:
      CodeUri: ./
      Handler: bootstrap
      Runtime: provided.al2
```

`Cargo.toml` 文件：

```
[package]
name = "test-handler"
version = "0.1.0"
edition = "2021"

[dependencies]
lambda_runtime = "0.6.0"
serde = "1.0.136"
tokio = { version = "1", features = ["macros"] }
tracing = { version = "0.1", features = ["log"] }
tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] }

[[bin]]
name = "function_a"
path = "src/function_a.rs"

[[bin]]
name = "function_b"
path = "src/function_b.rs"
```

# 使用输入构建 Python Lambda 函数 uv AWS SAM
<a name="building-python-uv"></a>


|  | 
| --- |
| 此功能为预览版 AWS SAM ，可能会发生变化。 | 

使用带有uv快速 Python 包安装程序和解析器的 AWS Serverless Application Model 命令行界面 (AWS SAMCLI) 来构建 Python AWS Lambda 函数。

**Topics**
+ [先决条件](#building-python-uv-prerequisites)
+ [配置 AWS SAM 为与 Python Lambda 函数一起使用以及 uv](#building-python-uv-configure)
+ [示例](#building-python-uv-examples)

## 先决条件
<a name="building-python-uv-prerequisites"></a>

**Python**  
要安装 Python，请参阅在 [Python 网站上下载](https://www.python.org/downloads/) *Python*。

**uv**  
 AWS SAMCLI需要安装速度极快的 [https://docs.astral.sh/uv/](https://docs.astral.sh/uv/)Python 包安装程序和解析器。有关安装说明，请参阅 *uv 文档*中的[安装](https://docs.astral.sh/uv/getting-started/installation/)。

**选择加入 AWS SAM CLI 测试版功能**  
由于此功能为预览版，因此您必须使用以下方法之一选择加入：  

1. 使用环境变量：`SAM_CLI_BETA_PYTHON_UV=1`。

1. 在您的 `samconfig.toml` 文件中添加以下内容：

   ```
   [default.build.parameters]
   beta_features = true
   [default.sync.parameters]
   beta_features = true
   ```

1. 使用支持的 AWS SAM CLI 命令时使用 `--beta-features` 选项。例如：

   ```
   $ sam build --beta-features
   ```

1. 当 AWS SAM CLI 提示您选择加入时，请选择选项 `y`。以下是示例：

   ```
   $ sam build
   Starting Build use cache
   Build method "python-uv" is a beta feature.
   Please confirm if you would like to proceed
   You can also enable this beta feature with "sam build --beta-features". [y/N]: y
   ```

## 配置 AWS SAM 为与 Python Lambda 函数一起使用以及 uv
<a name="building-python-uv-configure"></a>

### 第 1 步：配置您的 AWS SAM 模板
<a name="building-python-uv-configure-template"></a>

使用以下内容配置您的 AWS SAM 模板：
+ **BuildMethod** – `python-uv`.
+ **CodeUri**— 包含`pyproject.toml`或的函数代码目录的路径`requirements.txt`。
+ **H** andler — 你的函数处理器（例如`app.lambda_handler`）。
+ **运行时** — Python 运行时版本（例如`python3.12`）。

以下是已配置 AWS SAM 模板的示例：

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./my_function
      Handler: app.lambda_handler
      Runtime: python3.12
    Metadata:
      BuildMethod: python-uv
...
```

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

### Hello World 示例
<a name="building-python-uv-examples-hello"></a>

**在此示例中，我们使用 Python uv 作为包管理器构建了一个示例 Hello World 应用程序。**

uv可以使用`pyproject.toml`或来读`requirements.txt`取依赖关系。如果两者都给出，`sam build`将从中读`requirements.txt`取依赖关系。

以下是 Hello World 应用程序的结构：

```
hello-python-uv
├── README.md
├── events
│   └── event.json
├── hello_world
│   ├── __init__.py
│   ├── app.py
│   └── pyproject.toml
├── samconfig.toml
└── template.yaml
```

`pyproject.toml` 文件：

```
[project]
name = "my-function"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "requests>=2.31.0",
    "boto3>=1.28.0",
]
```

在我们的 AWS SAM 模板中，我们的 Python 函数定义如下：

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
...
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.12
      Architectures:
        - x86_64
    Metadata:
      BuildMethod: python-uv
```

接下来，运行 `sam build` 以构建应用程序并准备部署。 AWS SAM CLI 创建一个 `.aws-sam` 目录并在其中整理构建构件。我们的函数依赖项是使用安装uv并存储在的`.aws-sam/build/HelloWorldFunction/`。

```
hello-python-uv$ sam build
Starting Build use cache
Build method "python-uv" is a beta feature.
Please confirm if you would like to proceed
You can also enable this beta feature with "sam build --beta-features". [y/N]: y

Experimental features are enabled for this session.
Visit the docs page to learn more about the AWS Beta terms https://aws.amazon.com/service-terms/.

Cache is invalid, running build and copying resources for following functions (HelloWorldFunction)
Building codeuri: /Users/.../hello-python-uv/hello_world runtime: python3.12 metadata: {'BuildMethod': 'python-uv'} architecture: x86_64 functions: HelloWorldFunction
Running PythonUvBuilder:UvBuild
Running PythonUvBuilder:CopySource

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
```

**注意**  
`python-uv`构建方法是按`Metadata`部分中的每个函数配置的。模板中的每个函数都可以使用不同的构建方法，从而允许您在同一个 AWS SAM 模板中将uv基于的函数与`pip`基于的函数混合使用。如果未指定构建方法，`pip`则默认使用。

# 在中使用自定义运行时构建 Lambda 函数 AWS SAM
<a name="building-custom-runtimes"></a>

您可以使用 `sam build` 命令构建 Lambda 函数所需的自定义运行时系统。您可以通过为函数指定 `Runtime: provided` 来声明 Lambda 函数以使用自定义运行时系统。

要构建自定义运行时系统，请使用 `BuildMethod: makefile` 条目声明 `Metadata` 资源属性。您提供自定义 makefile，在其中声明包含运行时构建命令的表单 `build-function-logical-id` 的构建目标。如有必要，您的 makefile 负责编译自定义运行时系统，并将构建构件复制到工作流程中后续步骤所需的适当位置。Makefile 的位置由函数资源的 `CodeUri` 属性指定，并且必须命名为 `Makefile`。

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

### 示例 1：用 Rust 编写的函数的自定义运行时系统
<a name="building-custom-runtimes-examples-rust"></a>

**注意**  
我们建议使用 Cargo Lambda 构建 Lambda 函数。要了解更多信息，请参阅[使用 in 构建 Rust Lambda 函数 Cargo Lambda AWS SAM](building-rust.md)。

以下 AWS SAM 模板声明了一个函数，该函数为用 Rust 编写的 Lambda 函数使用自定义运行时，并指示`sam build`为构建目标执行命令。`build-HelloRustFunction`

```
Resources:
  HelloRustFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: HelloRust
      Handler: bootstrap.is.real.handler
      Runtime: provided
      MemorySize: 512
      CodeUri: .
    Metadata:
      BuildMethod: makefile
```

以下 makefile 包含构建目标和将要执行的命令。请注意，`CodeUri` 属性设置为 `.`，因此 makefile 必须位于项目根目录（即与应用程序 AWS SAM 模板文件相同的目录）。文件名必须是 `Makefile`。

```
build-HelloRustFunction:
	cargo build --release --target x86_64-unknown-linux-musl
	cp ./target/x86_64-unknown-linux-musl/release/bootstrap $(ARTIFACTS_DIR)
```

有关设置开发环境以执行前面 `makefile` 中的 `cargo build` 命令的更多信息，请参阅博客文章 [AWS Lambda的 Rust 运行时系统](https://aws.amazon.com/blogs/opensource/rust-runtime-for-aws-lambda/)。

### 示例 2：适用于 Python3.12 的 makefile 生成器（替代使用捆绑生成器）
<a name="building-custom-runtimes-examples-python"></a>

您可能需要使用未包含在捆绑生成器中的库或模块。此示例显示了带有 makefile 生成器的 Python3.12 运行时的 AWS SAM 模板。

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.12
    Metadata:
      BuildMethod: makefile
```

以下 makefile 包含构建目标和将要执行的命令。请注意，`CodeUri` 属性设置为 `hello_world`，因此 makefile 必须位于 `hello_world` 子目录的根目录中，并且文件名必须为 `Makefile`。

```
build-HelloWorldFunction:
	cp *.py $(ARTIFACTS_DIR)
	cp requirements.txt $(ARTIFACTS_DIR)
	python -m pip install -r requirements.txt -t $(ARTIFACTS_DIR)
	rm -rf $(ARTIFACTS_DIR)/bin
```

# 在中构建 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
```