AWS-PatchAsgInstanceを使ってAutoScalingグループ内のインスタンスに順番にパッチを当てる

AWS-PatchAsgInstanceを使ってAuto Scalingグループ内のインスタンスに順番にパッチを当てる

AWS-PatchAsgInstanceを使ってAutoScalingグループ内のインスタンスに順番にパッチを当てる

以下のページで、メンテナンスウィンドウを使用して、EC2インスタンスへのパッチ適用をスケジュールする方法を取り上げました。

https://awstut.com/2023/02/05/set-up-maintenance-window-to-schedule-ssm-patch-manager

今回はAuto Scalingグループ内のEC2インスタンスを対象とすることを考えます。

SSM AutomationランブックAWS-PatchAsgInstanceを使用することによって、これを実現できます。

Patch EC2 instances in an Auto Scaling group.

AWS-PatchAsgInstance

CloudFormationを使用して、AWS-PatchAsgInstanceを実行する環境を構築します。

構築する環境

Diagram of AWS-PatchAsgInstance to patch instances in Auto Scaling Group in turn.

プライベートサブネット内にAuto Scalingグループを作成します。
グループ内で作成するインスタンスはAmazon Linux 2とします。

メンテナンスウィンドウを設定します。
内容は定期的にSSM AutomationランブックAWS-PatchAsgInstanceを実行するものです。
このランブックを実行することによって、Auto Scalingグループ内のEC2インスタンスに対して、順番にAWS-RunPatchBaselineが実行されることになります。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/115

テンプレートファイルのポイント解説

メンテナンスウィンドウを設定する場合、以下の3つのリソースを設定します。

  • メンテナンスウィンドウ
  • メンテナンスウィンドウターゲット
  • メンテナンスウィンドウタスク

メンテナンスウィンドウ

Resources:
  MaintenanceWindow:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      AllowUnassociatedTargets: false
      Cutoff: 1
      Duration: 2
      Name: !Sub "${Prefix}-MaintenanceWindow"
      Schedule: rate(30 minutes)
      ScheduleTimezone: Asia/Tokyo
Code language: YAML (yaml)

rate式で60分ごとにタスクを実行するように設定します。

メンテナンスウィンドウターゲット

Resources:
  MaintenanceWindowTarget:
    Type: AWS::SSM::MaintenanceWindowTarget
    Properties:
      Name: !Sub "${Prefix}-MaintenanceWindowTarget"
      ResourceType: INSTANCE
      Targets:
        - Key: tag:aws:autoscaling:groupName
          Values:
            - !Ref AutoScalingGroup
      WindowId: !Ref MaintenanceWindow
Code language: YAML (yaml)

Auto Scalingグループ内のインスタンスをメンテナンスウィンドウとする場合、ResourceTypeプロパティは「INSTANCE」を指定します。

Auto Scalingグループ内のインスタンスには、自動で設定されるタグがあります。

Auto Scaling グループでは、キーに aws:autoscaling:groupName、値に Auto Scaling グループ名が使用され、インスタンスにタグが自動的に追加されます。

Auto Scaling グループとインスタンスにタグを付ける

今回はこちらをTargetsプロパティに指定します。
なおKeyプロパティにタグ名を指定する場合は、「tag:[タグ名]」の形式で指定します。

メンテナンスウィンドウタスク

Resources:
  MaintenanceWindowTask:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      MaxConcurrency: 1
      MaxErrors: 0
      Name: !Sub "${Prefix}-MaintenanceWindowTask"
      Priority: 10
      ServiceRoleArn: !GetAtt SSMAutomationRole.Arn
      Targets:
        - Key: WindowTargetIds
          Values:
            - !Ref MaintenanceWindowTarget
      TaskArn: AWS-PatchAsgInstance
      TaskInvocationParameters:
        MaintenanceWindowAutomationParameters:
          Parameters:
            InstanceId:
              - "{{RESOURCE_ID}}"
      TaskType: AUTOMATION
      WindowId: !Ref MaintenanceWindow
Code language: YAML (yaml)

作成するタスクはAWS-PatchAsgInstanceを実行するものです。

TaskTypeプロパティは「AUTOMATION」とし、Targetsプロパティは先述のメンテナンスウィンドウのIDとします。

TaskInvocationParametersプロパティでAWS-PatchAsgInstanceを実行する上でのパラメータを設定できます。
パラメータについて以下のページをご確認ください。

https://docs.aws.amazon.com/ja_jp/systems-manager-automation-runbooks/latest/userguide/automation-aws-patchasginstance.html

今回は必須パラメータであるInstanceIdのみ設定します。
このパラメータはAuto Scalingグループ内のインスタンスのIDを指定します。
つまりインスタンスごとに異なるということです。
こちらについては、疑似パラメータを指定することができます。

必須入力パラメータフィールドで擬似パラメータ値を使用して、メンテナンスウィンドウが対象とするリソース ID を動的に参照できます。{{RESOURCE_ID}} などの擬似パラメータを使用すると、各リソース ID を個別に入力しなくても、複数のリソースを対象にできます。

Systems Manager のメンテナンスウィンドウでオートメーションタスクを登録するときに擬似パラメータを追加するにはどうすればよいですか?

今回は上記に従い、「{{RESOURCE_ID}}」を指定します。

(参考) ALBおよびAuo Scalingグループ

本ページはメンテナンスウィンドウを設定することで、定期的にAWS-PatchAsgInstanceを実行することを中心に取り上げます。

プライベートサブネット内にAuto Scalingグループを作成し、これをALBにアタッチする方法については、以下のページをご確認ください。

https://awstut.com/2022/10/08/introduction-to-ec2-auto-scaling-no-scaling-policy

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

https://awstut.com/2021/12/02/cloudformation-nested-stacks

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • メンテナンスウィンドウ:0dd5b473dd8357e1b
  • Auto Scalingグループ:fa-115-AutoScalingGroup
  • ALBのDNS名:fa-115-ALB-905077433.ap-northeast-1.elb.amazonaws.com

AWS Management Consoleから各リソースを確認します。

メンテナンスウィンドウを確認します。

Detail of SSM 1.

5分ごとにタスクが実行される設定になっていることがわかります。

Detail of SSM 2.

タスクの内容を見ると、AWS-PatchAsgInstanceを実行する内容であることがわかります。

Detail of SSM 3.

タグキーが「aws:autoscaling:groupName」、値が「fa-115-AutoScalingGroup」のインスタンスがメンテナンスウィンドウの対象となります。

Auto Scalingグループを確認します。

Detail of Auto Scaling 1.

最小値1、最大値2、希望値2でグループが作成されています。

Detail of Auto Scaling 2.

確かにグループ内に2つのインスタンスが作成されており、2つとも「InService」です。

動作確認

準備が整いましたので、動作を確認します。

Detail of SSM 4.

確かにAWS-PatchAsgInstanceのタスクが実行されています。
Auto Scalingグループ内のインスタンスの内、1台に対して順番にステップが実行されて、パッチ適用が行われます。

Detail of SSM 5.

改めてAuto Scalingグループを見ると、確かに1台のインスタンスのステータスが「Standby」に変化しました。
つまりこのインスタンスに対して、ALBからのトラフィックはルーティングされないということです。

Detail of Auto Scaling 3.

ALBにアクセスすると、現在パッチ適用の対象ではない方のインスタンスが応答しました。
グループ内の全てのインスタンスに対して、同時にパッチ適用が行われるわけではないため、アプリケーションが停止することはありません。

しばらく待つと、全ステップの実行が完了します。

Detail of SSM 6.

改めてAuto Scalingグループを確認します。

Detail of Auto Scaling 4.

パッチ適用が完了したインスタンスのステータスが「InService」に戻りました。

Detail of Auto Scaling 5.

1台目のインスタンスが完了した後は、もう一方のインスタンスがパッチ適用の対象となります。

このようにAWS-PatchAsgInstanceを使うことによって、Auto Scalingグループ内のインスタンスに対して、順番にパッチ適用を行うことができます。

まとめ

AWS-PatchAsgInstanceを実行する環境を構築しました。