AWS Systems Managerでパッチ適用を自動化する

はじめに

今回業務でパッチ適用の自動化に携わりましたので、備忘録としてハンズオン形式で残します。
今後Automationを使用したパッチ適用の自動化をされる方の参考になれば幸いです。
※設定多いので、内容長いです※

全体的な構成

今回はLinuxとWindowsの複数サーバのパッチ適用自動化に取り組みました。
全体的なイメージは以下です。

【Patch Manager】

Patch Managerでは、対象のインスタンスにパッチ適用する設定を行います。
こちらはハンズオンの記事がたくさん出回っていますので、以下の記事がわかりやすいので参考ください。
SSMのPatch Managerを利用したEC2への自動パッチ適用

【Mentenance Windows】

メンテナンスウィンドウではスケジュールを設定します。
メンテナンスウィンドウ内に[タスク]を複数作成することができ、実行順序を決められます。
例えば、[タスク1]実行完了後、[タスク2]を実行する、等です。

つまり、メンテナンスウィンドウ内のタスクは、同日のスケジュールで実行したいタスクを設定すれば良いです。

【Automation】

Automationには、自動化したい一連の流れを登録することができます。

例えば、以下の流れです。
①インスタンスIDを取得する
②パッチ適用を実施する
③EC2を再起動する
④正常性確認を行う。

AWS側ですでに用意されているドキュメントも使用できますし、スクリプトを直接設定することや、サーバー上に配置しているスクリプトを実行するように設定することもできます。

また、Automationの中にAutomationを設定することもできます。
例えば以下のように、Automation1の中にAutomation3を組み込むことができます。

複数サーバで同じ動きをするドキュメントを一つのAutomationにして使いまわすと便利です。

今回のハンズオン

今回は、赤枠の部分を作成していきたいと思います。

ハンズオン…の前に

この後ハンズオン形式で説明していきますが、こちらの記事では、メンテナンスウィンドウとパッチベースラインの設定は説明されていますので、この部分のハンズオンは省きます。
上記記事の「3.適用設定」は即時適用の方法となりますので、「3.適用設定」実行せずに戻ってきてください。

今回は、メンテナンスウィンドウタスクの作成と、Automationドキュメントの作成の部分をメインに説明していきたいと思います。

ハンズオン

前提

・AWSアカウントがあること
・ルートユーザー以外のユーザーを使用していること
SSM Agent がプリインストールされたEC2インスタンスを作成していること

IAMロールの作成

①EC2にアタッチするロールを以下のポリシーを含み、ロールを作成します。
こちらの手順を参考にロールを作成します。

②SSMに使用するロールを、以下のポリシーを含み、ロールを作成します。
こちらの公式ドキュメントを参照ください。
※SSMにて実行する操作により、使用するポリシーが変わります。詳しくはAWS Systems Manager API リファレンスをご確認ください。

Automation runbookの作成

まずはAutomation runbookから作成していきます。以下の部分です。

[オートメーション]→[Create runbook]をクリックします。

ビジュアルデザインエクスペリエンス(というらしい)が表示されますので、ここでドキュメントを設定していきます。
まずは左上のオレンジ枠でランブック名を入力します。

左の赤枠から該当のドキュメントをDnD(ドラッグアンドドロップ)し、真ん中で並べます。

そして真ん中のドキュメント(青枠)をクリックすると、右側の青枠で詳細を設定できます。

詳しくはドキュメントを参照ください

今回は、以下の流れで作ってみましたので、一つずつ設定を解説していきます。
①パッチ適用を実施する
②インスタンスIDを取得する
③EC2を再起動する
④正常性確認を行う
⑤完了したらSNSで通知する
⑥失敗したらSNSで通知する

ランブック属性の設定

真ん中のグリッド線のドキュメント以外のところをクリックします。
・[属性]タブの[ロールを割り当てる]でSSM用に作成したロールを割り当てます。

・[パラメータ]タブで使用するパラメータを設定します。
※EC2インスタンスの指定は、タグを使用して指定するのですが、その際以下のパラメータを使用します。

①パッチ適用を実施する

左側の[アクション] ブラウザーの[インスタンスでコマンドを実行]アクションを使用し、以下を設定します。

【全般】タブを以下の通り入力します。
・ステップ名:applyOSPatch
・説明:OSパッチ適用(自由に入力)

【インプット】タブを以下の通り入力します。
・ドキュメント名:AWS-RunPatchBaseline ドキュメントはこちら
・Targets -オプション:以下の通り設定します。※{{ExecTarget}}は先ほどランブック属性で設定したパラメータです。

- Name: tag:Name
     Values: ‘{{ExecTarget}}’

【出力】タブは設定しません。

【設定】タブを以下の通り入力します。
・最大試行回数(自由に設定)
・タイムアウト秒数(自由に設定)
・クリティカル:true(デフォルト)
・次のステップ(自動で入力される)
・失敗した場合(設定する場合手動で入力必要。EmptyでもOK)
・キャンセルした場合(設定する場合手動で入力必要。EmptyでもOK)

②インスタンスIDを取得する

左のAWS APIタブから[DescribeInstances]を探し、Startの下にドラックアンドドロップします。(検索画面で検索もできます)

【全般タブ】を説明を以下の通り入力します。
・ステップ名:getEC2InstanceID
・説明:自由に入力

【インプット】タブを以下の通り入力します。
・その他の入力 – オプション
 名前:Filters
入力値:

- Name: tag:Name
     Values: ‘{{ExecTarget}}’

【出力】タブを以下の通り入力します。
名前: EC2InstanceID
セレクター: $.Reservations..Instances..InstanceId
タイプ: StringList
 

【設定】タブを以下の通り入力します。
・最大試行回数(自由に設定)
・タイムアウト秒数(自由に設定)
・クリティカル:true(デフォルト)
・次のステップ(自動で入力される)
・失敗した場合(設定する場合手動で入力必要。EmptyでもOK)
・キャンセルした場合(設定する場合手動で入力必要。EmptyでもOK)

③EC2を再起動する

【全般タブ】を説明を以下の通り入力します。
・ステップ名:reStartEC2
・説明: EC2を再起動する

【インプット】タブを以下の通り入力します。
名前を入力: RuntimeParameters
入力値: InstanceId: ‘{{getEC2InstanceID.EC2InstanceID}}’

【出力】タブは設定しません。

【設定】タブを以下の通り入力します。
・最大試行回数(自由に設定)
・タイムアウト秒数(自由に設定)
・クリティカル:true(デフォルト)
・次のステップ(自動で入力される)
・失敗した場合(設定する場合手動で入力必要。EmptyでもOK)
・キャンセルした場合(設定する場合手動で入力必要。EmptyでもOK)

④正常性確認を行う。

【全般タブ】を説明を以下の通り入力します。
・ステップ名:statusCheck
・説明:ステータスチェックを行う

【インプット】タブを以下の通り入力します。
ドキュメント名: AWS-RunShellScript
パラメータ -コマンド-: "/sh/statusCheck.sh"(スクリプトのパスです。事前に作成してしておきます)
Targets – オプション

- Key: tag:Name
     Values: ‘{{ExecTarget}}’


【出力】タブは設定しません。

【設定】タブを以下の通り入力します。
・最大試行回数(自由に設定)
・タイムアウト秒数(自由に設定)
・クリティカル:true(デフォルト)
・次のステップ(自動で入力される)
・失敗した場合(設定する場合手動で入力必要。EmptyでもOK)
・キャンセルした場合(設定する場合手動で入力必要。EmptyでもOK)

⑤完了したらSNSで通知する

【全般タブ】を説明を以下の通り入力します。
・ステップ名:nomalEnd
・説明: 正常終了

【インプット】タブを以下の通り入力します。
・Message : message:成功しました。(メールの本文なので自由に設定)
・その他の入力 – オプション
 名前を入力:TopicArn
 入力値:<SNSのARNを入力※SNSトピックを作成してください>

名前を入力:Subject
入力値:Title:success

【出力】タブは設定しません。

【設定】タブを以下の通り入力します。
・最大試行回数(自由に設定)
・タイムアウト秒数(自由に設定)
・クリティカル:true(デフォルト)
・次のステップ(自動で入力される)
・失敗した場合(Empty)
・キャンセルした場合(Empty)

⑤失敗したらSNSで通知する

【全般タブ】を説明を以下の通り入力します。
・ステップ名:AbnomalEnd
・説明:異常終了で通知する

【インプット】タブを以下の通り入力します。
・Message:message:失敗しました
・その他の入力 – オプション
 名前を入力:TopicArn
 入力値:<SNSのARNを入力※SNSトピックを作成してください>

 名前を入力:Subject
 入力値:title:失敗しました

【出力】タブは設定しません。

【設定】タブを以下の通り入力します。
・最大試行回数(自由に設定)
・タイムアウト秒数(自由に設定)
・クリティカル:true(デフォルト)
・次のステップ(自動で入力される)
・失敗した場合(Empty)
・キャンセルした場合(Empty)

これですべての設定は終わりです。
右上の[新しいバージョンを作成]をクリックして、作成完了です。

※注意※IAMポリシーの設定を忘れずに

Automationに設定したドキュメントを実行する為には、SSM用に作成したIAMロールに必要なポリシーのActionを含めてください。

今回であれば、以下は追加で設定が必要です。
・ec2:DescribeInstances
・ec2:StopInstances
・sns:Publish
他、不足しているポリシーがあれば、メンテナンスウィンドウを実行した際にエラーとなって出力されますので、都度修正しましょう。

メンテナンスウィンドウの設定

左のナビゲーションペインで[メンテナンスウィンドウ]をクリックします。
右上の[メンテナンスウィンドウの作成]をクリックします。

以下を設定し、一番下の[メンテナンスウィンドウの作成]をクリックします。
※設定値はご自由に設定ください。

メンテナンスウィンドウの一覧画面に戻るので、先ほど作成したメンテナンスウィンドウのウィンドウIDをクリックします。

メンテナンスウィンドウの設定詳細画面が出てくるので、右上の[アクション]から[オートメーションタスクの登録]を選択します。

オートメーションタスクの登録画面です。
以下を入力していきます。

先ほど作成したAutomationドキュメントを設定します。

ターゲットと入力パラメータを設定します。
入力パラメータには、オートメーションで設定したパラメータが自動で出てきます。

今回ExceTargetにはパッチ適用したいEC2インスタンスのNAMEタグの値を設定します。

IAMサービスロールを設定します。
SSM用に作成したロール(オートメーションでも設定しているロール)のarnを選択します。(検索も可)

選択したら、一番下の[オートメーションタスクの登録]をクリックします。

ウィンドウタスクが作成されました。

あとはメンテナンスウィンドウで設定した時間を待つのみです。

メンテナンスウィンドウタスクの実行結果確認

メンテナンスウィンドウ > ウィンドウID > 履歴 を選択すると以下の画面が表示されるので、ウィンドウIDを選択し、[詳細の表示]をクリックします。

[Execution Details]の画面が表示される。

下にスクロールし、[タスク呼び出し]のIDを選択し、[詳細の表示]をクリックする。

[Execution detail: オートメーション名]が表示されます。

下にスクロールし、[Executed step]で各ステップのステータスを確認することができます。

ステータスにFailedがあった場合は、該当のステップIDをクリックすると以下の画面になりますので、[ExecutionId]をクリックします。

ステータスがFailedになっているステップIDをクリックします。

次の画面で[Failure details]に失敗した理由が記載されていますので、確認しトラブルシューティングできます。

ハンズオンは以上です。

停止対応

以下のリソースは課金されますので停止しましょう。
・EC2インスタンス → 停止
・メンテナンスウィンドウ → アクション → メンテナンスウィンドウの無効化

最後に

お疲れ様でした。

実際のパッチ適用は更に更に工程が多く、複数サーバにで各10~30ステップ程作成しました。
手作業だと4-5時間かかってしまっていたのが、10分ほどで完了!これぞ自動化の醍醐味!って感じですね。
オートメーション様様です。

Last modified: 2024-03-14

Author