教學課程 - 發佈自訂執行時間 - AWS Lambda

教學課程 - 發佈自訂執行時間

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

先決條件

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

為了完成以下步驟,您需要命令列終端或 shell 來執行命令。命令和預期的輸出會列在不同的區塊中:

aws --version

您應該會看到下列輸出:

aws-cli/2.0.57 Python/3.7.4 Darwin/19.6.0 exe/x86_64

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

在 Linux 和 macOS 上,使用您偏好的 shell 和套件軟體管理工具。在 Windows 10 上,您可以安裝適用於 Linux 的 Windows 子系統,以取得 Ubuntu 和 Bash 的 Windows 整合版本。

您需要 IAM 角色來建立 Lambda 函數。該角色需要許可,才能將日誌傳送至 CloudWatch Logs,並存取您的函數使用的 AWS 服務。如果您還沒有函數開發角色,請立即建立一個。

若要建立執行角色

  1. 在 IAM 主控台中開啟 Roles (角色) 頁面。

  2. 選擇 Create Role (建立角色)

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

    • Trusted entity (信任實體) - Lambda

    • Permissions (許可) - AWSLambdaBasicExecutionRole

    • Role name (角色名稱) - lambda-role

    AWSLambdaBasicExecutionRole 政策具備函數將日誌寫入到 CloudWatch Logs 時所需的許可。

建立 函數

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

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

範例 引導

#!/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" -X GET "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 -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE" done

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

注意

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

指令碼定義了一個接受事件資料的處理常式函式,會將該資料記錄到 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

將檔案轉成可執行檔並加入至 .zip 封存檔。

runtime-tutorial$ chmod 755 function.sh bootstrap runtime-tutorial$ zip function.zip function.sh bootstrap adding: function.sh (deflated 24%) adding: bootstrap (deflated 39%)

建立名為的函數 bash-runtime

runtime-tutorial$ aws lambda create-function --function-name bash-runtime \ --zip-file fileb://function.zip --handler function.handler --runtime provided \ --role arn:aws:iam::123456789012:role/lambda-role { "FunctionName": "bash-runtime", "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:bash-runtime", "Runtime": "provided", "Role": "arn:aws:iam::123456789012:role/lambda-role", "Handler": "function.handler", "CodeSha256": "mv/xRv84LPCxdpcbKvmwuuFzwo7sLwUO1VxcUv3wKlM=", "Version": "$LATEST", "TracingConfig": { "Mode": "PassThrough" }, "RevisionId": "2e1d51b0-6144-4763-8e5c-7d5672a01713", ... }

叫用函式並驗證回應。

runtime-tutorial$ aws lambda invoke --function-name bash-runtime --payload '{"text":"Hello"}' response.txt --cli-binary-format raw-in-base64-out { "StatusCode": 200, "ExecutedVersion": "$LATEST" } runtime-tutorial$ cat response.txt Echoing request: '{"text":"Hello"}'

建立 Layer

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

建立一個含有 bootstrap 檔案的 Layer 封存檔。

runtime-tutorial$ zip runtime.zip bootstrap adding: bootstrap (deflated 39%)

使用 publish-layer-version 命令建立 Layer。

runtime-tutorial$ aws lambda publish-layer-version --layer-name bash-runtime --zip-file fileb://runtime.zip { "Content": { "Location": "https://awslambda-us-west-2-layers.s3.us-west-2.amazonaws.com/snapshots/123456789012/bash-runtime-018c209b...", "CodeSha256": "bXVLhHi+D3H1QbDARUVPrDwlC7bssPxySQqt1QZqusE=", "CodeSize": 584, "UncompressedCodeSize": 0 }, "LayerArn": "arn:aws:lambda:us-west-2:123456789012:layer:bash-runtime", "LayerVersionArn": "arn:aws:lambda:us-west-2:123456789012:layer:bash-runtime:1", "Description": "", "CreatedDate": "2018-11-28T07:49:14.476+0000", "Version": 1 }

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

更新函數

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

更新函式組態以提取 Layer。

runtime-tutorial$ aws lambda update-function-configuration --function-name bash-runtime \ --layers arn:aws:lambda:us-west-2:123456789012:layer:bash-runtime:1 { "FunctionName": "bash-runtime", "Layers": [ { "Arn": "arn:aws:lambda:us-west-2:123456789012:layer:bash-runtime:1", "CodeSize": 584, "UncompressedCodeSize": 679 } ] ... }

這會將執行時間新增至 /opt 目錄中的函數。Lambda 會使用此執行時間,但前提是已從函數的部署套件中移除它。更新函式程式碼,使之僅包含處理常式指令碼。

runtime-tutorial$ zip function-only.zip function.sh adding: function.sh (deflated 24%) runtime-tutorial$ aws lambda update-function-code --function-name bash-runtime --zip-file fileb://function-only.zip { "FunctionName": "bash-runtime", "CodeSize": 270, "Layers": [ { "Arn": "arn:aws:lambda:us-west-2:123456789012:layer:bash-runtime:7", "CodeSize": 584, "UncompressedCodeSize": 679 } ] ... }

叫用函式以確認其是否可搭配執行時間 Layer 運作。

runtime-tutorial$ aws lambda invoke --function-name bash-runtime --payload '{"text":"Hello"}' response.txt --cli-binary-format raw-in-base64-out { "StatusCode": 200, "ExecutedVersion": "$LATEST" } runtime-tutorial$ cat response.txt Echoing request: '{"text":"Hello"}'

更新執行時間

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

範例 引導

#!/bin/sh set -euo pipefail echo "## Environment variables:" env # Initialization - load function handler source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh" ...

輸入新的程式碼,建立 Layer 的第二個版本。

runtime-tutorial$ zip runtime.zip bootstrap updating: bootstrap (deflated 39%) runtime-tutorial$ aws lambda publish-layer-version --layer-name bash-runtime --zip-file fileb://runtime.zip

設定函式以使用新版本的 Layer。

runtime-tutorial$ aws lambda update-function-configuration --function-name bash-runtime \ --layers arn:aws:lambda:us-west-2:123456789012:layer:bash-runtime:2

共享 Layer

為執行時間 Layer 加入許可陳述式,以便將其與其他帳戶共享。

runtime-tutorial$ aws lambda add-layer-version-permission --layer-name bash-runtime --version-number 2 \ --principal "*" --statement-id publish --action lambda:GetLayerVersion { "Statement": "{\"Sid\":\"publish\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"lambda:GetLayerVersion\",\"Resource\":\"arn:aws:lambda:us-west-2:123456789012:layer:bash-runtime:2\"}", "RevisionId": "9d5fe08e-2a1e-4981-b783-37ab551247ff" }

您可以加入多個陳述式,各自將許可授予單一帳戶、某個組織內的帳戶或所有帳戶。

清除

刪除各個版本的 Layer。

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

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

使用 delete-function 命令刪除本教學課程的函式。

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