Lambda 拡張機能 API を使用した拡張機能の作成 - AWS Lambda

Lambda 拡張機能 API を使用した拡張機能の作成

Lambda 関数の作成者は、拡張機能を使用して、Lambda を、モニタリング、可観測性、セキュリティ、およびガバナンスのための任意のツールと統合します。関数作成者は、AWS、AWS パートナー、およびオープンソースプロジェクトの拡張機能を使用できます。拡張機能の使用の詳細については、AWS Lambda コンピューティングブログの AWS 拡張機能の紹介を参照してください。このセクションでは、Lambda Extensions API、Lambda 実行環境ライフサイクル、および Lambda Extensions API リファレンスを使用する方法を説明します。

Extensions API と Telemetry API は、Lambda と外部拡張機能を接続します。

拡張機能の作成者は、Lambda Extensions API を使用して Lambda 実行環境に深く統合することができます。拡張機能は、関数および実行環境のライフサイクルイベントに登録できます。これらのイベントに対応して、新しいプロセスを開始し、ロジックを実行し、Lambda ライフサイクルのすべてのフェーズ (初期化、呼び出し、およびシャットダウン) を制御し、これらに参加することができます。さらに、Runtime Logs API を使用して、ログのストリームを受信できます。

拡張機能は、実行環境で独立したプロセスとして実行され、関数の呼び出しが完全に処理された後も引き続き実行できます。拡張機能はプロセスとして実行されるため、関数とは異なる言語で記述できます。コンパイルされた言語を使用して拡張機能を実装することをお勧めします。この場合、拡張機能は、サポートされているランタイムと互換性のある自己完結型のバイナリです。すべての Lambda ランタイム は拡張機能をサポートします。コンパイルされていない言語を使用する場合は、必ず互換性のあるランタイムを拡張機能に含めてください。

Lambda は内部拡張機能もサポートしています。内部拡張機能は、ランタイムプロセスで別のスレッドとして実行されます。ランタイムは、内部拡張を開始および停止します。Lambda 環境と統合する別の方法は、言語固有の環境変数とラッパースクリプトを使用することです。これらを使用して、ランタイム環境を設定し、ランタイムプロセスの起動動作を変更できます。

関数に拡張機能を追加するには、次の 2 つの方法があります。.zip ファイルアーカイブとしてデプロイされた関数では、拡張機能をレイヤーとしてデプロイします。コンテナイメージとして定義された関数の場合は、コンテナイメージに拡張機能を追加します。

注記

拡張機能とラッパースクリプトの例については、AWS Lambda サンプル GitHub リポジトリの 「AWS拡張」を参照してください。

Lambda 実行環境のライフサイクル

実行環境のライフサイクルには、以下のフェーズが含まれています。

  • Init: このフェーズ中、Lambda は、設定したリソースを使用して実行環境を作成またはフリーズ解除し、関数コードとすべてのレイヤーをダウンロードして、拡張機能とランタイムを初期化し、関数の初期化コード (メインハンドラーの外部にあるコード) を実行します。Init フェーズは、最初の呼び出し中か、プロビジョニング済みの同時実行を有効にしている場合は関数呼び出しの前に、発生します。

    Init フェーズは、Extension initRuntime initFunction init の 3 つのサブフェーズに分割されます。これらのサブフェーズでは、関数コードが実行される前に、すべての拡張機能とランタイムがそのセットアップタスクを完了します。

  • Invoke: このフェーズでは、Lambda は関数ハンドラーを呼び出します。関数が実行され、完了すると、Lambda は、別の関数呼び出しを処理する準備をします。

  • Shutdown: このフェーズは、Lambda 関数が一定期間呼び出しを受け取らなかった場合にトリガーされます。Shutdown フェーズでは、Lambda はランタイムをシャットダウンし、拡張機能にアラートを出してそれらを完全に停止させた後、環境を削除します。Lambda は、各拡張機能に Shutdown イベントを送信します。これにより、環境がシャットダウンされようとしていることを各拡張機能に伝えます。

各フェーズは、Lambda からランタイム、および登録されたすべての拡張機能へのイベントから始まります。ランタイムと各拡張機能は、Next API リクエストを送信することで完了を示します。Lambda は、各プロセスが完了して保留中のイベントがなくなると、実行環境をフリーズします。

拡張機能の Lambda 実行環境ライフサイクル

初期化フェーズ

Extension init フェーズの間、各拡張機能モジュールは、イベントを受信するために Lambda に登録されている必要があります。Lambda は、拡張機能がブートストラップシーケンスを完了していることを検証するために、拡張機能の完全なファイル名を使用します。したがって、各 Register API コールには、拡張機能の完全なファイル名を持つ Lambda-Extension-Name ヘッダーを含める必要があります。

1 つの関数に最大 10 個の拡張機能を登録できます。この制限は、Register API コールを通じて適用されます。

各拡張機能が登録されると、Lambda は Runtime init フェーズを開始します。ランタイムプロセスは functionInit を呼び出して Function init フェーズを開始します。

Init フェーズはランタイム後に完了します。登録された各拡張機能は、Next API リクエストを送信することで完了を示します。

注記

拡張機能は、Init フェーズの任意の時点で初期化を完了できます。

Lambda 初期化フェーズにおけるイベントのシーケンス

呼び出しフェーズ

Next API リクエストに応答して Lambda 関数が呼び出されると、Lambda は、ランタイム、および Invoke イベントに登録されている各拡張機能に、Invoke イベントを送信します。

呼び出し中、外部拡張機能は関数と並行して実行されます。また、関数が完了した後も、引き続き実行されます。これにより、診断情報をキャプチャしたり、ログ、メトリクス、トレースを任意の場所に送信したりできます。

ランタイムから関数応答を受信した後、拡張機能がまだ実行中であっても、Lambda はクライアントに応答を返します。

Invoke フェーズはランタイム後に終了します。すべての拡張機能は、Next API リクエストを送信することによって完了を示します。

Lambda 呼び出しフェーズにおけるイベントのシーケンス

イベントペイロード:ランタイムに送信されるイベント(および Lambda 関数)は、リクエスト、ヘッダー (RequestId など) およびペイロード全体を保持します。各拡張機能に送信されるイベントには、イベントの内容を説明するメタデータが含まれます。このライフサイクルイベントには、イベントのタイプ、関数のタイムアウト時間 (deadlineMs) 、requestId、呼び出された関数の Amazon リソースネーム (ARN) 、およびトレースヘッダーが含まれます。

関数イベント本体にアクセスする拡張機能は、その拡張機能と通信するインランタイム SDK を使用できます。関数のデベロッパーは、関数が呼び出されたときにインランタイム SDK を使用して、拡張機能にペイロードを送信します。

ペイロードの例を次に示します。

{ "eventType": "INVOKE", "deadlineMs": 676051, "requestId": "3da1f2dc-3222-475e-9205-e2e6c6318895", "invokedFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:ExtensionTest", "tracing": { "type": "X-Amzn-Trace-Id", "value": "Root=1-5f35ae12-0c0fec141ab77a00bc047aa2;Parent=2be948a625588e32;Sampled=1" } }

所要時間の制限: 関数のタイムアウト設定では、Invoke フェーズ全体の所要時間を制限します。例えば、関数のタイムアウトを 360 秒に設定した場合、関数とすべての拡張機能は 360 秒以内に完了する必要があります。独立した呼び出し後フェーズはないことに注意してください。所要時間はランタイムおよびすべての拡張機能の呼び出しが完了するまでの合計時間であり、関数およびすべての拡張機能の実行が終了するまで計算されません。

パフォーマンスの影響と拡張機能のオーバーヘッド: 拡張機能は、関数のパフォーマンスに影響を与える可能性があります。拡張機能の作成者は、拡張機能のパフォーマンスへの影響を制御する必要があります。例えば、拡張機能でコンピューティング負荷の高い操作を実行した場合、拡張機能と関数コードで同じ CPU リソースを共有するため、関数の実行時間が長くなります。さらに、関数呼び出しの完了後に拡張機能が広範な操作を実行する場合、すべての拡張機能が完了を示すまで Invoke フェーズが継続するため、関数の実行時間が長くなります。

注記

Lambda は、関数のメモリ設定に比例して CPU パワーを割り当てます。関数と拡張機能のプロセスが同じ CPU リソースで競合するため、メモリ設定が小さい場合、実行時間と初期化時間が長くなることがあります。実行時間と初期化時間を短縮するには、メモリ設定を引き上げてみてください。

Invoke フェーズで拡張機能によって発生したパフォーマンスへの影響を確認できるように、Lambda は PostRuntimeExtensionsDuration メトリクスを出力します。このメトリクスでは、ランタイム Next API リクエストから最後の拡張機能の Next API リクエストまでの累積時間が測定されます。使用されるメモリの増加を測定するには、MaxMemoryUsed メトリクスを使用します。関数のメトリクスの詳細については、「Lambda 関数のメトリクスを表示する」を参照してください。

関数のデベロッパーは、異なるバージョンの関数を並行して実行して、特定の拡張機能の影響を把握することができます。拡張機能の作成者は、関数のデベロッパーが適切な拡張機能を選択しやすくするために、予想されるリソース消費を公開することをお勧めします。

シャットダウンフェーズ

Lambda は、ランタイムをシャットダウンしようとする際に、登録された各外部拡張機能に Shutdown を送信します。拡張機能は、この時間を最終的なクリーンアップタスクに使用できます。Shutdown イベントは Next API リクエストに応答して送信されます。

所要時間の制限: Shutdown フェーズの最大所要時間は、登録された拡張機能の設定によって異なります。

  • 0 ms – 登録された拡張機能を持たない関数

  • 500 ms - 登録された内部拡張機能を持つ関数

  • 2000 ms - 登録された外部拡張機能を 1 つ以上持つ関数

外部拡張機能を持つ関数の場合、Lambda はランタイムプロセスがグレースフルシャットダウンを実行するために、最大 300 ms (内部拡張機能を持つランタイムでは 500 ms) を予約します。Lambda は、外部拡張機能をシャットダウンするために 2,000 ミリ秒の制限の残りを割り当てます。

ランタイムまたは拡張機能が制限内で Shutdown イベントに応答しない場合、Lambda は SIGKILL の通知を使用してプロセスを終了します。

Lambda シャットダウンフェーズにおけるイベントのシーケンス

イベントペイロード: Shutdown イベントには、シャットダウンの理由と残り時間 (ミリ秒単位) が含まれます。

shutdownReason には次の値が含まれています。

  • SPINDOWN - 正常なシャットダウン

  • TIMEOUT - 所要時間の制限がタイムアウトしました

  • FAILURE - エラー状態 (out-of-memory イベントなど)

{ "eventType": "SHUTDOWN", "shutdownReason": "reason for shutdown", "deadlineMs": "the time and date that the function times out in Unix time milliseconds" }

アクセス許可と設定

拡張機能は、Lambda 関数と同じ実行環境で実行されます。拡張機能は、CPU、メモリ、/tmp ディスクストレージなどのリソースも関数と共有します。さらに、関数と同じ AWS Identity and Access Management (IAM) ロールとセキュリティコンテキストが使用されます。

ファイルシステムとネットワークアクセス許可: 拡張機能は、関数ランタイムと同じファイルシステムおよびネットワーク名の名前空間で実行されます。つまり、拡張機能は関連するオペレーティングシステムと互換性がある必要があります。拡張機能で追加の 送信ネットワークトラフィック ルールが必要な場合は、これらのルールを関数の設定に適用する必要があります。

注記

関数コードディレクトリは読み取り専用であるため、拡張機能は関数コードを変更できません。

環境変数: 拡張機能は、関数の環境変数にアクセスできます。ただし、ランタイムプロセスに固有の次の変数は除きます。

  • AWS_EXECUTION_ENV

  • AWS_LAMBDA_LOG_GROUP_NAME

  • AWS_LAMBDA_LOG_STREAM_NAME

  • AWS_XRAY_CONTEXT_MISSING

  • AWS_XRAY_DAEMON_ADDRESS

  • LAMBDA_RUNTIME_DIR

  • LAMBDA_TASK_ROOT

  • _AWS_XRAY_DAEMON_ADDRESS

  • _AWS_XRAY_DAEMON_PORT

  • _HANDLER

障害処理

初期化の失敗: 拡張機能が失敗した場合、Lambda は実行環境を再起動して一貫した動作を適用し、拡張機能のフェイルファストを推奨します。また、お客様によっては、拡張機能が、ログ記録、セキュリティ、ガバナンス、テレメトリ収集などのミッションクリティカルなニーズを満たす必要があります。

呼び出しの失敗(メモリ不足、関数のタイムアウトなど): 拡張機能はランタイムとリソースを共有するため、メモリが消耗した場合に影響を受けます。ランタイムが失敗すると、すべての拡張機能とランタイム自体が Shutdown フェーズに参加します。さらにランタイムは、現在の呼び出しの一部として、または遅延された再初期化メカニズムを通じて、自動的に再起動されます。

Invoke 中に障害が発生した場合 (関数のタイムアウトやランタイムエラーなど)、 Lambda サービスはリセットを実行します。リセットは Shutdown イベントのように動作します。まず、Lambda はランタイムをシャットダウンし、登録された各外部拡張機能に Shutdown イベントを送信します。イベントには、シャットダウンの理由が含まれます。この環境が新しい呼び出しに使用される場合、拡張機能とランタイムは次の呼び出しの一部として再初期化されます。

実行環境の例: Init、Invoke、Invoke with Error、Invoke、Shutdown

前示の図の詳細については、「呼び出しフェーズ中の失敗」を参照してください。

拡張機能のログ: Lambda は、拡張機能のログ出力を CloudWatch Logs に送信します。また Lambda は、Init 中に各拡張機能に対して追加のログイベントも生成します。ログイベントは、成功時には名前と登録設定 (event、config) を記録し、失敗時には失敗理由を記録します。

拡張機能のトラブルシューティング

  • Register リクエストが失敗した場合は、Lambda-Extension-Name API コールの Register ヘッダーに拡張機能の完全なファイル名が含まれていることを確認します。

  • 内部拡張機能に対する Register リクエストが失敗した場合は、そのリクエストが Shutdown イベントに登録されていないことを確認します。

拡張機能 API リファレンス

拡張機能 API バージョン 2020-01-01 の OpenAPI 仕様は、こちらから入手できます: extensions-api.zip

API エンドポイントの値は、AWS_LAMBDA_RUNTIME_API 環境変数から取得できます。Register リクエストを送信するには、各 API パスの前にプレフィックス 2020-01-01/ を使用します。以下に例を示します。

http://${AWS_LAMBDA_RUNTIME_API}/2020-01-01/extension/register

登録

Extension init 中、すべての拡張機能は、イベントを受信するために Lambda に登録される必要があります。Lambda は、拡張機能がブートストラップシーケンスを完了していることを検証するために、拡張機能の完全なファイル名を使用します。したがって、各 Register API コールには、拡張機能の完全なファイル名を持つ Lambda-Extension-Name ヘッダーを含める必要があります。

内部拡張機能はランタイムプロセスによって開始および停止されるため、Shutdown イベントへの登録は許可されません。

パス/extension/register

メソッド - POST

リクエストヘッダー

  • Lambda-Extension-Name - 拡張機能の完全なファイル名。必須: はい。タイプ: 文字列。

  • Lambda-Extension-Accept-Feature – これを使用して、登録時にオプションの拡張機能を指定します。必須: いいえ。型: カンマで区切られた文字列。この設定を使用して指定できる機能:

    • accountId – これを指定した場合は、拡張機能登録レスポンスに、拡張機能を登録している Lambda 関数に関連付けられたアカウント ID が含まれます。

リクエストボディのパラメータ
  • events - 登録するイベントの配列。必須: いいえ。型: 文字列の配列 有効な文字列: INVOKESHUTDOWN

レスポンスヘッダー
  • Lambda-Extension-Identifier - それ以降のすべてのリクエストに必要な、生成された一意のエージェント識別子 (UUID 文字列)。

レスポンスコード
  • 200 - レスポンス本文には、関数名、関数バージョン、およびハンドラー名が含まれます。

  • 400 – Bad Request

  • 403 – Forbidden

  • 500 – Container error 回復不能な状態。拡張機能はすぐに終了する必要があります。

例 リクエストボディの例
{ 'events': [ 'INVOKE', 'SHUTDOWN'] }
例 レスポンスの例
{ "functionName": "helloWorld", "functionVersion": "$LATEST", "handler": "lambda_function.lambda_handler" }
例 オプションの accountId 機能が含まれたレスポンスボディの例
{ "functionName": "helloWorld", "functionVersion": "$LATEST", "handler": "lambda_function.lambda_handler", "accountId": "123456789012" }

次へ

拡張機能は Next API リクエストを送信して、次のイベント (Invokeイベントまたは Shutdown イベント) を受信します。レスポンス本文にはペイロードが含まれます。ペイロードは、イベントデータを含む JSON ドキュメントです。

拡張機能は、新しいイベントを受信する準備ができていることを示す Next API リクエストを送信します。これはブロック呼び出しです。

拡張機能は一定期間中断される可能性があるため、返されるイベントが発生するまで、GET 呼び出しにタイムアウトを設定しないでください。

パス/extension/event/next

メソッド - GET

リクエストヘッダー
  • Lambda-Extension-Identifier - 拡張機能の一意の識別子 (UUID 文字列)。必須: はい。型: UUID 文字列。

レスポンスヘッダー
  • Lambda-Extension-Event-Identifier – イベントの一意の識別子 (UUID 文字列)。

レスポンスコード
  • 200 - レスポンスには、次のイベント (EventInvoke または EventShutdown) に関する情報が含まれます。

  • 403 – Forbidden

  • 500 – Container error 回復不能な状態。拡張機能はすぐに終了する必要があります。

初期化エラー

拡張機能はこのメソッドを使用して、初期化エラーを Lambda に報告します。拡張機能が登録後に初期化に失敗した場合に呼び出します。Lambda がエラーを受信すると、それ以降の API コールは成功しません。拡張機能は、Lambda からの応答を受信した後に終了する必要があります。

パス/extension/init/error

メソッド - POST

リクエストヘッダー
  • Lambda-Extension-Identifier - 拡張機能の一意の識別子。必須: はい。型: UUID 文字列。

  • Lambda-Extension-Function-Error-Type - 拡張機能が検出したエラータイプ。必須: はい。このヘッダーは、文字列値で構成されています。Lambda はどのような文字列でも受け入れますが、形式は <category.reason> にすることが推奨されます。例:

    • Extension.NoSuchHandler

    • Extension.APIKeyNotFound

    • Extension.ConfigInvalid

    • Extension.UnknownReason

リクエストボディのパラメータ
  • ErrorRequest - エラーに関する情報。必須: いいえ。

このフィールドは、次の構造を持つ JSON オブジェクトです。

{ errorMessage: string (text description of the error), errorType: string, stackTrace: array of strings }

Lambda は、errorType として任意の値を受け入れることに注意してください。

次の例は、呼び出しで指定されたイベントデータを関数で解析できなかった Lambda 関数のエラーメッセージを示しています。

例 関数エラー
{ "errorMessage" : "Error parsing event data.", "errorType" : "InvalidEventDataException", "stackTrace": [ ] }
レスポンスコード
  • 202 - Accepted

  • 400 – Bad Request

  • 403 – Forbidden

  • 500 – Container error 回復不能な状態。拡張機能はすぐに終了する必要があります。

終了エラー

拡張機能は、このメソッドを使用して、終了する前に Lambda にエラーを報告します。予期しない障害が発生したときに呼び出します。Lambda がエラーを受信すると、それ以降の API コールは成功しません。拡張機能は、Lambda からの応答を受信した後に終了する必要があります。

パス/extension/exit/error

メソッド - POST

リクエストヘッダー
  • Lambda-Extension-Identifier - 拡張機能の一意の識別子。必須: はい。型: UUID 文字列。

  • Lambda-Extension-Function-Error-Type - 拡張機能が検出したエラータイプ。必須: はい。このヘッダーは、文字列値で構成されています。Lambda はどのような文字列でも受け入れますが、形式は <category.reason> にすることが推奨されます。例:

    • Extension.NoSuchHandler

    • Extension.APIKeyNotFound

    • Extension.ConfigInvalid

    • Extension.UnknownReason

リクエストボディのパラメータ
  • ErrorRequest - エラーに関する情報。必須: いいえ。

このフィールドは、次の構造を持つ JSON オブジェクトです。

{ errorMessage: string (text description of the error), errorType: string, stackTrace: array of strings }

Lambda は、errorType として任意の値を受け入れることに注意してください。

次の例は、呼び出しで指定されたイベントデータを関数で解析できなかった Lambda 関数のエラーメッセージを示しています。

例 関数エラー
{ "errorMessage" : "Error parsing event data.", "errorType" : "InvalidEventDataException", "stackTrace": [ ] }
レスポンスコード
  • 202 - Accepted

  • 400 – Bad Request

  • 403 – Forbidden

  • 500 – Container error 回復不能な状態。拡張機能はすぐに終了する必要があります。