

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Lambda 関数を Application Load Balancer のターゲットとして使用する
<a name="lambda-functions"></a>

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

ロードバランサーは、ネットワーク接続を使用する代わりに Lambda 関数を直接呼び出します。したがって、Application Load Balancer セキュリティグループのアウトバウンドルールの要件はありません。

**制限**
+ Lambda 関数とターゲットグループは、同じアカウントおよび同じリージョンにある必要があります。
+ Lambda 関数に送信できるリクエストボディの最大サイズは 1 MB です。関連するサイズ制限の詳細については、[HTTP ヘッダーの制限](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html#http-header-limits)を参照してください。
+ Lambda 関数が送信できるレスポンス JSON の最大サイズは 1 MB です。
+ WebSockets はサポートされていません。アップグレードのリクエストは HTTP 400 コードで拒否されます。
+ Local Zones はサポートされていません。
+ 自動ターゲット加重 (ATW) はサポートされていません。

**Topics**
+ [Lambda 関数の準備](#prepare-lambda-function)
+ [Lambda 関数のターゲットグループの作成](#create-lambda-target-group)
+ [ロードバランサーからのイベントの受け取り](#receive-event-from-load-balancer)
+ [ロードバランサーへの応答](#respond-to-load-balancer)
+ [複数値ヘッダー](#multi-value-headers)
+ [ヘルスチェックの有効化](#enable-health-checks-lambda)
+ [Lambda 関数を登録する](#register-lambda-function)
+ [Lambda 関数の登録解除](#deregister-lambda-function)

デモについては、[Application Load Balancer の Lambda ターゲット](https://exampleloadbalancer.com/lambda_demo.html)を参照してください。

## Lambda 関数の準備
<a name="prepare-lambda-function"></a>

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

**Lambda 関数を呼び出すアクセス許可**  
ターゲットグループを作成し、 AWS マネジメントコンソールを使用して Lambda 関数を登録すると、コンソールは必要なアクセス権限を自動的に Lambda 関数ポリシーに追加します。それ以外の場合は、ターゲットグループを作成し、 を使用して関数を登録した後 AWS CLI、[add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) コマンドを使用して、Lambda 関数を呼び出すアクセス許可を Elastic Load Balancing に付与する必要があります。`aws:SourceAccount` および `aws:SourceArn` の条件キーを使用して、関数の呼び出しを指定のターゲットグループに制限することをお勧めします。詳細については、*IAM ユーザーガイド* の「[「混乱した代理」問題](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html)」を参照してください。

```
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 \
    --source-account target-group-account-id
```

**Lambda 関数のバージョニング**  
ターゲットグループごとに 1 つの Lambda 関数を登録できます。Lambda 関数を変更し、ロードバランサーが常に現行バージョンの Lambda 関数を呼び出せるようにするには、関数のエイリアスを作成し、ロードバランサーに Lambda 関数を登録するときに関数 ARN にエイリアスを含めます。詳細については、「*AWS Lambda デベロッパーガイド*」の「[AWS Lambda 関数のエイリアス](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html)」を参照してください。

**関数タイムアウト**  
ロードバランサーは、Lambda 関数が応答またはタイムアウトするまで待機します。予期される実行時間に基づいて Lambda 関数のタイムアウトを設定することをお勧めします。デフォルトのタイムアウト値と、その変更方法の詳細については、「[Lambda 関数のタイムアウトを設定する](https://docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html)」を参照してください。設定できる最大のタイムアウト値の詳細については、「[AWS Lambda のクォータ](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html)」を参照してください。

## Lambda 関数のターゲットグループの作成
<a name="create-lambda-target-group"></a>

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

------
#### [ Console ]

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

1. Amazon EC2 コンソールの [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) を開いてください。

1. ナビゲーションペインの [**ロードバランシング**] で [**ターゲットグループ**] を選択します。

1. **[ターゲットグループの作成]** を選択します。

1. [**ターゲットタイプの選択**] で [**Lambda 関数**] を選択します。

1. [**ターゲットグループ名**] に、ターゲットグループの名前を入力します。

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

1. (オプション) **タグ** を展開します。追加するタグごとに、**[新しいタグを追加]** を選択し、タグキーとタグ値を入力します。

1. [**次へ**] を選択します。

1. Lambda 関数を登録する準備ができたら、**[Lambda 関数を選択]** を選択してリストから Lambda 関数を選択するか、**[Lambda 関数 ARN を入力]** を選択して Lambda 関数の ARN を入力します。

   Lambda 関数を登録する準備ができていない場合は、**[後で Lambda 関数を登録]** を選択し、後でターゲットを登録します。詳細については、「[ターゲットの登録](target-group-register-targets.md#register-targets)」を参照してください。

1. **[ターゲットグループの作成]** を選択します。

------
#### [ AWS CLI ]

**lambda タイプの対象グループを作成するには**  
[create-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/create-target-group.html) コマンドを使用します。

```
aws elbv2 create-target-group \
    --name my-target-group \
    --target-type lambda
```

**Lambda 関数を登録するには**  
[register-targets](https://docs.aws.amazon.com/cli/latest/reference/elbv2/register-targets.html) コマンドを使用します。

```
aws elbv2 register-targets \
    --target-group-arn target-group-arn \
    --targets Id=lambda-function-arn
```

------
#### [ CloudFormation ]

**ターゲットグループを作成し、Lambda 関数を登録するには**  
[AWS::ElasticLoadBalancingV2::TargetGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html) リソースタイプを定義します。Lambda 関数を今すぐ登録する準備ができていない場合は、`Targets` プロパティを省略して後で追加できます。

```
Resources:
  myTargetGroup:
    Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
    Properties:
      Name: my-target-group
      TargetType: lambda
      Tags: 
        - Key: 'department'
          Value: '123'
      Targets:
        - Id: !Ref myLambdaFunction
```

------

## ロードバランサーからのイベントの受け取り
<a name="receive-event-from-load-balancer"></a>

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

`content-encoding` ヘッダーが存在する場合、ロードバランサー Base64 は本体をエンコードし、`isBase64Encoded` を `true` に設定します。

`content-encoding` ヘッダーが存在しない場合、Base64 エンコーディングはコンテンツタイプによって異なります。タイプが text/\$1、application/json、application/javascript、application/xml である場合、ロードバランサーは本文をそのまま送信し、`isBase64Encoded` を `false` に設定します。それ以外の場合、ロードバランサー Base64 は本文をエンコードし、`isBase64Encoded` を `true` に設定します。

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

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

## ロードバランサーへの応答
<a name="respond-to-load-balancer"></a>

Lambda 関数からのレスポンスには、Base64 エンコーディングのステータス、ステータスコード、およびヘッダーが含まれます。本文は省略できます。

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

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

**nodejs** をベースとした 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](https://github.com/aws/elastic-load-balancing-tools/tree/master/application-load-balancer-serverless-app) を参照してください。または、[Lambda コンソール](https://console.aws.amazon.com/lambda)を開き、**[アプリケーション]** から **[アプリケーションを作成]** を選択し、 AWS Serverless Application Repository から次のいずれかを選択します。
+ ALB-Lambda-Target-UploadFiletoS3
+ ALB-Lambda-Target-BinaryResponse
+ ALB-Lambda-Target-WhatisMyIP

## 複数値ヘッダー
<a name="multi-value-headers"></a>

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

**Topics**
+ [複数値ヘッダーを持つリクエスト](#multi-value-headers-request)
+ [複数値ヘッダーを持つレスポンス](#multi-value-headers-response)
+ [複数値ヘッダーの有効化](#enable-multi-value-headers)

### 複数値ヘッダーを持つリクエスト
<a name="multi-value-headers-request"></a>

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

次のリクエスト例には、同じキーを持つ 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"],
    ...
},
```

クエリパラメータが URL エンコードされている場合、ロードバランサーはそれらをデコードしません。その場合は Lambda 関数でデコードする必要があります。

### 複数値ヘッダーを持つレスポンス
<a name="multi-value-headers-response"></a>

ヘッダーに使用されるフィールドの名前は、ターゲットグループに対して複数値ヘッダーを有効にするかどうかによって異なります。複数値ヘッダーを有効にしている場合は `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 レスポンスペイロードで指定されたのとは異なる順序でヘッダーをクライアントに送信する場合があります。したがって、ヘッダーが特定の順序で返されるとは限らないことに留意してください。

### 複数値ヘッダーの有効化
<a name="enable-multi-value-headers"></a>

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

------
#### [ Console ]

**複数値ヘッダーを有効化するには**

1. Amazon EC2 コンソールの [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) を開いてください。

1. ナビゲーションペインの [** Load Balancing (ロードバランシング) **] で [** Target Groups (ターゲットグループ) **] を選択します。

1. ターゲットグループの名前を選択して、その詳細ページを開きます。

1. [**Attributes**] タブで、[**Edit**] を選択します。

1. **[複数値のヘッダー]** を有効にします。

1. **[Save changes]** (変更の保存) をクリックします。

------
#### [ AWS CLI ]

**複数値ヘッダーを有効化するには**  
`lambda.multi_value_headers.enabled` 属性を指定して [modify-target-group-attributes](https://docs.aws.amazon.com/cli/latest/reference/elbv2/modify-target-group-attributes.html) コマンドを使用します。

```
aws elbv2 modify-target-group-attributes \
    --target-group-arn target-group-arn \
    --attributes "Key=lambda.multi_value_headers.enabled,Value=true"
```

------
#### [ CloudFormation ]

**複数値ヘッダーを有効化するには**  
[AWS::ElasticLoadBalancingV2::TargetGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html) リソースを更新して、`lambda.multi_value_headers.enabled` 属性を含めます。

```
Resources:
  myTargetGroup:
    Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
    Properties:
      Name: my-target-group
      TargetType: lambda
      Tags: 
        - Key: 'department'
          Value: '123'
      Targets:
        - Id: !Ref myLambdaFunction
      TargetGroupAttributes:
        - Key: "lambda.multi_value_headers.enabled"
          Value: "true"
```

------

## ヘルスチェックの有効化
<a name="enable-health-checks-lambda"></a>

デフォルトでは、ヘルスチェックは種類が `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
}
```

------
#### [ Console ]

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

1. Amazon EC2 コンソールの [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) を開いてください。

1. ナビゲーションペインの [** Load Balancing (ロードバランシング) **] で [** Target Groups (ターゲットグループ) **] を選択します。

1. ターゲットグループの名前を選択して、その詳細ページを開きます。

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

1. [**ヘルスチェック**] で、[**有効化**] を選択します。

1. (オプション) 必要に応じてヘルスチェック設定を更新します。

1. **[Save changes]** (変更の保存) をクリックします。

------
#### [ AWS CLI ]

**lambda ターゲットグループのヘルスチェックを有効にするには**  
[modify-target-group](https://docs.aws.amazon.com/cli/latest/reference/elbv2/modify-target-group.html) コマンドを使用します。

```
aws elbv2 modify-target-group \
    --target-group-arn target-group-arn \
    --health-check-enabled
```

------
#### [ CloudFormation ]

**lambda ターゲットグループのヘルスチェックを有効にするには**  
[AWS::ElasticLoadBalancingV2::TargetGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html) リソースを更新します。

```
Resources:
  myTargetGroup:
    Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
    Properties:
      Name: my-target-group
      TargetType: lambda
      HealthCheckEnabled: true
      Tags: 
        - Key: 'department'
          Value: '123'
      Targets:
        - Id: !Ref myLambdaFunction
```

------

## Lambda 関数を登録する
<a name="register-lambda-function"></a>

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

------
#### [ Console ]

**Lambda 関数を登録するには**

1. Amazon EC2 コンソールの [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) を開いてください。

1. ナビゲーションペインの [** Load Balancing (ロードバランシング) **] で [** Target Groups (ターゲットグループ) **] を選択します。

1. ターゲットグループの名前を選択して、その詳細ページを開きます。

1. **[ターゲット]** タブに登録された Lambda 関数が表示されない場合は、**[ターゲットの登録]** を選択します。

1. Lambda 関数を選択するか、その ARN を入力します。

1. [**登録**] を選択します。

------
#### [ AWS CLI ]

**Lambda 関数を登録するには**  
[register-targets](https://docs.aws.amazon.com/cli/latest/reference/elbv2/register-targets.html) コマンドを使用します。

```
aws elbv2 register-targets \
    --target-group-arn target-group-arn \
    --targets Id=lambda-function-arn
```

------
#### [ CloudFormation ]

**Lambda 関数を登録するには**  
[AWS::ElasticLoadBalancingV2::TargetGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-targetgroup.html) リソースを更新します。

```
Resources:
  myTargetGroup:
    Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
    Properties:
      Name: my-target-group
      TargetType: lambda
      Tags: 
        - Key: 'department'
          Value: '123'
      Targets:
        - Id: !Ref myLambdaFunction
```

------

## Lambda 関数の登録解除
<a name="deregister-lambda-function"></a>

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

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

------
#### [ Console ]

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

1. Amazon EC2 コンソールの [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/) を開いてください。

1. ナビゲーションペインの [** Load Balancing (ロードバランシング) **] で [** Target Groups (ターゲットグループ) **] を選択します。

1. ターゲットグループの名前を選択して、その詳細ページを開きます。

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

1. 確認を求めるメッセージが表示されたら、[**Deregister**] を選択します。

------
#### [ AWS CLI ]

**Lambda 関数を登録解除するには**  
[deregister-targets](https://docs.aws.amazon.com/cli/latest/reference/elbv2/deregister-targets.html) コマンドを使用します。

```
aws elbv2 deregister-targets \
    --target-group-arn target-group-arn \
    --targets Id=lambda-function-arn
```

------