EC2 Auto Scaling を通じて起動されるインスタンスを、それぞれが異なるサブネット内にある複数の Elastic Network Interface を持つように設定するにはどうすればよいですか?

最終更新日: 2022 年 6 月 27 日

Amazon Elastic Compute Cloud (Amazon EC2) Auto Scaling が新しいインスタンスを起動するときに、異なるサブネット内にある 2 番目の Elastic Network Interface がインスタンスに自動的にアタッチされるようにしたいと考えています。また、インスタンスの終了時に EC2 Auto Scaling が Elastic Network Interface を削除するようにしたいとも考えています。これらを実現するにはどうすればよいですか?

簡単な説明

EC2 Auto Scaling では、Auto Scaling が新しいインスタンスをスピンアップするときに、2 番目の Elastic Network Interface を自動的にアタッチすることがサポートされています。ただし、インスタンスにアタッチされた Elastic Network Interface は、どちらも同じサブネット内にあります。

このソリューションを使用すると、EC2 Auto Scaling によって起動されたインスタンスを、任意の 2 つの異なるサブネットに配置できます。例えば、一方の Elastic Network Interface をパブリックサブネットに配置して、もう一方をプライベートサブネットに配置することが可能です。

注意: このソリューションは、ウォームプールと、ウォームプールへのスケールインもサポートしています。

サブネット内のプライベート IP アドレスを使い切ってしまわないようにするため、インスタンスにアタッチされた Elastic Network Interface は、インスタンスの終了時に削除されます。これは、アカウントの Elastic Network Interface 制限に到達することを防ぐために役立ちます。

これを行うには、以下を実行します。

  1. インスタンスが [pending: wait] (保留中: 待機) 状態のときに、2 番目の Elastic Network Interface をそのインスタンスにアタッチする AWS Lambda 関数を作成します。2 番目の Elastic Network Interface が、1 番目の Elastic Network Interface のサブネットとは異なるサブネット内にあることを確認してください。
  2. インスタンス起動用のライフサイクルフックを作成します。
  3. Amazon EventBridge ルールまたは Amazon Simple Notification Service (Amazon SNS) トピックを設定して、Lambda 関数をトリガーします。ルールまたは SNS トピックは、Auto Scaling が新しいインスタンスを起動したときに EC2 Instance-launch Lifecycle Action によって呼び出されます

注: 次の解決方法は、各アベイラビリティーゾーンに 2 つのサブネットがある、単一または複数のアベイラビリティーゾーンで有効化された Auto Scaling グループ向けの方法です。

解決方法

Lambda 関数を作成する

以下を実行する Lambda 関数を作成します。

  • 起動されたインスタンスにアタッチされている 1 番目のネットワークインターフェイスのサブネットをチェックする。
  • Auto Scaling グループのアベイラビリティーゾーン内に設定されたもう一方のサブネットで、2 番目の Elastic Network Interface をインスタンスにアタッチします。

Lambda 関数を作成するには、以下を実行します。

1.    Lambda コンソールを開きます。

2.    [Create function] (関数の作成) を選択します。

3.    [Author from scratch] を選択します。

4.    [Function Name] (関数名) フィールドに Lambda 関数の名前を入力してから、 [Runtime] (ランタイム) に [Python 3.8] を選択します。

5.    ドロップダウンの矢印を選択して [Permissions] (許可) を展開し、Lambda 関数のデフォルトの実行ロールを変更します。既存の AWS Identity and Access Management (IAM) ロールを使用するか、IAM コンソールでカスタムロールを作成するかを選択できます。関数ロールには次の許可が必要です。

{
    "Statement": [{
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DetachNetworkInterface",
                "ec2:DeleteNetworkInterface",
                "ec2:DescribeSubnets",
                "ec2:AttachNetworkInterface",
                "ec2:DescribeInstances",
                "ec2:ModifyNetworkInterfaceAttribute",
                "autoscaling:CompleteLifecycleAction",
                "autoscaling:DescribeAutoScalingGroups"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}

6.    [Create function] を選択します。

7.    Multiple ENI Auto Scaling グループの Python スクリプトをダウンロードします。次に、そのコードを Function コードフィールドにコピーします。

8.    [Deploy] (デプロイ) タブを選択して、変更が保存されていることを確認します。

ライフサイクルフックを作成する

AWS マネジメントコンソールからイベントをトリガーするライフサイクルフックを作成します。手順については、「Add lifecycle hooks (console)」(ライフサイクルフックの追加 (コンソール)) を参照してください。または、次の AWS コマンドラインインターフェイス (AWS CLI) コマンドを使用します。

注: このユースケースでは、[Heartbeat timeout] (ハートビートタイムアウト) パラメータを 300 秒に設定し、[Default result] (デフォルト結果) パラメータを [ABANDON] に設定します。

aws autoscaling put-lifecycle-hook --lifecycle-hook-name my-lifecycle-launch-hook --auto-scaling-group-name my-asg --lifecycle-transition autoscaling:EC2_INSTANCE_LAUNCHING --heartbeat-timeout 300 --default-result ABANDON

注: AWS CLI コマンドの実行時にエラーが発生した場合は、AWS CLI の最新バージョンを使用していることを確認してください

Lambda 関数をトリガーする

Amazon EventBridge または Amazon Simple Notification Service (Amazon SNS) を使用して Lambda 関数をトリガーできます。

Lambda 関数をトリガーする EventBridge ルールを作成する

1.    [EventBridge コンソール] を開きます。

2.    左側のナビゲーションペインで [Rules] (ルール) を選択します。

注意: [Event bus] (イベントバス) には AWS のデフォルトイベントバスを選択してください。アカウント内の AWS のサービスがイベントを発行すると、イベントは常にアカウントのデフォルトイベントバスに送信されます。

3.    [Create rule] (ルールの作成) を選択します。

4.    ルールの [Name] (名前) と [Description] (説明) を入力します。

5.    [Rule type] (ルールタイプ) で [Rule with an event pattern] (イベントパターンを持つルール) を選択して、[Next] (次へ) を選択します。

6.    [Event Source] (イベントソース) で [Other] (その他) を選択し、[Event pattern] (イベントパターン) セクションに以下を追加してから、[Next] (次へ) を選択します。

注意: 以下の例では、AutoScalingGroupName を Auto Scaling グループの名前に変更し、LifecycleHookName をライフサイクルフックの名前に変更してください。

{
  "source": ["aws.autoscaling"],
  "detail-type": ["EC2 Instance-launch Lifecycle Action"],
  "detail": {
    "AutoScalingGroupName": ["my-asg"],
    "LifecycleHookName": ["my-lifecycle-launch-hook"]
  }
}

7.    [Target types] (ターゲットタイプ) には、[AWS service] (AWS のサービス) を選択します。

8.    [Select a target] (ターゲットを選択) で、ドロップダウンメニューから [Lambda function] (Lambda 関数) を選択し、先ほど作成した Lambda 関数を選択します。

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

10.    (オプション) ルールのタグを 1 つ、または複数入力します。

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

12.    ルールの詳細を確認してから、[Create rule] (ルールを作成) を選択します。

Lambda 関数をトリガーする Amazon SNS トピックを作成する

SNS トピックを使用するには、次を実行します。

1.    以下のコマンドを実行して、AWS CLI コマンドを使用して SNS トピックに通知を送信するライフサイクルフックを作成します。

aws autoscaling put-lifecycle-hook --lifecycle-hook-name my-lifecycle-launch-hook --auto-scaling-group-name my-asg --lifecycle-transition autoscaling:EC2_INSTANCE_LAUNCHING --heartbeat-timeout 300 --default-result ABANDON --notification-target-arn <SNStopicARN>

2.    Lambda 関数をトリガーするようにこの SNS トピックを設定します。

これで、Auto Scaling が新しいインスタンスを起動するときに、2 番目の Elastic Network Interface が異なるサブネットに作成され、インスタンスにアタッチされるようになりました。

注: Amazon Linux AMI を使用していない起動テンプレートには、追加のインターフェイスを作成するために、OS レベルで追加のオプションを設定する必要がある場合があります。


Use EventBridge to handle Auto Scaling events (EventBridge を使用して Auto Scaling イベントを処理する)

Auto Scaling グループの起動テンプレートの作成

この記事はお役に立ちましたか?


請求に関するサポートまたは技術サポートが必要ですか?