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

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

使用 sam build

使用Amazon Serverless Application Model命令行接口 (Amazon SAMCLI)sam build 命令为无服务器应用程序做好准备,以执行开发工作流程中的后续步骤,例如本地测试或部署到Amazon Web Services 云。此命令创建一个.aws-sam目录,该目录以和sam deploy要求的格式和位置来构建sam local您的应用程序。

注意

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

使用 sam build 构建应用程序

在使用之前sam build,请考虑并配置以下内容:

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

  2. Lambda 运行时提供在调用函数时,运行时会在执行环境中运行函数时。您可以配置原生和自定义运行时。

    1. 原生运行时 — 在支持的 Lambda 运行时中编写您的 Lambda 函数,并在中构建您的函数以使用原生 Lambda 运行时Amazon Web Services 云。

    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.9 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. CAmazon SAM LI 创建.aws-sam构建目录。以下是示例:

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

根据您的应用程序的配置方式,Amazon SAMCLI 会执行以下操作:

  1. .aws-sam/build目录中下载、安装和整理依赖关系。

  2. 准备好您的 Lambda 代码。这可能包括编译您的代码、创建可执行的二进制文件和构建容器镜像。

  3. 将构建构件复制到该.aws-sam目录中。格式将根据您的应用程序包类型而有所不同。

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

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

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

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

  • 构建目录 — 包含您的 Lambda 函数和相互独立结构的层。这会为.aws-sam/build目录中的每个函数或层生成唯一的结构。

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

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

本地测试和部署

使用sam local或使用执行本地测试时sam deploy,Amazon SAMCLI 会执行以下操作:

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

  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 SAM CLI 将您的原始项目目录识别为根项目目录。准备就绪后,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-nodejs12.x

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

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

将环境变量传递到构建容器

使用--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 SAMCLI 会逐个构建每个函数。要加快构建过程,请使用--parallel选项。这会同时构建所有的函数和层。

以下是此命令的示例:

$ sam build —-parallel

问题排查

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

示例

构建使用本机运行时和.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? ... 11 - java8 12 - nodejs18.x 13 - nodejs16.x 14 - nodejs14.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 ...

CAmazon SAM LI 初始化应用程序并创建以下项目目录:

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 ...

CAmazon SAM LI 初始化应用程序。以下是应用程序目录结构的示例:

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命令的更多信息,请参阅以下内容: