Elastic Load Balancing
Application Load Balancer

ターゲットとしての Lambda 関数

Lambda 関数をターゲットとして登録し、Lambda 関数のターゲットグループにリクエストを転送するリスナールールを設定できます。ロードバランサーが Lambda 関数をターゲットとしてターゲットグループにリクエストを転送すると、Lambda 関数を呼び出し、リクエストのコンテンツを JSON 形式で Lambda 関数に渡します。

制限

  • Lambda 関数とターゲットグループは同じアカウントにある必要があります。

  • Lambda 関数に送信できるリクエストボディの最大サイズは 1 MB です。関連するサイズ制限の詳細については、「HTTP ヘッダーの制限」を参照してください。

  • Lambda 関数が送信できるレスポンス JSON の最大サイズは 1 MB です。

  • WebSockets はサポートされていません。アップグレードのリクエストは HTTP 400 コードで拒否されます。

Lambda 関数の準備

Application Load Balancer で Lambda 関数を使用している場合は、以下の推奨事項が適用されます。

Lambda 関数を呼び出すアクセス権限

ターゲットグループを作成し、AWS マネジメントコンソール を使用して Lambda 関数を登録すると、コンソールは必要なアクセス権限を自動的に Lambda 関数ポリシーに追加します。それ以外の場合は、ターゲットグループを作成し、AWS CLI を使用して関数を登録した後で、add-permission コマンドを使用して Lambda 関数を呼び出す Elastic Load Balancing アクセス権限を付与する必要があります。--source-arn パラメータを含めて、指定されたターゲットグループに関数の呼び出しを制限することをお勧めします。

aws lambda add-permission \ --function-name lambda-function-arn-with-alias-name \ --statement-id elb1 \ --principal elasticloadbalancing.amazonaws.com \ --action lambda:InvokeFunction \ --source-arn target-group-arn

Lambda 関数のバージョニング

ターゲットグループごとに 1 つの Lambda 関数を登録できます。Lambda 関数を変更し、ロードバランサーが常に現行バージョンの Lambda 関数を呼び出せるようにするには、関数のエイリアスを作成し、ロードバランサーに Lambda 関数を登録するときに関数 ARN にエイリアスを含めます。詳細については、AWS Lambda Developer Guideで「AWS Lambda 関数のバージョニングとエイリアス」および「エイリアスを使用したトラフィックの移行」を参照してください。

関数タイムアウト

ロードバランサーは、Lambda 関数が応答またはタイムアウトするまで待機します。予期される実行時間に基づいて Lambda 関数のタイムアウトを設定することをお勧めします。デフォルトのタイムアウト値と、その変更方法の詳細については、「基本的な AWS Lambda 関数の設定」を参照してください。設定できる最大のタイムアウト値の詳細については、「AWS Lambda の制限」を参照してください。

Lambda 関数のターゲットグループの作成

リクエストルーティングで使用されるターゲットグループを作成します。リクエストのコンテンツが、コンテンツをこのターゲットグループに転送するアクションを含むリスナールールと一致する場合、ロードバランサーは登録された Lambda 関数を呼び出します。

ターゲットグループを作成し、Lambda 関数を登録するには

  1. https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。

  2. ナビゲーションペインの [LOAD BALANCING] で [ターゲットグループ] を選択します。

  3. [Create target group] を選択します。

  4. [Target group name] で、ターゲットグループの名前を入力します。

  5. [ターゲットの種類] で、[Lambda 関数] を選択します。

  6. [Lambda 関数] で、次のいずれかを実行します。

    • Lambda 関数を選択する

    • 新しい Lambda 関数を作成し、その関数を選択する

    • ターゲットグループを作成した後で Lambda 関数を登録する

  7. (オプション) ヘルスチェックを有効にするには、[ヘルスチェック]、[有効化] の順に選択します。

  8. [作成] を選択します。

ターゲットグループを作成し、AWS CLI を使用して Lambda 関数の登録を解除するには

create-target-groupregister-targets コマンドを使用します。

ロードバランサーからのイベントの受け取り

ロードバランサーは、HTTP と HTTPS の両方でリクエストの Lambda 呼び出しをサポートしています。ロードバランサーは、JSON 形式でイベントを送信します。ロードバランサーは、リクエストごとに X-Amzn-Trace-IdX-Forwarded-ForX-Forwarded-PortX-Forwarded-Proto の各ヘッダーを追加します。

コンテンツタイプが、text/*、application/json、application/javascript、application/xml のいずれかである場合、ロードバランサーは Lambda 関数に本文をそのまま送信し、isBase64Encodedfalse に設定します。他のすべてのタイプでは、ロードバランサーは本文を Base64 でエンコードし、isBase64Encodedtrue に設定します。

以下に示しているのは、イベントの例です。

{ "requestContext": { "elb": { "targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/my-target-group/6d0ecf831eec9f09" } }, "httpMethod": "GET", "path": "/", "queryStringParameters": {parameters}, "headers": { "accept": "text/html,application/xhtml+xml", "accept-language": "en-US,en;q=0.8", "content-type": "text/plain", "cookie": "cookies", "host": "lambda-846800462-us-east-2.elb.amazonaws.com", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6)", "x-amzn-trace-id": "Root=1-5bdb40ca-556d8b0c50dc66f0511bf520", "x-forwarded-for": "72.21.198.66", "x-forwarded-port": "443", "x-forwarded-proto": "https" }, "isBase64Encoded": false, "body": "request_body" }

ロードバランサーへの応答

Lambda 関数からのレスポンスには、Base64 エンコーディングのステータス、ステータスコード、ステータスの説明、およびヘッダーが含まれます。本文は省略できます。statusDescription ヘッダーには、ステータスコードと理由フレーズが 1 つのスペースで区切って含まれている必要があります。

レスポンス本文にバイナリコンテンツを含めるには、コンテンツを Base64 でエンコードし、isBase64Encodedtrue に設定する必要があります。ロードバランサーはコンテンツをデコードしてバイナリコンテンツを取得し、そのコンテンツを HTTP レスポンスの本文でクライアントに送信します。

ロードバランサーはホップバイホップのヘッダー (ConnectionTransfer-Encoding など) を優先しません。ロードバランサーがクライアントにレスポンスを送信する前に計算するため、Content-Length ヘッダーは省略できます。

Lambda 関数からのレスポンスの例を次に示します。

{ "isBase64Encoded": false, "statusCode": 200, "statusDescription": "200 OK", "headers": { "Set-cookie": "cookies", "Content-Type": "application/json" }, "body": "Hello from Lambda (optional)" }

Application Load Balancer で動作する Lambda 関数のテンプレートについては、github の「application-load-balancer-serverless-app」を参照してください。または、Lambda コンソールを開き、関数を作成して、AWS Serverless Application Repository から次のいずれかを選択します。

  • ALB-Lambda-Target-HelloWorld

  • ALB-Lambda-Target-UploadFiletoS3

  • ALB-Lambda-Target-BinaryResponse

  • ALB-Lambda-Target-WhatisMyIP

複数値のヘッダー

クライアントからのリクエストまたは Lambda 関数からのレスポンスに、複数の値を含むヘッダーが含まれている場合、または同じヘッダーが複数回含まれている場合、複数値のヘッダー構文のサポートを有効にできます。複数値のヘッダーを有効にすると、ロードバランサーと Lambda 関数との間で交換されるリクエストとレスポンスのヘッダーで、配列が使用されます。それ以外の場合、ロードバランサーは受け取った最後の値を使用します。

複数値ヘッダーを持つリクエスト

ヘッダーおよびクエリ文字列パラメータに使用されるフィールドの名前は、ターゲットグループに対して複数値ヘッダーを有効にするかどうかによって異なります。

次のリクエスト例には、同じキーを持つ 2 つのクエリパラメータがあります。

http://www.example.com?&myKey=val1&myKey=val2

デフォルトの形式では、ロードバランサーはクライアントによって送信された最後の値を使用し、queryStringParameters を使用してクエリ文字列パラメータを含むイベントを送信します。次に例を示します。

"queryStringParameters": { "myKey": "val2"},

複数値ヘッダーを有効にした場合、ロードバランサーはクライアントから送信された両方のキー値を使用し、multiValueQueryStringParameters を使用してクエリ文字列パラメータを含むイベントを送信します。次に例を示します。

"multiValueQueryStringParameters": { "myKey": ["val1", "val2"] },

同様に、クライアントがヘッダーに 2 つの Cookie を含むリクエストを送信するとします。

"cookie": "name1=value1", "cookie": "name2=value2",

デフォルトの形式では、ロードバランサーはクライアントによって送信された最後の Cookie を使用し、headers を使用してヘッダーを含むイベントを送信します。次に例を示します。

"headers": { "cookie": "name2=value2", ... },

複数値ヘッダーを有効にすると、ロードバランサーはクライアントによって送信された両方の Cookie を使用し、multiValueHeaders を使用してヘッダーを含むイベントを送信します。次に例を示します。

"multiValueHeaders": { "cookie": ["name1=value1", "name2=value2"], ... },

複数値ヘッダーを持つレスポンス

ヘッダーに使用されるフィールドの名前は、ターゲットグループに対して複数値ヘッダーを有効にするかどうかによって異なります。複数値ヘッダーを有効にしている場合は multiValueHeaders を使用し、それ以外の場合は headers を使用する必要があります。

デフォルトの形式では、単一の Cookie を指定できます。

{ "headers": { "Set-cookie": "cookie-name=cookie-value;Domain=myweb.com;Secure;HttpOnly", "Content-Type": "application/json" }, }

複数値のヘッダーを有効にすると、複数の Cookie を次のように指定できます。

{ "multiValueHeaders": { "Set-cookie": ["cookie-name=cookie-value;Domain=myweb.com;Secure;HttpOnly","cookie-name=cookie-value;Expires=May 8, 2019"], "Content-Type": ["application/json"] }, }

複数値のヘッダーの有効化

ターゲットの種類が lambda であるターゲットグループに対して、複数値のヘッダーを有効または無効にすることができます。

コンソールを使用して複数値のヘッダーを有効にするには

  1. https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。

  2. ナビゲーションペインの [LOAD BALANCING] で [ターゲットグループ] を選択します。

  3. ターゲットグループを選択します。

  4. [説明] タブで、[属性の編集] を選択します。

  5. [Multi value headers (複数値ヘッダー)] の場合は、[Enable (有効化)] を選択します。

  6. [Save] を選択します。

AWS CLI を使用して複数値のヘッダーを有効にするには

lambda.multi_value_headers.enabled 属性を指定して modify-target-group-attributes コマンドを使用します。

ヘルスチェックの有効化

デフォルトでは、ヘルスチェックは種類が lambda のターゲットグループに対しては無効になっています。Amazon Route 53 を使用して DNS フェイルオーバーを実装するには、ヘルスチェックを有効にできます。Lambda 関数は、ヘルスチェックリクエストに応答する前に、ダウンストリームサービスの状態を確認できます。Lambda 関数からのレスポンスでヘルスチェックの失敗が示された場合、ヘルスチェックの失敗が Route 53 に渡されます。バックアップアプリケーションスタックにフェイルオーバーするよう Route 53 を設定できます。

ヘルスチェックについては、他の Lambda 関数の呼び出しと同じように課金されます。

Lambda 関数に送信されるヘルスチェックの形式は次のとおりです。イベントがヘルスチェックイベントかどうかを確認するには、ユーザーエージェントフィールドの値を確認します。ヘルスチェックのユーザーエージェントは ELB-HealthChecker/2.0 です。

{ "requestContext": { "elb": { "targetGroupArn": "arn:aws:elasticloadbalancing:region:123456789012:targetgroup/my-target-group/6d0ecf831eec9f09" } }, "httpMethod": "GET", "path": "/", "queryStringParameters": {}, "headers": { "user-agent": "ELB-HealthChecker/2.0" }, "body": "", "isBase64Encoded": false }

ターゲットグループのヘルスチェックを有効にするには

  1. https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。

  2. ナビゲーションペインの [LOAD BALANCING] で [ターゲットグループ] を選択します。

  3. ターゲットグループを選択します。

  4. [ヘルスチェック] タブで [ヘルスチェックの編集] を選択します。

  5. [Health check (ヘルスチェック)] で、[Enable (有効化)] を選択します。

  6. [Save] を選択します。

AWS CLI を使用してターゲットグループのヘルスチェックを有効にするには

modify-target-group コマンドを使用し、--health-check-enabled オプションを指定します。

Lambda 関数の登録解除

トラフィックを Lambda 関数に送信する必要がなくなった場合は、登録を解除できます。Lambda 関数の登録を解除すると、未処理のリクエストは HTTP 5XX エラーで失敗します。

Lambda 関数を置き換えるには、新しいターゲットグループを作成し、新しい関数を新しいターゲットグループに登録し、リスナールールを更新して既存のターゲットグループではなく新しいターゲットグループを使用することをお勧めします。

Lambda 関数を登録解除するには

  1. https://console.aws.amazon.com/ec2/) にある Amazon EC2 コンソールを開きます。

  2. ナビゲーションペインの [LOAD BALANCING] で [ターゲットグループ] を選択します。

  3. ターゲットグループを選択します。

  4. [ターゲット] タブで、[登録解除] を選択します。

  5. [登録解除] を選択します。

AWS CLI を使用して Lambda 関数を登録解除するには

deregister-targets コマンドを使用します。