チュートリアル - カスタムランタイムの公開 - AWS Lambda

チュートリアル - カスタムランタイムの公開

このチュートリアルでは、カスタムランタイムで Lambda 関数を使用します。まず、ランタイムを関数のデプロイパッケージに含めます。次に、それを関数とは別に管理するレイヤーに移行します。最後に、リソースベースのアクセス許可ポリシーを更新して、ランタイムレイヤーを世界と共有します。

前提条件

このチュートリアルでは、基本的な Lambda オペレーションと Lambda コンソールについてある程度の知識があることを前提としています。初めての方は、コンソールで Lambda の関数の作成 の手順に従って最初の Lambda 関数を作成してください。

次のステップを完了するには、コマンドを実行するコマンドラインターミナルまたはシェルが必要です。コマンドと予想される出力は、別々のブロックにリストされます。

aws --version

次のような出力が表示されます。

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

コマンドが長い場合、コマンドを複数行に分割するためにエスケープ文字 (\) が使用されます。

Linux および macOS では、任意のシェルとパッケージマネージャーを使用します。Windows 10 では、Linux 用の Windows サブシステムをインストールして、Windows 統合バージョンの Ubuntu および Bash を入手できます。

Lambda 関数を作成するには IAM ロールが必要です。ロールには、ログを CloudWatch Logs に送信し、関数で使用される AWS サービスにアクセスするためのアクセス許可が必要です。関数開発用の実行ロールをお持ちでない場合は、ここで作成します。

実行ロールを作成するには

  1. IAM コンソールの [roles page (ロールページ)] を開きます。

  2. [ロールの作成] を選択します。

  3. 次のプロパティでロールを作成します。

    • 信頼されたエンティティLambda

    • アクセス許可AWSLambdaBasicExecutionRole

    • ロール名lambda-role

    AWSLambdaBasicExecutionRole ポリシーには、ログを CloudWatch Logs に書き込むために関数が必要とするアクセス許可があります。

関数の作成

カスタムランタイムで Lambda 関数を作成します。この例には、ランタイム bootstrap ファイルと関数バンドラーの 2 つのファイルが含まれています。いずれのファイルも Bash で実装されています。

ランタイムは、デプロイパッケージから関数スクリプトを読み込みます。2 つの変数を使用して、スクリプトを見つけます。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"}'

レイヤーの作成

ランタイムコードと関数コードを区別するには、ランタイムのみを含むレイヤーを作成します。レイヤーを使用すると、関数の依存関係を個別に開発することができ、複数の関数で同じレイヤーを使用する場合には、ストレージの使用量を抑えることができます。

bootstrap ファイルを含むレイヤーアーカイブを作成します。

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

publish-layer-version コマンドでレイヤーを作成します。

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 }

これにより、最初のバージョンのレイヤーが作成されます。

関数の更新

関数でランタイムレイヤーを使用するには、レイヤーを使用するように関数を設定し、関数からランタイムコードを削除します。

関数設定を更新して、レイヤーに取り込みます。

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

関数を呼び出し、ランタイムレイヤーで正常に動作することを確認します。

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

新しいコードで 2 番目のレイヤーバージョンを作成します。

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

新しいバージョンのレイヤーを使用するように関数を設定します。

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

レイヤーを共有する

他のアカウントと共有するには、ランタイムレイヤーにアクセス許可ステートメントを追加します。

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

単一のアカウント、組織内のアカウント、またはすべてのアカウントにそれぞれアクセス許可を付与する複数のステートメントを追加できます。

クリーンアップ

各バージョンのレイヤーを削除します。

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 に存在します。関数は引き続き動作しますが、削除したバージョンが使用されるように、参照を設定することはできません。関数のレイヤーのリストを変更した場合は、新しいバージョンを指定するか、削除したレイヤーを除外する必要があります。

delete-function でチュートリアル用の関数を削除します。

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