建築簡介 AWS SAM - AWS Serverless Application Model

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

建築簡介 AWS SAM

使用命 AWS Serverless Application Model 令列介面 (AWS SAMCLI) sam build 命令為開發工作流程中的後續步驟準備無伺服器應用程式,例如本機測試或部署到 AWS 雲端. 此命令會建立一個.aws-sam目錄,以及sam deploy需要的格式和位置來建構應用程式。sam local

注意

使用時,您sam build必須從開發電腦上的無伺服器應用程式的基本元件開始。這包括一個 AWS SAM 模板, AWS Lambda 函數代碼,以及任何特定語言的文件和依賴關係。如需進一步了解,請參閱建立您的應用程式 AWS SAM

使用 sam 構建構建應用程式

使用前sam build,請考慮設定下列項目:

  1. Lambda 函數和層 — 該sam build命令可以建立 Lambda 函數和層。若要進一步了解 Lambda 層,請參閱在中建置 Lambda 圖層 AWS SAM

  2. Lambda 執行階段 — 執行階段提供語言特定的環境,可在呼叫時在執行環境中執行函數。您可以設定原生和自訂執行階段。

    1. 原生執行階段 — 在支援的 Lambda 執行階段中撰寫您的 Lambda 函數,並建立函數,以便在 AWS 雲端.

    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 SAMCLI輸出的範例:

    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 SAMCLI立組.aws-sam建目錄。以下是範例:

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

視應用程式的設定方式而定, AWS SAMCLI會執行下列動作:

  1. 下載,安裝和組織.aws-sam/build目錄中的依賴關係。

  2. 準備您的 Lambda 式碼。這可能包括編譯程式碼、建立可執行的二進位檔案,以及建置容器映像檔。

  3. 將組建加工品複製到.aws-sam目錄中。格式會根據您的應用程式套件類型而有所不同。

    1. 對於 .zip 封裝類型,成品尚未壓縮,因此可用於本機測試。使用時 AWS SAMCLI拉鍊您的應用sam deploy程序。

    2. 對於容器映像封裝類型,會在本機建立容器映像,並在.aws-sam/build.toml檔案中參考。

  4. 將 AWS SAM 範本複製到.aws-sam目錄中,並在必要時使用新的檔案路徑對其進行修改。

以下是組成.aws-sam目錄中組成構成品的主要元件:

  • 建置目錄 — 包含彼此獨立結構的 Lambda 函數和層。這會為.aws-sam/build目錄中的每個函數或圖層產生唯一的結構。

  • AWS SAM 範本-根據建置流程期間的變更以更新的值進行修改。

  • 建置的 .toml 檔案 — 組態檔案,其中包含使用的組建設定。 AWS SAMCLI

本機測試與部署

使用執行本機測試sam local或使用部署時sam deploy, AWS SAMCLI會執行下列動作:

  1. 它會先檢查.aws-sam目錄是否存在,以及 AWS SAM 範本是否位於該目錄內。如果符合這些條件,會 AWS SAMCLI將其視為應用程式的根目錄。

  2. 如果不符合這些條件,會 AWS SAMCLI將 AWS SAM 範本的原始位置視為應用程式的根目錄。

開發時,如果對原始應用程式檔案進行了變更,請在本機測試之前執行sam build以更新.aws-sam目錄。

最佳實務

  • 不要編輯.aws-sam/build目錄下的任何代碼。相反,請更新項目文件夾中的原始源代碼並運行sam build以更新目.aws-sam/build錄。

  • 當您修改原始檔案時,sam build請執行以更新目.aws-sam/build錄。

  • 您可能希 AWS SAMCLI望引用項目的原始根目錄而不是.aws-sam目錄,例如在使用sam local. 刪除目.aws-sam錄中的目錄或 AWS SAM 模板,以使您的原始項目目錄 AWS SAMCLI識別為根項目目錄。.aws-sam準備就緒後,sam build再次執行以建立目.aws-sam錄。

  • 當您執行時sam build,每次都會覆寫.aws-sam/build目錄。目.aws-sam錄沒有。如果您想要儲存檔案 (例如記錄),請將它們儲存在中,.aws-sam以防止它們遭到覆寫。

山姆構建的選項

建立單一資源

提供資源的邏輯 ID 以僅建置該資源。以下是範例:

$ sam build HelloWorldFunction

若要建立巢狀應用程式或堆疊的資源,請使用下列格式提供應用程式或堆疊邏輯 ID 以及資源邏輯 ID<stack-logical-id>/<resource-logical-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 SAMCLI構建一個函數。若要加速建置程序,請使用--parallel選項。這會同時構建所有功能和層。

以下是此命令的範例:

$ sam build —-parallel

通過在源文件夾中構建項目來加快構建時間

對於支持的運行時和構建方法,您可以使用該--build-in-source選項直接在源文件夾中構建項目。默認情況下, AWS SAM CLI構建在臨時目錄中,其中涉及複製源代碼和項目文件。使用--build-in-source,直接在源文件夾中 AWS SAM CLI構建,通過消除將文件複製到臨時目錄的需要來加快構建過程。

如需支援的執行階段和建置方法的清單,請參閱--build-in-source

疑難排解

若要疑難排解 AWS SAMCLI,請參閱AWS SAMCLI疑難排

範例

建置使用原生執行階段和 .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 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 ...

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-containersam 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"}%

進一步了解

若要進一步瞭解如何使用sam build指令,請參閱下列內容: