使用 AWS SAM 进行构建简介 - AWS Serverless Application Model

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

使用 AWS SAM 进行构建简介

使用 AWS Serverless Application Model 命令行界面 (AWS SAM CLI) sam build 命令让无服务器应用程序为开发工作流程的后续步骤(例如,本地测试或部署到 AWS Cloud)做好准备。此命令会创建 .aws-sam 目录,该目录将以 sam localsam deploy 所要求的格式和位置来编排应用程序的结构。

注意

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

使用 sam build 构建应用程序

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

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

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

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

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

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

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

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

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

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

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

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

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

    下面是 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
  3. 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 目录中下载、安装和组织依赖项。

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

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

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

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

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

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

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

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

  • build.toml 文件 - 包含 AWS SAM CLI 使用的构建设置的配置文件。

本地测试和部署

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

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

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

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

最佳实践

  • 不要编辑 .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 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-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 时,AWS SAM CLI 会逐个构建每个函数。要加快构建过程,请使用 --parallel 选项。这样可以同时构建所有函数和层。

以下是该命令的示例:

$ sam build —-parallel

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

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

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

故障排除

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

示例

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

对于本示例,请参阅 教程:使用以下命令部署 Hello World 应用程序 AWS SAM

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

首先,运行 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 SAM CLI 初始化应用程序并创建以下项目目录:

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

AWS SAM CLI 初始化应用程序。下面是应用程序目录结构的示例:

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 SAM CLI 下载容器映像,使用原生 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 命令的更多信息,请参阅以下内容: