

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

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

使用 AWS Serverless Application Model Command Line Interface (AWS SAMCLI) `sam build` 命令为开发工作流程中的后续步骤做好准备，例如本地测试或部署到。 AWS Cloud此命令会创建 `.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 Cloud中使用原生 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