チュートリアル: カスタムランタイムの構築 - AWS Lambda

チュートリアル: カスタムランタイムの構築

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

前提条件

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

以下の手順を完了するには、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 では、任意のシェルとパッケージマネージャーを使用します。

注記

Windows では、Lambda でよく使用される一部の Bash CLI コマンド (zip など) が、オペレーティングシステムの組み込みターミナルでサポートされていません。Ubuntu および Bash の Windows 統合バージョンを取得するには、Windows Subsystem for Linux をインストールします。このガイドの CLI コマンドの例では、Linux フォーマットを使用しています。Windows CLI を使用している場合、インライン JSON ドキュメントを含むコマンドを再フォーマットする必要があります。

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

実行ロールを作成するには
  1. IAM コンソールの [ロールページ] を開きます。

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

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

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

    • アクセス許可AWSLambdaBasicExecutionRole

    • ロール名lambda-role

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

関数の作成

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

  1. プロジェクト用のディレクトリを作成し、そのディレクトリに切り替えます。

    mkdir runtime-tutorial cd runtime-tutorial
  2. bootstrap という名前の新しいファイルを作成します。これはカスタムランタイムです。

    例 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

    ランタイムは、デプロイパッケージから関数スクリプトを読み込みます。2 つの変数を使用して、スクリプトを見つけます。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 を実行します。詳細については、バージョン 2 の AWS Command Line Interface ユーザーガイドの「AWS CLI でサポートされているグローバルコマンドラインオプション」を参照してください。

    次のような結果が表示されます。

    { "StatusCode": 200, "ExecutedVersion": "$LATEST" }
  7. レスポンスを確認してください。

    cat response.txt

    次のような結果が表示されます。

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

レイヤーの作成

ランタイムコードと関数コードを区別するには、ランタイムのみを含むレイヤーを作成します。レイヤーを使用すると、関数の依存関係を個別に開発することができ、複数の関数で同じレイヤーを使用する場合には、ストレージの使用量を抑えることができます。詳細については、「レイヤーによる Lambda 依存関係の管理」を参照してください。

  1. bootstrap ファイルを含む .zip ファイルを作成します。

    zip runtime.zip bootstrap
  2. publish-layer-version コマンドを使用してレイヤーを作成します。

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

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

関数の更新

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

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

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

    これにより、ランタイムが /opt ディレクトリの関数に追加されます。Lambda がレイヤーのランタイムを使用するようにするには、次の 2 つのステップに示すように、関数のデプロイパッケージから 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. 関数を呼び出し、ランタイムレイヤーで正常に動作することを確認します。

    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 を実行します。詳細については、バージョン 2 の AWS Command Line Interface ユーザーガイドの「AWS CLI でサポートされているグローバルコマンドラインオプション」を参照してください。

    次のような結果が表示されます。

    { "StatusCode": 200, "ExecutedVersion": "$LATEST" }
  5. レスポンスを確認してください。

    cat response.txt

    次のような結果が表示されます。

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

ランタイムの更新

  1. 実行環境に関する情報をログ記録するには、環境変数が出力されるようにランタイムスクリプトを更新します。

    例 bootstrap
    #!/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. 新しいバージョンのレイヤーを使用するように関数を設定します。

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

レイヤーを共有する

レイヤーを別の と共有するにはAWS アカウント、レイヤーのリソースベースのポリシー にクロスアカウントアクセス許可ステートメントを追加します。add-layer-version-permission コマンドを実行し、アカウント ID を として指定しますprincipal。アクセス許可は、各ステートメントで、1 つのアカウント、すべてのアカウント、または AWS Organizations 内の組織に付与することができます。

以下の例では、アカウント 111122223333 に bash-runtime レイヤーのバージョン 2 へのアクセス許可を付与します。

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

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

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

アクセス許可は、単一レイヤーバージョンにのみ適用されます。新しいレイヤーバージョンを作成するたびに、このプロセスを繰り返します。

クリーンアップ

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

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

delete-function コマンドを使用して関数を削除します。

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