AWS Patch Managerの設定

はじめに

先日、AWS構築で、初めてPatch ManagerによるEC2内のソフトウェアパッケージ自動アップデートを設定する機会がありました。

Patch Managerはリリースされてから10年近く?経っており、多くの情報がありますが、僕自身が初めて触ってみて、Patch Manager設定画面の構成や、設定項目の意味など、戸惑うことも多かったので、ここにまとめておきます。

今回は、AlmaLinux 9 のEC2インスタンスに対して Patch Manager を設定するものとします。

(参考)
・AWS Systems Manager Patch Manager – AWSユーザーガイド
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/patch-manager.html

・Patch Manager 本番・検証環境で時間を分けて自動パッチ適用をしてみた
https://qiita.com/sugimount-a/items/82210ea0b8e791c75688

Patch Managerのしくみ

Patch Managerは、Systems Manager(SSM)の一機能です。
Patch Managerの設定項目としては、大きく分けて2つ、「パッチベースライン」「パッチポリシー」があります。

・パッチベースライン
パッチの適用ルールを指定します。
パッチ適用対象の分類や重要度のほか、パッチリリースから遅延させる期間(何日経ってから適用するか)や、除外ルールなどを指定します。

・パッチポリシー
パッチベースラインと、パッチ適用対象EC2インスタンス、実行スケジュールなど、パッチ適用の実行計画についてまとめて管理します。

パッチ適用の実行処理は、「Run Command」によるコマンドのリモート実行となります。
Run Command のドキュメント(実行するコマンドの定義)としては、「AWS-RunPatchBaseline」を使用します。

「AWS-RunPatchBaseline」ドキュメントについては、
Systems Managerの「ドキュメント」からその内容を確認できます。

なお、Patch Managerは、以前は以下のような構成でした。

  • 「パッチベースライン」でソフトウェアアップデートルールを設定(これは現在と変わらない)。
  • 「パッチグループ」で適用対象EC2インスタンスを選択。
  • 「メンテナンスウインドウ」で実行スケジュールを指定。
  • 「パッチ適用設定」で、パッチ適用の詳細を設定。あるいは、「メンテナンスウインドウ」で、Run Commandタスクを登録。

現在は、「パッチポリシー」の使用がデフォルトとなっており、「パッチグループ」「メンテナンスウインドウ」「パッチ適用設定」は使用しないようになりました。
AWSCLIでは現在でも設定できるのかもしれませんが。

Patch ManagerがサポートするOS

Patch Managerは、Windows Server, Linuxサーバー, macOS といった幅広いOSをサポートしています。
ただし、2026年3月現在、RHEL互換のディストリビューションでいえば、RHELは10をサポートしていますが、AlmaLinux, Rocky Linux, Oracle Linuxは、9.x までのサポートで、10 は対象外となっています。
いずれサポート対象となると思いますが、RHELよりは少し遅れるようです。

(参考)
・Patch Manager でサポートされているオペレーティングシステム – AWSユーザーガイドhttps://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/patch-manager-prerequisites.html#supported-os

Patch Manager設定の前準備

Patch Managerの設定を行う前に、必要な前準備を行います。

(参考)
・Patch Manager の前提条件 – AWSユーザーガイド
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/patch-manager-prerequisites.html#supported-os

  1. SSMへのアクセス
  2. AmazonSSMManagedInstanceCoreポリシーの付与
  3. SSMエージェントのインストール
  4. ソフトウェアのインストール
  5. ログ保存用S3バケットの作成とバケット書き込み権限設定
  6. EC2インスタンスへのタグ付け

1. SSMとS3へのアクセス

EC2から、SSMやS3へのアウトバウンド通信ができる必要があります。
プライベートサブネットに存在するEC2の場合は、NATゲートウェイ経由、もしくは、VPCエンドポイント経由で、SSMやS3にアクセスできるようにします。

VPCエンドポイントを使用する場合は、ssm, ssmmessages, ec2messages, s3 の各エンドポイントを作成します。

(参考)
・Systems Manager のために VPC エンドポイントを使用して EC2 インスタンスのセキュリティを強化する – AWSユーザーガイド
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/setup-create-vpc.html

2. AmazonSSMManagedInstanceCoreポリシーの付与

パッチ適用対象のEC2のIAMロール(インスタンスプロファイル)に、SSMの機能使用に必要となる AmazonSSMManagedInstanceCore ポリシーを付与します。

3. SSMエージェントのインストール

パッチ適用対象のEC2に、SSMエージェントをインストールします。
1,2,3 は、セッションマネージャーによるEC2への接続でも必要となりますので、PatchManagerを使用しなくても、もはや必須といえます。
SSMエージェントのインストールは、EC2インスタンス作成時に、ユーザーデータでインストールコマンドを投入するのが簡単です。

4. ソフトウェアのインストール

DNFベースのOSの場合、リポジトリ情報とパッチファイルを解凍するために zstd、xz、unzip のユーティリティが必要とのことで、インストールします。

 $ sudo dnf install zstd xz unzip

5. ログ保存用S3バケットの作成とバケット書き込み権限設定

現状のパッチポリシーのしくみでは、Patch Managerの実行ログは、S3バケットに保存するようになっています。
(メンテナンスウインドウを使用したPatch Managerの設定では、CloudWatch Logsへのログ保存も可能だったようです。)

そのため、Patch Managerのログ保存専用S3バケットを作成します。
また、このバケットにアクセス可能なIAMポリシーを作成し、パッチ適用対象のEC2のIAMロール(インスタンスプロファイル)にIAMポリシーをアタッチします。

バケットにアクセス可能なIAMポリシーはこんな感じです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::<S3バケット名>/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::<S3バケット名>"
            ]
        }
    ]
}

6. EC2インスタンスへのタグ付け

パッチ適用対象とするターゲットノード(EC2インスタンス)の指定方法はいくつか用意されており、インスタンスをひとつずつ手動選択することもできますが、タグで管理すると運用しやすいでしょう。

例えば、こんなタグを設定します。

キー: PatchManager
値: <パッチポリシー名>

Patch Managerの設定

Patch Managerのメイン設定を行います。
パッチベースラインとパッチポリシーを作成します。

パッチベースラインの作成

パッチベースラインを作成し、パッチの適用ルールを指定します。

Patch Managerでは、各OSに対してデフォルトのパッチベースラインが用意されています。
どのような設定をするか、いきなり設定する前に、自分が設定したいOSのデフォルトパッチベースラインを見てみるとよいでしょう。

AlmaLinuxのデフォルトパッチベースラインは以下のようになっています。

これを参考に、カスタマイズしてみます。

※このデフォルトベースラインからコピー&編集できるとよいのですが、そのような機能はありません。

パッチベースラインを作成します。
名前はてきとうに、オペレーティングシステムは AlmaLinux を指定します。

「オペレーティングシステムの承認ルール」で、パッチ適用ルールを設定します。
今回は、デフォルトベースラインに近い形で、2つの承認ルールを作成します。

  • Securityパッチは、重要度CriticalとImportantで、リリースから2日以上経過したものを適用する。(重要度Moderate以下のものは適用しない。)
  • Bugfixパッチは、リリースから7日以上経過したものを適用する。

・製品(Products)
「製品」の選択メニューを開いてみると、OSのバージョンを指定する箇所のようですので、OSマイナーバージョンが上がっても実行されて問題なければ、「All」を指定します。
(dnf upgradeコマンドによるアップデートですので、メジャーバージョンアップは実行されないはずです。)

・自動承認の日数
今回は上記のように設定しましたが、検証環境はすぐに適用し、本番環境は少し日数を経てから適用する、といった使い分けもよいでしょう。

・パッチの例外
「特定のソフトウェアのみ適用」や、「指定のソフトウェアは適用除外」を指定できます。

パッケージ名は、ワイルドカードの指定も可能です。
複数指定する場合は、カンマ区切りで指定します。
このあたりは、dnfコマンドの引数(除外の場合は excluedオプションの引数に)に、そのまま渡されると思います。

dnf upgrade コマンドを実行するので、リポジトリは有効となっている必要があります。
EPEL や remi など、サードパーティのリポジトリを使用して、アップデート対象としたい場合は、リポジトリを有効としましょう。

今回は、「PHP関連のパッケージを除外」とすることとし、「拒否されたパッチ」として「php*,composer*」を指定します。

※「アプリケーションの動作に関わるので、PHPはアップデートしないでほしい」という要望はよくありますが、アプリケーションレイヤの脆弱性は、WAF以外では守れないので、むしろマイナーバージョアップデートは積極的に実施すべき、と個人的には思います。

composer* を追加したのは、PHP Composerをパッケージインストールした環境で、これを指定しないと、PHPパッケージとの依存関係で Run Command の実行結果がエラーとなったことがあるためです。
(実行結果がエラーとなっても、他のパッケージのアップデートや必要な場合のOS再起動は実行されます。)

「拒否されたパッチのアクション」設定では、拒否されたパッチは、他のパッケージと依存関係があってもアップデートしたくないため、「ブロック」とします。

パッチポリシーの作成

パッチポリシーを作成して、パッチ適用の実行計画についてまとめて管理します。

ここで、例えばALBで複数台のEC2に負荷分散しているようなAWS構成を考えてみます。
このような構成では、同時にOSが再起動することでサービスダウンが発生しないよう、EC2ごとにパッチ適用タイミングをずらすとよいでしょう。
その場合、パッチポリシーの中に実行スケジュール設定が含まれるため、それぞれ別のパッチポリシーを作成することになります。

パッチマネージャーの「パッチマネージャーを作成」からパッチポリシーを作成します

このパッチポリシー設定の実体は、高速セットアップ(Quick Setup)の設定タイプPatch Managerの設定です。
ですので、高速セットアップの画面からもパッチポリシーを作成できます。

パッチポリシーの設定項目について補足します。

・パッチオペレーション
「スキャン」と「インストール」の違いは、パッチベースラインのルールについて適用対象パッケージの報告のみとするか、実際に適用(アップデート実施)するか、です。

Patch Managerの選択肢としては、「スキャン」または「スキャンとインストール」のみで、残念ながら「インストール」のみの指定はできません。。
「スキャンの結果を一度確認してからアップデート実行」という運用を想定しているのでこういう仕様となっているのでしょうが、そこまで手間をかけていられないケースも多いので、即時アップデートのみ実行する機能を用意してくれたらいいのに、と思います。

・スケジュール
スキャンとインストールのスケジュールは、カスタムCRON式で設定するのが現実的でしょう。

タイムゾーンの指定はできないため、UTCで指定します。
ログを見る限り、Patch Managerの実行は指定した時刻に開始されるようですが、実際にアップデートや再起動が実行されるまでには30分以上かかることもありました。
余裕をもって、完了までに1時間程度かかることを見込んで時間設定したほうがよさそうです。

日本時間の毎週月曜4時(UTCで日曜19時)であれば以下のようになります。

cron(0 19 ? * SUN *)

毎日実施するのであれば、「日単位」で時刻(UTC)を指定するとよいでしょう。

パッチオペレーションを「スキャンとインストール」とするときのスケジュール設定は悩みどころですが、僕は、インストール前にスキャン結果を確認しないことと、処理時間を考慮して、スキャンとインストールの間隔を1時間ぐらいとしました。

・最初の CRON 間隔まで更新プログラムのインストールを待ちます。
ここはわかりにくいのですが、無効の場合は、このパッチポリシーを作成または更新した直後に、「スキャン」または「インストール」が実行されます。
有効の場合は、「待ちます」というとおり、カスタムCRON式の指定日時まで待ちます。

・必要に応じて再起動
アップデート後に起動したプロセスに対してアップデートが実際に反映されるため、即時反映したい場合は、「必要に応じて再起動」を有効にします。

・パッチベースライン
パッチベースラインの指定では、AlmaLinuxのところで、先ほど作成したパッチベースラインを選択します。
この画面から、1つのパッチポリシーで複数種類のOSを対象として設定できることがわかります。

・ログストレージにパッチ適用 (Patching log storage)
日本語がわかりにくいですが、ログ出力設定です。
先ほど作成したログ出力用S3バケットを指定します。

・ターゲット
パッチ適用対象のリージョンとEC2インスタンスを指定します。
リージョン内のすべてのインスタンスを対象にすることも可能ですが、今回は、タグで指定します。

・レートの制御
パッチ適用の同時実行インスタンス数と、パッチ適用の実行が失敗する前にエラーを許可するノードの数または割合のしきい値(このしきい値分の失敗をしたときは、それ以降のインスタンスへの実行をやめる)を指定します。
対象とするインスタンスが多いときに、システム全体のネットワーク負荷や、大量の実行失敗を防ぐためのガードレールとなるでしょう。

・必要な IAM ポリシーを、インスタンスにアタッチされている既存のインスタンスプロファイルに追加します。
有効にすると、パッチポリシーの作成・更新時に、必要なポリシーが自動設定されます
ここは、有効にしておいたほうが確実だと思います。
(僕は最初は無効で作成して、権限エラーでパッチ適用の実行エラーとなり、調査に余計な時間がかかってしまいました。)

この設定項目の説明としては、マネジメントコンソールで以下のように表示されています。

このオプションを有効にすると、Quick Setup は、インスタンスプロファイルがアタッチされたインスタンスにも IAM ポリシーを追加します。ポリシー (
「AmazonSSMManagedInstanceCore」
「aws-quicksetup-patchpolicy-baselineoverrides-s3」
) が添付されます。

僕が調べた限りでは、EC2のIAMロールに、
AmazonSSMManagedInstanceCore
AWSQuickSetupPatchPolicyBaselineAccess
の2つのポリシーが追加されていました。

・デプロイロール
高速セットアップによるパッチポリシーに必要となるリソースの作成に必要なポリシーを詳細に把握していない限り、デフォルトの
「QuickSetup の信頼できるアクセス用のロールを作成して使用する」
でよいでしょう。

・設定マネージャーの詳細
高速セットアップの設定名となります。
デフォルトで入力されている、パッチポリシー名と同じ名前でよいでしょう。

ひととおり指定し、「作成」ボタンをクリックすると、デプロイ処理が開始され、パッチポリシーに必要な各種リソースが作成、必要な権限設定などが実行されます。
作成完了まで、数分かかります。

なお、パッチポリシーは、パッチマネージャーの画面には表示されません。
高速セットアップの設定ということで、「高速セットアップ」の「設定マネージャー」で表示されます。
ここから設定名を選択して、アクションメニューの「設定を編集」から、作成したパッチポリシーを編集できます。

また、S3バケット aws-quicksetup-patchpolicy--xxxxx が作成されます。
これは、パッチベースライン情報のjsonファイルを保存するバケットです。
さらに、そのS3バケットへのアクセスログを保存する
S3バケット aws-quicksetup-patchpolicy-access-log-<AWSアカウントID>-xxxxx
も作成されます。
これらのバケットは、パッチポリシーを作成するたび(あるいは、スキャンの初回実行時)に、新しく作成されます。

このS3バケットにアクセスするためのポリシーが、先ほどEC2のIAMロールに自動アタッチされた
AWSQuickSetupPatchPolicyBaselineAccess
です。

Patch Managerの動作確認

ひととおりの設定が完了したので、パッチ適用の動作確認を行います。

Patch Managerの実行

高速セットアップからパッチポリシーの編集画面を開き、スキャンのスケジュール and/or インストールスケジュールの
「最初の CRON 間隔まで更新プログラムのインストールを待ちます。」
を無効にして保存します。

これにより、保存が完了した時点で、パッチ適用のスキャンまたはインストールが開始されます。

実行結果の確認

Patch Managerの実行結果は、先ほど指定したログ保存用S3バケットに保存されますが、日付の階層がないため、最新のログは見つけにくいです。
Run Command画面のコマンド履歴 >ドキュメント名「AWS-RunPatchBaseline」の履歴
から該当インスタンスを選択して、実行結果を確認できます。

ステップ 1 はWindows
ステップ 2 はLinux
ステップ 3 はmacOS
の実行結果です。

Run CommandコマンドのAWS-RunPatchBaselineドキュメントとしては、マルチプラットフォームに対応しているので、OSが何であれ、この3ステップが実行されるようです。
今回のサーバーはLinuxですので、ステップ 2のエリアでOutput(標準出力)とError(標準エラー出)を確認できます。

なお、ログ保存用S3バケットの階層は、Run CommandコマンドのコマンドIDとEC2のインスタンスIDが含まれます。
S3バケットのほうを確認してみると、、、

stdoutファイルが標準出力、stderrファイルが標準エラー出力です。

EC2インスタンスでの確認

EC2にSSH接続して、パッケージのアップデート履歴や、OSの再起動が発生したかどうかを確認します。

 $ sudo dnf history

ID     | Command line              | Date and time    | Action(s)      | Altered
--------------------------------------------------------------------------------
    15 | install -y python3-urllib | 2026-03-11 12:35 | Upgrade        |    1
    14 | install -y openssl-1:3.5. | 2026-03-11 12:35 | Upgrade        |    3
    13 | install -y libsss_certmap | 2026-03-11 12:34 | Upgrade        |    8
    12 | install -y libbrotli-0:1. | 2026-03-11 12:34 | Upgrade        |    1
    11 | install -y kernel-tools-0 | 2026-03-11 12:34 | Upgrade        |    2
    10 | install -y kernel-0:5.14. | 2026-03-11 12:33 | Install        |    4
     9 | install -y gnupg2-0:2.3.3 | 2026-03-11 12:33 | Upgrade        |    1
     8 | install -y expat-0:2.5.0- | 2026-03-11 12:33 | Upgrade        |    1
     7 | install -y epel-release-0 | 2026-03-11 12:33 | Upgrade        |    1
     6 | install composer          | 2026-03-11 11:32 | Install        |    5  <
     5 | install php               | 2026-03-11 11:31 | Install        |   22 ><
     4 | install epel-release      | 2026-03-11 11:12 | Install        |    1 >E
     3 | install zstd xz unzip     | 2026-03-11 11:05 | Install        |    2  <
     2 | install -y https://s3.ap- | 2026-03-11 11:04 | Upgrade        |    1 >
     1 | install -y https://s3.ap- | 2026-03-10 16:37 | Upgrade        |    1

↑12時33分以降のものが、Patch Managerによるアップデートです。
1パッケージにひとつずつ、dnfコマンドが実行されていることがわかります。

 $ uptime -s

2026-03-11 12:51:25

↑OSが再起動され、12時51分に起動されたことがわかります。

コンプライアンスレポート

パッチマネージャー画面の「コンプライアンスレポート」で、パッチ適用状況を確認できます。
ここでいう「コンプライアンス」は、指定したパッチベースラインの承認ルールに従っているかどうか、を意味します。
最後にスキャンまたはインストールを実行した時点で、承認ルールを満たすすべてのパッチが最新であれば「準拠」であり、そうでなければ「非準拠」となります。

(参考)
・Patch Manager におけるコンプライアンスとは。 – AWSユーザーガイド
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/patch-manager.html#patch-manager-definition-of-compliance

フリートマネージャーでの確認

フリートマネージャーの画面でも、EC2インスタンスごとに、パッケージごとのパッチ適用状況や、コンプライアンスの状況を個別に確認できます。

適用状態などによる絞り込みも可能です。

おわりに

AWS Patch Managerのひととおりの設定と、設定項目の意味、動作確認についてまとめました。

設定項目はやや多いのですが、パッチ適用のルールやスケジュール、適用対象リソースを細かく指定でき、自動でパッチ適用を実行するだけではなく、パッチ適用状況を確認できる便利な機能です。
また、運用するEC2インスタンスが多いほど、メリットがありそうです。

機能構成としては、ルール設定、スケジュール設定、タグ等による対象リソース指定など、AWS Backupに近いと感じました。

AWS Backupはいろいろな情報を一つの画面で確認できるので、Patch Managerも、パッチポリシーの編集や、RunCommandの履歴など、パッチマネージャーの画面で一元管理して、確認できるようになるとうれしいですね。

タイトルとURLをコピーしました