【AWS Systems Manager】パッチマネージャー + メンテナンスウインドウの構成をCloudFormationテンプレート化してみた

AWS Systems Managerにおいてパッチマネージャーをメンテナンスウインドウを用いて定期実行させるときの構成をCloudFormationテンプレート化しました。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

コンバンハ、千葉(幸)です。

先日、パッチマネージャーをメンテナンスウインドウで定期実行する際の関連リソースについて確認しました。パッチベースライン、パッチグループ、メンテナンスウインドウといったリソースが登場することを抑えています。

それらをCloudFormationで作成できるようテンプレート化してみました。

目次

テンプレート範囲

以下のイメージです。★が付与されているものがCloudFormation上のリソースです。

補足事項としては以下があります。

  • パッチベースラインはAmazon Linux2向けのものとして作成する
  • パッチグループは「TestPG」という名称であるとする

テンプレート

以下の通りです。

AWSTemplateFormatVersion: '2010-09-09'
Description: "Create PatchBaseline"

Resources:
# ------------------------------------------------------------#
# PatchBaseline
# ------------------------------------------------------------#
  PatchBaseline:
    Type: AWS::SSM::PatchBaseline
    Properties:
      ApprovalRules:
        PatchRules:
          - ApproveAfterDays: 7
            PatchFilterGroup:
              PatchFilters:
                - Key: CLASSIFICATION
                  Values:
                    - Security
                - Key: SEVERITY
                  Values:
                    - Important
                    - Critical
          - ApproveAfterDays: 7
            PatchFilterGroup:
              PatchFilters:
                - Key: CLASSIFICATION
                  Values:
                    - Bugfix
      Description: "AmazonLinux2PatchBaseline create by CloudFormation"
      Name: AmazonLinux2PatchBaseline
      OperatingSystem: AMAZON_LINUX_2
      PatchGroups:
        - "TestPG"
# ------------------------------------------------------------#
# MaintenanceWindow
# ------------------------------------------------------------#
  MaintenanceWindow:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      AllowUnassociatedTargets: true
      Cutoff: 0
      Duration: 1
      Name: "maitenancewindow-TestPG"
      Schedule: "cron(00 18 ? * SAT *)"
# ------------------------------------------------------------#
# MaintenanceWindowTarget
# ------------------------------------------------------------#
  MaintenanceWindowTarget:
    Type: AWS::SSM::MaintenanceWindowTarget
    Properties:
      Name: PatchingTarget
      ResourceType: INSTANCE
      Targets:
        - Key: "tag:Patch Group"
          Values:
            - "TestPG"
      WindowId: !Ref MaintenanceWindow
    DependsOn: MaintenanceWindow
# ------------------------------------------------------------#
# MaintenanceWindowTask
# ------------------------------------------------------------#
  MaintenanceWindowTask:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      MaxConcurrency: 50
      MaxErrors: 0
      Name: PatchingTask
      Priority: 1
      Targets:
        - Key: WindowTargetIds
          Values:
            - !Ref MaintenanceWindowTarget
      TaskArn: AWS-RunPatchBaseline
      TaskType: RUN_COMMAND
      WindowId: !Ref MaintenanceWindow
      TaskInvocationParameters:
        MaintenanceWindowRunCommandParameters:
          TimeoutSeconds: 600
          Parameters: {"Operation":["Install"]}
    DependsOn: MaintenanceWindowTarget

リソースとして以下を含んでいます。

論理ID リソースタイプ
PatchBaseline AWS::SSM::PatchBaseline
MaintenanceWindow AWS::SSM::MaintenanceWindow
MaintenanceWindowTarget AWS::SSM::MaintenanceWindowTarget
MaintenanceWindowTask AWS::SSM::MaintenanceWindowTask

以下、各リソースを順番に確認していきます。

AWS::SSM::PatchBaseline

公式リファレンス

# ------------------------------------------------------------#
# PatchBaseline
# ------------------------------------------------------------#
  PatchBaseline:
    Type: AWS::SSM::PatchBaseline
    Properties:
      ApprovalRules:
        PatchRules:
          - ApproveAfterDays: 7
            PatchFilterGroup:
              PatchFilters:
                - Key: CLASSIFICATION
                  Values:
                    - Security
                - Key: SEVERITY
                  Values:
                    - Important
                    - Critical
          - ApproveAfterDays: 7
            PatchFilterGroup:
              PatchFilters:
                - Key: CLASSIFICATION
                  Values:
                    - Bugfix
      Description: "AmazonLinux2PatchBaseline create by CloudFormation"
      Name: AmazonLinux2PatchBaseline
      OperatingSystem: AMAZON_LINUX_2
      PatchGroups:
        - "TestPG"

パッチグループを新規に作成しつつ既存のパッチベースラインに登録、ということができなさそうであったためパッチベースラインも新規作成しています。事前定義されたパッチベースラインと同様の承認ルールとなるように作成しています。

なお、パッチベースライン名に「AWS」から始まるものを指定すると、CloudFormationを実行する段階でエラーが発生するので注意が必要です。

Patch Baseline Name: AWS-AmazonLinux2PatchBaseline cannot starts with: AWS- or AWS: (Service: AmazonSSM; Status Code: 400; Error Code: ValidationException; Request ID: 8cbf1a2f-0efb-4b81-a9b9-57aff3af5bb2)

AWS::SSM::MaintenanceWindow

公式リファレンス

# ------------------------------------------------------------#
# MaintenanceWindow
# ------------------------------------------------------------#
  MaintenanceWindow:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      AllowUnassociatedTargets: true
      Cutoff: 0
      Duration: 1
      Name: "maitenancewindow-TestPG"
      Schedule: "cron(00 18 ? * SAT *)"

ここでは、(JSTで考えた場合の)毎週日曜早朝の3:00を指定しています。以下を参考に、適宜カスタマイズしてください。

リファレンス: Systems Manager の Cron および Rate 式

AWS::SSM::MaintenanceWindowTarget

公式リファレンス

# ------------------------------------------------------------#
# MaintenanceWindowTarget
# ------------------------------------------------------------#
  MaintenanceWindowTarget:
    Type: AWS::SSM::MaintenanceWindowTarget
    Properties:
      Name: PatchingTarget
      ResourceType: INSTANCE
      Targets:
        - Key: "tag:Patch Group"
          Values:
            - "TestPG"
      WindowId: !Ref MaintenanceWindow
    DependsOn: MaintenanceWindow

パッチマネージャー上ではパッチグループという概念がありますが、メンテナンスウインドウのターゲットにおいては「特定のタグが付与されたインスタンス」という扱いでしかないのが、個人的にちょっと好きです。

AWS::SSM::MaintenanceWindowTask

公式リファレンス

# ------------------------------------------------------------#
# MaintenanceWindowTask
# ------------------------------------------------------------#
  MaintenanceWindowTask:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      MaxConcurrency: 50
      MaxErrors: 0
      Name: PatchingTask
      Priority: 1
      Targets:
        - Key: WindowTargetIds
          Values:
            - !Ref MaintenanceWindowTarget
      TaskArn: AWS-RunPatchBaseline
      TaskType: RUN_COMMAND
      WindowId: !Ref MaintenanceWindow
      TaskInvocationParameters:
        MaintenanceWindowRunCommandParameters:
          TimeoutSeconds: 600
          Parameters: {"Operation":["Install"]}
    DependsOn: MaintenanceWindowTarget

パッチマネージャーによるパッチ適用とは、Run CommandによってSSMドキュメントAWS-RunPatchBaselineを実行することを指す、というのが分かって面白いですね。

SSMドキュメントに渡すパラメータ

Parameters: {"Operation":["Install"]}の部分について、パラメータの渡し方をどう調べたら良いかが見当付かずに途方にくれていたのですが、いろいろ検索していると以下のページがヒットしたのでそれを踏襲しました。(262行目)

yamlで書くときはこのように書けば大丈夫です。

Parameters: 
  Operation:
    - Install

複数パラメータを指定する場合は以下のようになります。

Parameters: 
  Operation:
    - Install
  RebootOption:
    - NoReboot

ここでどういったパラメータを渡せばいいかについては、通常はSSMドキュメントの詳細画面から確認するのが良いかと思います。

AWS-RunPatchBaselineについてはAWSドキュメントで詳細に説明されていますので、こちらから確認した方がわかりやすいでしょう。

SSM ドキュメント AWS-RunPatchBaseline について

終わりに

Systems Managerのパッチマネージャーを一式CloudFormationで作成する際にテンプレートのご紹介でした。

1回作成するだけであれば明らかにマネジメントコンソールから作業する方が楽ですが、CloudFormationを利用することでメリットがある環境であればぜひご活用ください。

以上、目刺を尻尾から食べる千葉(幸)がお送りしました。