教學課程:建置自訂執行期 - AWS Lambda

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

教學課程:建置自訂執行期

在本教學課程中,您將建立具有自訂執行時間的 Lambda 函數。首先,您要將執行時間納入函式的部署套件中。接著再將其遷移到與函式分開而單獨管理的 Layer。最後,您要透過更新該執行時間 Layer 以資源為基礎的許可政策,將其與世界各地的人共享。

必要條件

此教學課程假設您具備基本的 Lambda 操作知識並了解 Lambda 主控台。若您尚未了解,請遵循 使用主控台建立一個 Lambda 函數 中的指示,建立您的第一個 Lambda 函數。

若要完成下列步驟,您需要 AWS Command Line Interface (AWS CLI) 版本 2。命令和預期的輸出會列在不同的區塊中:

aws --version

您應該會看到下列輸出:

aws-cli/2.13.27 Python/3.11.6 Linux/4.14.328-248.540.amzn2.x86_64 exe/x86_64.amzn.2

對於長命令,逸出字元 (\) 用於將命令分割為多行。

在 Linux 和 macOS 上,使用您偏好的 shell 和套件軟體管理工具。

注意

在 Windows 中,作業系統的內建終端不支援您常與 Lambda 搭配使用的某些 Bash CLI 命令 (例如 zip)。若要取得 Ubuntu 和 Bash 的 Windows 整合版本,請安裝適用於 Linux 的 Windows 子系統。本指南中的 CLI 命令範例使用 Linux 格式。如果您使用的是 Windows CLI,必須重新格式化包含內嵌 JSON 文件的命令。

您需要 IAM 角色來建立 Lambda 函數。角色需要權限才能將日誌發送到 CloudWatch 日誌並訪問您的功能使用的AWS服務。如果您還沒有函數開發角色,請立即建立一個。

若要建立執行角色
  1. 在 IAM 主控台中開啟 角色頁面

  2. 選擇 建立角色

  3. 建立具備下列屬性的角色。

    • 信任實體 - Lambda

    • 權限AWSLambdaBasicExecutionRole.

    • 角色名稱 - lambda-role

    AWSLambdaBasicExecutionRole策略具有函數將日誌寫入日誌所需的 CloudWatch 權限。

建立函數

建立具有自訂執行時間的 Lambda 函數。本範例包括兩個檔案:執行期 bootstrap 檔案以及函數處理常式。兩個檔案都是以 Bash 實作。

  1. 建立專案的目錄,然後切換至該目錄。

    mkdir runtime-tutorial cd runtime-tutorial
  2. 建立稱為 bootstrap 的新檔案。這是自訂執行期。

    範例 引導
    #!/bin/sh set -euo pipefail # Initialization - load function handler source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh" # Processing while true do HEADERS="$(mktemp)" # Get an event. The HTTP request will block until one is received EVENT_DATA=$(curl -sS -LD "$HEADERS" "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next") # Extract request ID by scraping response headers received above REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2) # Run the handler function from the script RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA") # Send the response curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE" done

    執行時間將從部署套件載入函式指令碼。其使用了兩個變數以找出指令碼。LAMBDA_TASK_ROOT 將告知套件解壓縮的位置,而 _HANDLER 則包含指令碼的名稱。

    在執行期載入函數指令碼之後,它將使用執行期 API 從 Lambda 中擷取調用事件、傳遞事件至處理常式,並將回應發布回 Lambda。為了取得請求 ID,執行時間將 API 回應中的各標頭儲存至暫時檔案,然後從該檔案讀取 Lambda-Runtime-Aws-Request-Id 標頭。

    注意

    執行時間另還負責其他任務,包括錯誤處理以及向處理常式提供內容資訊。如需詳細資訊,請參閱 要求

  3. 為函數建立指令碼。以下範例指令碼定義了一個接受事件資料的處理常式函數,會將該資料記錄到 stderr 並予以傳回。

    範例 function.sh
    function handler () { EVENT_DATA=$1 echo "$EVENT_DATA" 1>&2; RESPONSE="Echoing request: '$EVENT_DATA'" echo $RESPONSE }

    runtime-tutorial 目錄現在應該看起來像這樣:

    runtime-tutorial ├ bootstrap └ function.sh
  4. 將檔案轉成可執行檔並加入至 .zip 封存檔。這是部署套件。

    chmod 755 function.sh bootstrap zip function.zip function.sh bootstrap
  5. 建立名為的函數 bash-runtime。對於 --role,輸入 Lambda 執行角色的 ARN。

    aws lambda create-function --function-name bash-runtime \ --zip-file fileb://function.zip --handler function.handler --runtime provided.al2023 \ --role arn:aws:iam::123456789012:role/lambda-role
  6. 調用函數。

    aws lambda invoke --function-name bash-runtime --payload '{"text":"Hello"}' response.txt --cli-binary-format raw-in-base64-out

    如果您使用 AWS CLI 第 2 版,則需要 cli-binary-format 選項。若要讓此成為預設的設定,請執行 aws configure set cli-binary-format raw-in-base64-out。若要取得更多資訊,請參閱《AWS Command Line Interface 使用者指南第 2 版》AWS CLI 支援的全域命令列選項

    您應該看到如下回應:

    { "StatusCode": 200, "ExecutedVersion": "$LATEST" }
  7. 確認回應。

    cat response.txt

    您應該看到如下回應:

    Echoing request: '{"text":"Hello"}'

建立 Layer

為了將執行時間程式碼與函式程式碼分開,您要建立一個僅包含執行時間的 Layer。Layer 讓您能夠單獨開發函式的依存項目,且若搭配多個函式使用同一 Layer 還可減少儲存空間用量。如需詳細資訊,請參閱 使用 Lambda 層

  1. 建立包含 bootstrap 檔案的 .zip 檔案。

    zip runtime.zip bootstrap
  2. 使用 publish-layer-version 命令建立 Layer。

    aws lambda publish-layer-version --layer-name bash-runtime --zip-file fileb://runtime.zip

    如此即建立了 Layer 的第一個版本。

更新函數

若要搭配函式使用執行期 Layer,請將函式設定成使用 Layer,並且移除函式中的執行期程式碼。

  1. 更新函式組態以提取 Layer。

    aws lambda update-function-configuration --function-name bash-runtime \ --layers arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:1

    這會將執行時間新增至 /opt 目錄中的函數。若要確保 Lambda 使用層中的執行期,您必須將 boostrap 從函數的部署套件中移除,如接下來兩個步驟所示。

  2. 建立包含函數程式碼的 .zip 檔案。

    zip function-only.zip function.sh
  3. 更新函式程式碼,使之僅包含處理常式指令碼。

    aws lambda update-function-code --function-name bash-runtime --zip-file fileb://function-only.zip
  4. 調用函數以確認其是否可搭配執行期 layer 運作。

    aws lambda invoke --function-name bash-runtime --payload '{"text":"Hello"}' response.txt --cli-binary-format raw-in-base64-out

    如果您使用 AWS CLI 第 2 版,則需要 cli-binary-format 選項。若要讓此成為預設的設定,請執行 aws configure set cli-binary-format raw-in-base64-out。若要取得更多資訊,請參閱《AWS Command Line Interface 使用者指南第 2 版》AWS CLI 支援的全域命令列選項

    您應該看到如下回應:

    { "StatusCode": 200, "ExecutedVersion": "$LATEST" }
  5. 確認回應。

    cat response.txt

    您應該看到如下回應:

    Echoing request: '{"text":"Hello"}'

更新執行時間

  1. 若要記錄執行環境的相關資訊,請更新執行時間指令碼使其輸出環境變數。

    範例 引導
    #!/bin/sh set -euo pipefail # Configure runtime to output environment variables echo "## Environment variables:" env # Load function handler source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh" # Processing while true do HEADERS="$(mktemp)" # Get an event. The HTTP request will block until one is received EVENT_DATA=$(curl -sS -LD "$HEADERS" "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next") # Extract request ID by scraping response headers received above REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2) # Run the handler function from the script RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA") # Send the response curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE" done
  2. 建立包含新版本 bootstrap 檔案的 .zip 檔案。

    zip runtime.zip bootstrap
  3. 建立 bash-runtime 層的新版本。

    aws lambda publish-layer-version --layer-name bash-runtime --zip-file fileb://runtime.zip
  4. 設定函式以使用新版本的 Layer。

    aws lambda update-function-configuration --function-name bash-runtime \ --layers arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:2

共享 Layer

如欲將層使用許可授予其他帳戶,請透過 add-layer-version-permission 命令將陳述式新增至層版本的許可政策。在各陳述式中,您可將許可授予單一帳戶、所有帳戶或某個組織。

以下列範例會授予帳戶 111122223333 存取 bash-runtime layer 第 2 版的許可。

aws lambda add-layer-version-permission --layer-name bash-runtime --statement-id xaccount \ --action lambda:GetLayerVersion --principal 111122223333 --version-number 2 --output text

您應該會看到類似下列的輸出:

e210ffdc-e901-43b0-824b-5fcd0dd26d16 {"Sid":"xaccount","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::111122223333:root"},"Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:2"}

許可僅適用於單一層版本。每次建立新的層版本時均需重複此程序。

清除

刪除各個版本的 Layer。

aws lambda delete-layer-version --layer-name bash-runtime --version-number 1 aws lambda delete-layer-version --layer-name bash-runtime --version-number 2

由於函數持有對該層的第 2 版的參考,所以它仍存在於 Lambda 中。本函式將繼續運作,但無法再設定各函式使用已刪除的版本。若您修改了函數的 layer 清單,則必須指定新的版本或略去已刪除的 layer。

使用 delete-function 命令刪除函數。

aws lambda delete-function --function-name bash-runtime