使用 sam build - Amazon Serverless Application Model
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

使用 sam build

使用 Amazon Serverless Application Model Command Line Interface (Amazon SAMCLI) sam build 命令为开发工作流程中的后续步骤做好准备,例如本地测试或部署到。 Amazon Web Services 云此命令会创建 .aws-sam 目录,该目录将以 sam localsam deploy 所要求的格式和位置来编排应用程序的结构。

注意

使用 sam build 时,您需要从开发计算机上无服务器应用程序的基本组件开始。这包括 Amazon SAM 模板、 Amazon Lambda 函数代码以及任何特定于语言的文件和依赖关系。要了解更多信息,请参阅使用 sam init

使用 sam build 构建应用程序

使用 sam build 之前,请考虑并配置以下各项:

  1. Lambda 函数和层 - sam build 命令可以构建 Lambda 函数和层。要了解有关 Lambda 层的更多信息,请参阅 构建层

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

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

    2. 自定义运行时 - 使用任何编程语言编写 Lambda 函数,并使用在 makefile 或第三方生成器(例如 esbuild)中定义的自定义流程来构建运行时。要了解更多信息,请参阅构建自定义运行时系统

  3. Lambda 包类型 - Lambda 函数可以打包成以下 Lambda 部署包类型:

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

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

可在使用 sam init 初始化应用程序时配置这些应用程序设置。

  • 要了解有关使用 sam init 的更多信息,请参阅 使用 sam init

  • 要了解有关在应用程序中配置这些设置的更多信息,请参阅 构建 应用程序

构建应用程序
  1. cd 到项目的根目录。此位置与您的 Amazon SAM 模板相同。

    $ cd sam-app
  2. 运行以下命令:

    sam-app $ sam build <arguments> <options>
    注意

    常用选项是 --use-container。要了解更多信息,请参阅在提供的容器内构建 Lambda 函数

    下面是 Amazon 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
  3. Amazon SAM CLI 会创建 .aws-sam 构建目录。以下是 示例:

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

根据应用程序的配置, Amazon SAM CLI 会执行以下操作:

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

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

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

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

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

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

以下是构成 .aws-sam 目录中的构建构件的主要组件:

  • 构建目录 - 包含在结构上彼此独立的 Lambda 函数和层。这使得 .aws-sam/build 目录中的每个函数或层都有唯一的结构。

  • Amazon SAM 模板-根据构建过程中的更改使用更新的值进行修改。

  • build.toml 文件 — 包含使用的编译设置的配置文件。 Amazon SAMCLI

本地测试和部署

使用 sam local 执行本地测试或使用 sam deploy 进行部署时, Amazon SAM CLI 会执行以下操作:

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

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

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

最佳实践

  • 不要编辑 .aws-sam/build 目录下的任何代码。而是应更新项目文件夹中的原始源代码,然后运行 sam build 以更新 .aws-sam/build 目录。

  • 修改原始文件时,运行 sam build 以更新 .aws-sam/build 目录。

  • 您可能希望 Amazon SAM CLI 引用项目的原始根目录而不是 .aws-sam 目录,例如,在使用 sam local 进行开发和测试时。删除.aws-sam目录或.aws-sam目录中的 Amazon SAM 模板,以便将您的原始项目目录 Amazon SAMCLI识别为根项目目录。准备就绪后,再次运行 sam build 以创建 .aws-sam 目录。

  • 运行 sam build 时,.aws-sam/build 目录每次都会被覆盖。.aws-sam 目录不会被覆盖。如果您想要存储文件(例如日志),请将其存储在 .aws-sam 中,以防止它们被覆盖。

sam build 的选项

构建单个资源

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

$ sam build HelloWorldFunction

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

$ sam build MyNestedStack/MyFunction

在提供的容器内构建 Lambda 函数

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

此选项需要安装 Docker。有关说明,请参阅安装 Docker

以下是该命令的示例:

$ 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

传递环境变量给构建容器

使用 --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" } }

加快构建包含多个函数的应用程序

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

以下是该命令的示例:

$ sam build —-parallel

通过在源文件夹中构建项目来加快构建时间

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

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

故障排除

要排除故障 Amazon SAMCLI,请参阅Amazon SAM CLI 故障排除

示例

构建使用原生运行时和 .zip 包类型的应用程序

对于本示例,请参阅 教程:部署 Hello World 应用程序

构建使用原生运行时和映像包类型的应用程序

首先,运行 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 ...

初 Amazon 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

构建包含已编译编程语言的应用程序

在此示例中,我们使用 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 ...

初 Amazon 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 结合使用。 Amazon 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"}%

了解更多信息

要了解有关使用 sam build 命令的更多信息,请参阅以下内容: