Lambda を使用したカスタム終了ポリシーを作成する - Amazon EC2 Auto Scaling

Lambda を使用したカスタム終了ポリシーを作成する

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

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

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

入力データ

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_ININSTANCE_REFRESHMAX_INSTANCE_LIFETIMEREBALANCE を示します。

以下の情報は、Amazon EC2 Auto Scaling が入力データ Instances を生成する方法において最も重要な要因の概略を説明する

  • スケールインイベントおよびインスタンスのリフレッシュベースの終了によってインスタンスが終了する場合は、アベイラビリティーゾーン間のバランスを維持することが優先されます。そのため、グループに使用されている他のアベイラビリティーゾーンより多くのインスタンスが含まれるアベイラビリティーゾーンがある場合、入力データのインスタンスはそのバランスのとれていないアベイラビリティーゾーンのみからインスタンスに適用されます。グループに使用されているアベイラビリティーゾーンのバランスがとれている場合、入力データにはグループのすべてのアベイラビリティーゾーンのインスタンスが含まれます。

  • 混合インスタンスポリシーを使用する場合、各購入オプションの希望する割合に基づいて、スポットおよびオンデマンドのキャパシティーをバランスよく維持することも優先されます。まず、2 つのタイプ (スポットまたはオンデマンド) のどちらを終了すべきかを識別します。次に、アベイラビリティーゾーンのバランスが最も高い結果となるアベイラビリティーゾーンを終了できるインスタンス (特定された購入オプション内) を特定します。

レスポンスデータ

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

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

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

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

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

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

{ "InstanceIDs": [ ] }

カスタム終了ポリシーを使用することを考慮

カスタム終了ポリシーを使用する場合、次の点を考慮してください。

  • レスポンスデータで最初にインスタンスを返しても、その終了は保証されません。Lambda 関数が呼び出されたときに必要な数を超えるインスタンスが返された場合、Amazon EC2 Auto Scaling は、Auto Scaling グループに対して指定した他の終了ポリシーに対して各インスタンスを評価します。複数の終了ポリシーがある場合、リスト内の次の終了ポリシーを適用しようとします。終了に必要な数を超えるインスタンスがある場合は、次の終了ポリシーに移ります。他の終了ポリシーが指定されていない場合は、デフォルトの終了ポリシーを使用して、終了するインスタンスを決定します。

  • インスタンスが返されない場合、または Lambda 関数がタイムアウトした場合、Amazon EC2 Auto Scaling は関数を再度呼び出す前に少し待機します。スケールインイベントでは、グループの希望するキャパシティーが現在のキャパシティーよりも小さい限り、試行を続けます。たとえば、リフレッシュベースの終了の場合、1 時間試行し続けます。その後、インスタンスの終了に失敗し続けると、インスタンスの更新操作は失敗します。インスタンスの最大有効期間では、Amazon EC2 Auto Scaling は、その最大有効期間を超えていると識別されたインスタンスを終了しようとします。

  • 関数は繰り返し再試行されるため、Lambda 関数をカスタム終了ポリシーとして使用する前に、コード内の永続的なエラーをテストして修正してください。

  • 終了するインスタンスの独自のリストで入力データを上書きし、これらのインスタンスを終了してアベイラビリティーゾーンのバランスが崩れると、Amazon EC2 Auto Scaling はアベイラビリティーゾーン間のキャパシティーの分散を徐々に再調整します。まず、Lambda 関数を呼び出して、リバランシングを開始するかどうかを判断できるように、終了する準備ができているインスタンスがあるかどうかを確認します。終了する準備ができているインスタンスがある場合、最初に新しいインスタンスを起動します。インスタンスの起動が完了すると、グループの現在のキャパシティーが希望するキャパシティーよりも大きいことが検出され、スケールインイベントが開始されます。

Lambda 関数を作成する

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

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

  1. Lambda コンソールで [Functions (関数)] ページを開きます。

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

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

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

  5. [Create function] (関数の作成) を選択します。関数のコードと設定に戻ります。

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

  7. [Deploy‬] (デプロイ) をクリックします。

  8. 必要に応じて、Lambda 関数の公開バージョンを作成するには、[Versions (バージョン)] タブをクリックし、次に新しいバージョンを発行します。Lambda でのバージョニングの詳細については、AWS Lambdaデベロッパーガイドの「Lambda 関数のバージョン」を参照してください。

  9. バージョンを公開することを選択した場合、このバージョンの Lambda 関数と関連付けるには [Aliases (エイリアス)] タブを選択します。Lambda のエイリアスの詳細については、AWS Lambdaデベロッパーガイドの「Lambda 関数のエイリアス」を参照してください。

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

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

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

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

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

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

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

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

  13. これらの指示に従った後、次のステップとして Auto Scaling グループの終了ポリしーの ARN を指定し続けます。詳細については、「異なる終了ポリシーを使用する (コンソール)」を参照してください。

注記

Lambda 関数を開発する際の参考として使用できる例については、Amazon EC2 Auto Scaling の GitHub リポジトリを参照してください。

制約事項

  • 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 秒ですが、これを減らすことができます。

  • Amazon EC2 Auto Scaling は、インスタンスのスケールイン保護が有効になっているインスタンスを終了しません。