チュートリアル - カスタムランタイムの公開
このチュートリアルでは、カスタムランタイムで Lambda 関数を使用します。まず、ランタイムを関数のデプロイパッケージに含めます。次に、それを関数とは別に管理するレイヤーに移行します。最後に、リソースベースのアクセス許可ポリシーを更新して、ランタイムレイヤーを世界と共有します。
前提条件
このチュートリアルでは、基本的な Lambda オペレーションと Lambda コンソールについてある程度の知識があることを前提としています。初めての方は、コンソールで Lambda の関数の作成 の手順に従って最初の Lambda 関数を作成してください。
以下の手順を完了するには、「AWS Command Line Interface (AWS CLI) バージョン 2」が必要です。コマンドと予想される出力は、別々のブロックにリストされます。
aws --version
次のような出力が表示されます。
aws-cli/2.0.57 Python/3.7.4 Darwin/19.6.0 exe/x86_64
コマンドが長い場合、コマンドを複数行に分割するためにエスケープ文字 (\
) が使用されます。
Linux および macOS では、任意のシェルとパッケージマネージャーを使用します。
注記
Windows では、Lambda でよく使用される一部の Bash CLI コマンド (zip
など) が、オペレーティングシステムの組み込みターミナルでサポートされていません。Ubuntu および Bash の Windows 統合バージョンを取得するには、Windows Subsystem for Linux をインストール
Lambda 関数を作成するには IAM ロールが必要です。ロールには、ログを CloudWatch Logs に送信し、関数で使用される AWS サービスにアクセスするためのアクセス許可が必要です。関数開発用の実行ロールをお持ちでない場合は、ここで作成します。
実行ロールを作成するには
-
IAM コンソールの [ロールページ
] を開きます。 -
[ロールの作成] を選択します。
-
次のプロパティでロールを作成します。
-
信頼されたエンティティ – 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" "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
スクリプトをロードしたら、ランタイムは、イベントをループ処理します。ランタイム 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::
{ "FunctionName": "bash-runtime", "FunctionArn": "arn:aws:lambda:us-east-1: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", ... }123456789012
:role/lambda-role
関数を呼び出し、レスポンスを確認します。
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-east-1-layers.s3.us-east-1.amazonaws.com/snapshots/123456789012/bash-runtime-018c209b...", "CodeSha256": "bXVLhHi+D3H1QbDARUVPrDwlC7bssPxySQqt1QZqusE=", "CodeSize": 584, "UncompressedCodeSize": 0 }, "LayerArn": "arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime", "LayerVersionArn": "arn:aws:lambda:us-east-1: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-east-1:
{ "FunctionName": "bash-runtime", "Layers": [ { "Arn": "arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:1", "CodeSize": 584, "UncompressedCodeSize": 679 } ] ... }123456789012
:layer:bash-runtime:1
これにより、ランタイムが /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-east-1: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-east-1:
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-east-1: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