

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

# Lambda を使用したカスタム終了ポリシーを作成する
<a name="lambda-custom-termination-policy"></a>

Amazon EC2 Auto Scaling は、終了ポリシーを使用して、Auto Scaling グループのサイズを小さくするときに、最初に終了するインスタンスを優先順位付けします (*スケールイン*と言います)。Auto Scaling グループではデフォルトの終了ポリシーを使用しますが、独自の終了ポリシーを選択または作成することもできます。定義済みの終了ポリシーを選択する方法の詳細については、「[Amazon EC2 Auto Scaling の終了ポリシーを設定する](ec2-auto-scaling-termination-policies.md)」を参照してください。

このトピックでは、カスタム終了ポリシーを作成する方法について説明し、Amazon EC2 Auto Scaling が特定のイベントに応答して呼び出す AWS Lambda 関数を使用します。作成した Lambda 関数は、Amazon EC2 Auto Scaling から送信された入力データの情報を処理し、終了する準備ができているインスタンスのリストを返します。

カスタム終了ポリシーを使用すると、終了するインスタンスとタイミングをより適切に制御できます。例えば、Auto Scaling グループがスケールインする場合、Amazon EC2 Auto Scaling は中断すべきではない実行中のワークロードがあるかどうかを判断できません。Lambda 関数を使用すると、終了リクエストを検証し、ワークロードが完了するまで待機してから、終了するためにインスタンス ID を Amazon EC2 Auto Scaling に返して終了することができます。

**Topics**
+ [入力データ](#lambda-custom-termination-policy-input-data)
+ [レスポンスデータ](#lambda-custom-termination-policy-response-data)
+ [考慮事項](#lambda-termination-policy-considerations)
+ [Lambda 関数を作成する](#lambda-custom-termination-policy-create-function)
+ [制限事項](#lambda-custom-termination-policy-limitations)

## 入力データ
<a name="lambda-custom-termination-policy-input-data"></a>

Amazon EC2 Auto Scaling は、スケールインイベントの JSON ペイロードを生成します。また、インスタンスの最大有効期間またはインスタンスの更新機能の結果としてインスタンスが終了されるときにもこれを行います。また、アベイラビリティーゾーン間でグループのバランスを再調整するときに開始できるスケールインイベントの JSON ペイロードも生成します。

このペイロードには、Amazon EC2 Auto Scaling の終了に必要なキャパシティー、終了を提案するインスタンスのリスト、終了を開始したイベントに関する情報が含まれます。

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

```
{
  "AutoScalingGroupARN": "arn:aws:autoscaling:us-east-1:<account-id>:autoScalingGroup:d4738357-2d40-4038-ae7e-b00ae0227003:autoScalingGroupName/my-asg",
  "AutoScalingGroupName": "my-asg",
  "CapacityToTerminate": [
    {
      "AvailabilityZone": "us-east-1b",
      "Capacity": 2,
      "InstanceMarketOption": "on-demand"
    },
    {
      "AvailabilityZone": "us-east-1b",
      "Capacity": 1,
      "InstanceMarketOption": "spot"
    },
    {
      "AvailabilityZone": "us-east-1c",
      "Capacity": 3,
      "InstanceMarketOption": "on-demand"
    }
  ],
  "Instances": [
    {
      "AvailabilityZone": "us-east-1b",
      "InstanceId": "i-0056faf8da3e1f75d",
      "InstanceType": "t2.nano",
      "InstanceMarketOption": "on-demand"
    },
    {
      "AvailabilityZone": "us-east-1c",
      "InstanceId": "i-02e1c69383a3ed501",
      "InstanceType": "t2.nano",
      "InstanceMarketOption": "on-demand"
    },
    {
      "AvailabilityZone": "us-east-1c",
      "InstanceId": "i-036bc44b6092c01c7",
      "InstanceType": "t2.nano",
      "InstanceMarketOption": "on-demand"
    },
    ...
  ],
  "Cause": "SCALE_IN"
}
```

ペイロードには、Auto Scaling グループの名前、その Amazon リソースネーム (ARN)、および次の要素が含まれます:
+ `CapacityToTerminate` は、特定のアベイラビリティーゾーンで終了するように設定されたスポットまたはオンデマンドのキャパシティーを示します。
+ `Instances` は、Amazon EC2 Auto Scaling が「`CapacityToTerminate`」の情報に基づいて、終了を提案するインスタンスを表します。
+ `Cause` は、終了の原因となったイベントである `SCALE_IN`、`INSTANCE_REFRESH`、`MAX_INSTANCE_LIFETIME`、`REBALANCE` を示します。

以下の情報は、Amazon EC2 Auto Scaling が入力データ `Instances` を生成する方法において最も重要な要因の概略を説明する
+ スケールインイベントおよびインスタンスの更新に基づく終了によってインスタンスが終了する場合は、アベイラビリティーゾーン間のバランスを維持することが優先されます。そのため、グループに使用されている他のアベイラビリティーゾーンより多くのインスタンスが含まれるアベイラビリティーゾーンがある場合、入力データのインスタンスはそのバランスのとれていないアベイラビリティーゾーンのみからインスタンスに適用されます。グループに使用されているアベイラビリティーゾーンのバランスがとれている場合、入力データにはグループのすべてのアベイラビリティーゾーンのインスタンスが含まれます。
+ [混合インスタンスポリシー](ec2-auto-scaling-mixed-instances-groups.md)を使用する場合、各購入オプションの希望する割合に基づいて、スポットおよびオンデマンドのキャパシティーをバランスよく維持することも優先されます。まず、2 つのタイプ (スポットまたはオンデマンド) のどちらを終了すべきかを識別します。次に、アベイラビリティーゾーンのバランスが最も高い結果となるアベイラビリティーゾーンを終了できるインスタンス (特定された購入オプション内) を特定します。

## レスポンスデータ
<a name="lambda-custom-termination-policy-response-data"></a>

入力データと応答データが連携して、終了するインスタンスのリストを絞り込みます。

指定された入力では、Lambda 関数からの応答は次の例のようになります。

```
{
  "InstanceIDs": [
    "i-02e1c69383a3ed501",
    "i-036bc44b6092c01c7",
    ...
  ]
}
```

`InstanceIDs` は、終了する準備ができているインスタンスを表します。

または、終了する準備ができている別のインスタンスのセットを返すこともできます。これにより、入力データのインスタンスが上書きされます。Lambda 関数が呼び出されたときに終了する準備ができていない場合は、インスタンスを返さないように選択することもできます。

終了する準備ができているインスタンスがない場合、Lambda 関数からの応答は次の例のようになります。

```
{
  "InstanceIDs": [ ]
}
```

## 考慮事項
<a name="lambda-termination-policy-considerations"></a>

カスタム終了ポリシーを使用する場合、次の点を考慮してください。
+ レスポンスデータで最初にインスタンスを返しても、その終了は保証されません。Lambda 関数が呼び出されたときに必要な数を超えるインスタンスが返された場合、Amazon EC2 Auto Scaling は、Auto Scaling グループに対して指定した他の終了ポリシーに対して各インスタンスを評価します。複数の終了ポリシーがある場合、リスト内の次の終了ポリシーを適用しようとします。終了に必要な数を超えるインスタンスがある場合は、次の終了ポリシーに移ります。他の終了ポリシーが指定されていない場合は、デフォルトの終了ポリシーを使用して、終了するインスタンスを決定します。
+ インスタンスが返されない場合、または Lambda 関数がタイムアウトした場合、Amazon EC2 Auto Scaling は関数を再度呼び出す前に少し待機します。スケールインイベントでは、グループの希望するキャパシティが現在のキャパシティよりも小さい限り、試行を続けます。例えば、リフレッシュベースの終了の場合、1 時間試行し続けます。その後、インスタンスの終了に失敗し続けると、インスタンスの更新操作は失敗します。インスタンスの最大有効期間では、Amazon EC2 Auto Scaling は、その最大有効期間を超えていると識別されたインスタンスを終了しようとします。
+ 関数は繰り返し再試行されるため、Lambda 関数をカスタム終了ポリシーとして使用する前に、コード内の永続的なエラーをテストして修正してください。
+ 終了するインスタンスの独自のリストで入力データを上書きし、これらのインスタンスを終了してアベイラビリティーゾーンのバランスが崩れると、Amazon EC2 Auto Scaling はアベイラビリティーゾーン間のキャパシティーの分散を徐々に再調整します。まず、Lambda 関数を呼び出して、リバランシングを開始するかどうかを判断できるように、終了する準備ができているインスタンスがあるかどうかを確認します。終了する準備ができているインスタンスがある場合、最初に新しいインスタンスを起動します。インスタンスの起動が完了すると、グループの現在のキャパシティが希望するキャパシティよりも大きいことが検出され、スケールインイベントが開始されます。
+ スケールイン保護を使用して特定のインスタンスが終了されないように保護する機能にカスタム終了ポリシーが影響をおよぼすことはありません。詳細については、「[インスタンスのスケールイン保護を使用してインスタンスの終了を制御する](ec2-auto-scaling-instance-protection.md)」を参照してください。
+ Lambda 関数がインスタンスを返さない場合、これにより自動的にすべての終了が妨げられるわけではありません。Amazon EC2 Auto Scaling は、終了ポリシーに関係なく、Auto Scaling ヘルスチェックによって異常と見なされるインスタンスを引き続き終了します。

## Lambda 関数を作成する
<a name="lambda-custom-termination-policy-create-function"></a>

まず Lambda 関数を作成し、Auto Scaling グループの終了ポリシーで Amazon リソースネーム (ARN) を指定できるようにします。

**Lambda 関数を作成するには (コンソール)**

1. Lambda コンソールで [[Functions (関数)] ページ](https://console.aws.amazon.com/lambda/home#/functions)を開きます。

1. 画面の上部のナビゲーションバーで、Auto Scaling グループの作成時に使用したのと同じリージョンを選択します。

1. [**Create function (関数の作成)**] を選択し、[**Author from scratch (一から作成)**] を選択します。

1. [**基本的な情報**] の [**関数名**] に、関数の名前を入力します。

1. [**関数の作成**] を選択してください。関数のコードと設定に戻ります。

1. 関数をまだコンソールで開いている状態で、**関数コード**の下にエディタに貼り付けます。

1. **[デプロイ]** をクリックします。

1. 必要に応じて、Lambda 関数の公開バージョンを作成するには、[**Versions (バージョン)**] タブをクリックし、次に**新しいバージョンを発行します**。Lambda でのバージョニングの詳細については、*AWS Lambda デベロッパーガイド*の「[Lambda 関数のバージョン](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html)」を参照してください。

1. バージョンを公開することを選択した場合、このバージョンの Lambda 関数と関連付けるには [**Aliases (エイリアス)**] タブを選択します。Lambda のエイリアスの詳細については、*AWS Lambda デベロッパーガイド*の「[Lambda 関数のエイリアス](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html)」を参照してください。

1. 次に [**Configuration (設定)**] タブと [**Permissions (アクセス許可)**] を選択します。

1. [**Resource-based policy (リソースベースのポリシー)**] にスクロールダウンして [**アクセス許可の追加**] を選択します。リソースベースのポリシーを使用して、関数を呼び出すアクセス許可を、ポリシーで指定されているプリンシパルに付与します。この場合、プリンシパルは Auto Scaling グループに関連付けられている [Amazon EC2 Auto Scaling service-linked role](https://docs.aws.amazon.com/autoscaling/ec2/userguide/autoscaling-service-linked-role.html) です。

1. [**Policy statement (ポリシーステートメント)**] セクションで、権限を設定します。

   1. **AWS アカウント** を選択します。

   1. **Principal (プリンシパル)** で、例えば **arn:aws:iam::<aws-account-id>:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling** といった呼び出しサービスにリンクされたロールの ARN を入力します。

   1. [**Action (アクション)**] で、[**lambda:InvokeFunction**] を選択します。

   1. [**Statement ID (ステートメント ID)**] に **AllowInvokeByAutoScaling** といった一意のステートメント ID を入力します。

   1. **[保存]** を選択します。

1. これらの指示に従った後、次のステップとして Auto Scaling グループの終了ポリしーの ARN を指定し続けます。詳細については、「[Auto Scaling グループの終了ポリシーを変更する](custom-termination-policy.md)」を参照してください。

**注記**  
Lambda 関数を開発する際の参考として使用できる例については、Amazon EC2 Auto Scaling の [GitHub リポジトリ](https://github.com/aws-samples/amazon-ec2-auto-scaling-group-examples)を参照してください。

## 制限事項
<a name="lambda-custom-termination-policy-limitations"></a>
+ Auto Scaling グループの終了ポリシーで指定できる Lambda 関数は 1 つだけです。複数の終了ポリシーが指定されている場合は、最初に Lambda 関数を指定する必要があります。
+ Lambda 関数を参照するには、修飾されていない ARN (サフィックスなし)、バージョンまたはエイリアスをサフィックスとして持つ修飾された ARN を使用します。修飾されていない ARN が使用されている場合 (例えば、`function:my-function`)、リソースベースのポリシーは、関数の未公開バージョンで作成する必要があります。修飾された ARN が使用されている場合 (例えば、`function:my-function:1` または `function:my-function:prod`)、リソースベースのポリシーは、その公開バージョンの関数に対して作成する必要があります。
+ `$LATEST` サフィックスで修飾された ARN を使用できません。`$LATEST` サフィックスで修飾された ARN を参照するカスタム終了ポリシーを追加すると、エラーが発生します。
+ 入力データで提供されるインスタンスの数は、30,000 インスタンスまでに制限されています。終了できるインスタンスが 30,000 個を超える場合、入力データには インスタンスの最大数が戻されることを示す `"HasMoreInstances": true` を示します。
+ Lambda 関数の最大実行時間は 2 秒 (2000 ミリ秒) です。ベストプラクティスとして、予想される実行時間に基づいて Lambda 関数のタイムアウト値を設定する必要があります。Lambda 関数のデフォルトのタイムアウトは 3 秒ですが、これを減らすことができます。
+ ランタイムが 2 秒の制限を超えると、ランタイムがこのしきい値を下回るまで、すべてのスケールインアクションが保留されます。ランタイムが一貫して長い Lambda 関数の場合、結果をキャッシュして後続の Lambda 呼び出し中に取得できるようにするなど、ランタイムを短縮する方法を見つけます。
+ クロスアカウントの Lambda 関数はサポートされていません。カスタム終了ポリシーとして使用される Lambda 関数は、Auto Scaling グループ AWS アカウント と同じ にある必要があります。このページの設定手順は、特に同一アカウント設定に焦点を当てています。
+ カスタム終了ポリシーは、異常なインスタンスには適用されません。異常なインスタンスは常に終了対象と見なされ、Lambda 関数は残りのインスタンスの終了順序のみを評価します。