メンテナンスウィンドウを設定してSSM Patch Managerの実行をスケジュールする

メンテナンスウィンドウを設定してSSM Patch Managerの実行をスケジュールする

メンテナンスウィンドウを設定して、SSM Patch Managerの実行をスケジュールする

以下のページでパッチベースラインについて取り上げました。

https://awstut.com/2022/01/22/ssm-patch-manager-custom-patch-baseline

今回はパッチを適用するスケジュールを設定することを考えます。
メンテナンスウィンドウを設定することによって、パッチのスケジューリングができます。

パッチベースライン (およびオプションのパッチグループ) を設定したら、メンテナンスウィンドウを使用してパッチをノードに適用できます。

メンテナンスウィンドウを使用したパッチ適用スケジュールについて

今回は以下のAWS公式ページを参考に、CloudFormationを使用して、メンテナンスウィンドウを設定します。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/maintenance-windows-cli-tutorials-create.html

構築する環境

Diagram of set up Maintenance Window to schedule SSM Patch Manager.

プライベートサブネット内に、EC2インスタンスを1つ配置します。
インスタンスはAmazon Linux 2とします。

メンテナンスウィンドウを設定します。
内容は定期的にSSMドキュメントAWS-RunPatchBaselineを実行するものです。
このドキュメントを実行することによって、インスタンスには、Amazon Linux 2のデフォルトであるAWS-AmazonLinux2DefaultPatchBaselineが実行されることになります。

S3バケットにPatch Managerの実行ログを保存します。

CloudFormationテンプレートファイル

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

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

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

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

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

メンテナンスウィンドウ

Resources:
  MaintenanceWindow:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      AllowUnassociatedTargets: true
      Cutoff: 1
      Description: My-First-Maintenance-Window
      Duration: 2
      Name: !Sub "${Prefix}-MaintenanceWindow"
      Schedule: rate(5 minutes)
      ScheduleTimezone: Asia/Tokyo
Code language: YAML (yaml)

以下のページで、AWS CLIを使ったメンテナンスウィンドウの作成方法が取り上げられています。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/mw-cli-tutorial-create-mw.html

上記を参考にCloudFormationテンプレートを作成します。

設定内容は以下の通りです。

5 分ごとに最大 2 時間実行します (必要に応じて)。
メンテナンスウィンドウのオペレーションが終了してから 1 時間以内に新しいタスクが開始されないようにします。
関連付けられていないターゲット (メンテナンスウィンドウに登録されていないインスタンス) を許可します。

ステップ 1: メンテナンスウィンドウを作成する (AWS CLI)

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

Resources:
  MaintenanceWindowTarget:
    Type: AWS::SSM::MaintenanceWindowTarget
    Properties:
      Description: My-First-Maintenance-Window-Target
      Name: !Sub "${Prefix}-MaintenanceWindowTarget"
      ResourceType: INSTANCE
      Targets:
        - Key: tag:Patch Group
          Values:
            - !Ref PatchGroupTag
      WindowId: !Ref MaintenanceWindow
Code language: YAML (yaml)

以下のページで、AWS CLIを使ったメンテナンスウィンドウターゲットの作成方法が取り上げられています。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/mw-cli-tutorial-targets.html

上記を参考にCloudFormationテンプレートを作成します。

以下の条件でタグが設定されているインスタンスをメンテナンスウィンドウターゲットとします。

  • キー:Patch Group
  • 値:my-patch-group

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

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

Resources:
  MaintenanceWindowTask:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      Description: My-First-Maintenance-Window
      MaxConcurrency: 1
      MaxErrors: 1
      Name: !Sub "${Prefix}-MaintenanceWindowTask"
      Priority: 10
      Targets:
        - Key: WindowTargetIds
          Values:
            - !Ref MaintenanceWindowTarget
      TaskArn: AWS-RunPatchBaseline
      TaskInvocationParameters:
        MaintenanceWindowRunCommandParameters:
          OutputS3BucketName: !Ref S3BucketName
          Parameters:
            Operation:
              - Install
      TaskType: RUN_COMMAND
      WindowId: !Ref MaintenanceWindow
Code language: YAML (yaml)

以下のページで、AWS CLIを使ったメンテナンスウィンドウタスクの作成方法が取り上げられています。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/mw-cli-tutorial-tasks.html

上記を参考にCloudFormationテンプレートを作成します。

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

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

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/patch-manager-about-aws-runpatchbaseline.html

今回は必須パラメータであるOperationのみを設定します。
スキャンだけでなくインストールも実施するように、「Install」を指定します。

(参考)EC2インスタンス

Resources:
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref PrivateSubnet
          GroupSet:
            - !Ref InstanceSecurityGroup
      Tags:
        - Key: Patch Group
          Value: !Ref PatchGroupTag
Code language: YAML (yaml)

ポイントはタグ設定です。
メンテナンスウィンドウターゲットで指定したものと同様の設定を行います。

環境構築

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

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

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

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

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

  • EC2インスタンス:i-0ff14606b3c6f9e57
  • メンテナンスウィンドウ:mw-005d1fe0cee81a8f0

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

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

Detail of SSM 1.

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

Detail of SSM 2.

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

Detail of SSM 3.

タグキーが「Patch Group」、値が「my-patch-group」のインスタンスがメンテナンスウィンドウの対象となります。

動作確認

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

Detail of SSM 4.

しばらく待機してヒストリを見ると、タスクが実行されたことがわかります。

Detail of SSM 5.

確かにインスタンスを対象にしてタスクが実行されました。

Detail of SSM 6.

実行された内容を確認することができます。

今回はS3バケットに実行ログを保管するように設定しておりますので、そちらを確認します。

Detail of S3.

以下がファイルの内容の一部です。

/usr/bin/python3
/usr/bin/python2.7
/usr/bin/python2
/usr/bin/python
/usr/bin/yum
Using Yum version: 3.4.3
Using python binary: 'python2.7'
Using Python Version: Python 2.7.18
01/15/2023 11:59:24 root [INFO]: Downloading payload from https://s3.dualstack.ap-northeast-1.amazonaws.com/aws-ssm-ap-northeast-1/patchbaselineoperations/linux/payloads/patch-baseline-operations-1.101.tar.gz
01/15/2023 11:59:25 root [INFO]: Attempting to import entrance file os_selector
01/15/2023 11:59:25 root [INFO]: Running with snapshot id = 65deccb0-8b50-4d9e-9021-806637490599 and operation = Install
01/15/2023 11:59:25 root [INFO]: Instance Id: i-0ff14606b3c6f9e57
01/15/2023 11:59:25 root [INFO]: Region: ap-northeast-1
01/15/2023 11:59:25 root [INFO]: Product: AmazonLinux2
01/15/2023 11:59:25 root [INFO]: Patch Group: my-patch-group
01/15/2023 11:59:25 root [INFO]: Operation type: Install
01/15/2023 11:59:25 root [INFO]: Snapshot Id: 65deccb0-8b50-4d9e-9021-806637490599
01/15/2023 11:59:25 root [INFO]: Patch Baseline: {u'approvedPatchesEnableNonSecurity': False, u'baselineId': u'pb-00fda5699d1ae3942', u'name': u'AWS-AmazonLinux2DefaultPatchBaseline', u'modifiedTime': 1529573088.054, u'description': u'Default Patch Baseline for Amazon Linux 2 Provided by AWS.', u'rejectedPatches': [], u'globalFilters': {u'filters': [{u'values': [u'*'], u'key': u'PRODUCT'}]}, u'sources': [], u'approvalRules': {u'rules': [{u'enableNonSecurity': False, u'filterGroup': {u'filters': [{u'values': [u'Security'], u'key': u'CLASSIFICATION'}, {u'values': [u'Critical', u'Important'], u'key': u'SEVERITY'}]}, u'approveAfterDays': 7, u'complianceLevel': u'UNSPECIFIED', u'approveUntilDate': None}, {u'enableNonSecurity': False, u'filterGroup': {u'filters': [{u'values': [u'Bugfix'], u'key': u'CLASSIFICATION'}]}, u'approveAfterDays': 7, u'complianceLevel': u'UNSPECIFIED', u'approveUntilDate': None}]}, u'createdTime': 1529573088.054, u'rejectedPatchesAction': u'ALLOW_AS_DEPENDENCY', u'approvedPatchesComplianceLevel': u'UNSPECIFIED', u'operatingSystem': u'AMAZON_LINUX_2', u'approvedPatches': [], u'accountId': u'486716784251'}

...

01/15/2023 12:00:06 root [INFO]:  Instance is Compliant

...

01/15/2023 12:00:06 root [INFO]: Attempting full upload
01/15/2023 12:00:06 root [INFO]: Upload complete.
01/15/2023 12:00:06 root [INFO]: Report upload successful.
01/15/2023 12:00:06 root [INFO]: Inventory upload was successful.
01/15/2023 12:00:06 root [INFO]: Reboot is not required
01/15/2023 12:00:06 root [INFO]: Inventory upload was successful.
01/15/2023 12:00:06 root [INFO]: Reboot is not required
Code language: plaintext (plaintext)

確かにAWS-RunPatchBaselineが実行されて、インスタンス内の各種モジュールのアップデートが実行されました。

最後に改めてタスクの実行履歴を確認します。

Detail of SSM 7.

2回目のタスク実行履歴が確認できます。

1回目の実行後の、5分後に2回目が実行されていることができます。
このことから、確かにrate式で指定したスケジュール通りに、タスクが実行されてました。

まとめ

メンテナンスウィンドウを設定して、パッチをスケジュールする方法を確認しました。