検証・本番環境を考慮した EC2インスタンスへのパッチ適用環境を作ってみる【SSMメンテナンスウィンドウ編】
はじめに
上図のように インスタンスの タグを使って パッチを当てる/当てない や パッチ内容 をコントロールできるようなパッチ当て環境を実装してみます。
前回のブログでは Patch Manager と State Manager を活用しました。
今回は Patch Manager と Maintenance Windows を使います。
前提条件
今回は Amazon Linux 2 のインスタンス群からなる検証/本番環境を前提として話を進めます。
また、検証環境/本番環境がアカウント分離されているかどうかは問いません。
実現したい環境
- 時間的制約があるインスタンス※ へ重要パッチを適用させたい
- 定期的にパッチが当たるようにしたい
- 事前にどのパッチが当たるかを判断するために、「スキャンのみ」も実施できるようにしたい
- 検証環境/本番環境でパッチ内容を変えたい(例: タイミングをずらす)
※ここでいう 「時間的制約があるインスタンス」 は、例えば以下のような事情を持つモノです。
- どうしてもパッチ当て作業の負荷/影響を受けたくない時間帯があるモノ
- 厳密にメンテナンス期間を指定しているモノ
このようなインスタンスには Maintenance Windows が活かせます。 制約のない場合は Maintenance Windows でも良いですし、 前回ブログ のように State Manager でも良いでしょう。
設計
時間的制約はインスタンスごとに異なります。 その 時間的制約単位でメンテナンスウィンドウを作る 必要があります。
以降の設計は 毎日 AM2:00 – AM3:00 をメンテナンス期間としてパッチ当て可能 な検証/本番インスタンスを対象にした 設計とします。
インスタンスの タグ を使って パッチを当てる/当てない や パッチ内容 をコントロールします。 具体的には以下の 2種類のタグを使って、インスタンスを分類してみます。
Patch Group タグ |
PatchWindowTaskAM2 タグ |
分類 |
---|---|---|
STG | SCAN | 検証環境のインスタンス(AM2:00 -- AM3:00 パッチ当て可)。パッチスキャンのみ |
STG | INSTALL | 検証環境のインスタンス(AM2:00 -- AM3:00 パッチ当て可)。パッチ当てを行う |
PRD | SCAN | 本番環境のインスタンス(AM2:00 -- AM3:00 パッチ当て可)。パッチスキャンのみ |
PRD | INSTALL | 本番環境のインスタンス(AM2:00 -- AM3:00 パッチ当て可)。パッチ当てを行う |
この分類に応じた 「Patch Manager ベースライン」「Maintenance Window」設計を行います。
Patch Manager ベースライン
(前回のブログ と同じ内容です。詳細はこちら御覧ください)
以下 2種類のベースラインを作成します。 検証環境インスタンス、本番環境インスタンスでパッチ内容を分けるように設定します。
STG用 ベースライン | PRD用 ベースライン | |
---|---|---|
名前 | STG-AL2Baseline | PRD-AL2Baseline |
パッチグループ | Patch Group=STG |
Patch Group=PRD |
承認ルール#1 | Security/Critical/リリース後 1日 | Security/Critical/リリース後 31日 |
承認ルール#2 | Security/Important/リリース後 1日 | Security/Important/リリース後 31日 |
Maintenance Window タスク
メンテナンスウィンドウの設計です。 ざっくりと説明すると、以下のパラメータを定めます。
- スケジュール
- タスクを実行できる期間
- ターゲット
- タスクを実行するインスタンス
- インスタンスIDやタグで指定 (今回は タグを利用)
- 複数作成可
- タスク
- ターゲットとSSMドキュメントの組み合わせ
- 複数作成可
スケジュールは 毎日 AM2:00 -- AM3:00
です。
この時間帯にタスクを実行できるメンテナンスウィンドウを作成します。
パッチ適用を行う SSMドキュメントは AWS-RunPatchBaseline です。
AWS-RunPatchBaseline
の主なパラメータは以下 2つ。
RebootOption=Reboot/NoReboot
… パッチ適用後に再起動するか、しないかOperation=Scan/Install
… スキャンのみ行うか、インストールまで行うか
よって、以下のように スキャン用のウィンドウタスクと インストール用のウィンドウタスクを 作成すれば良さそうです。
スキャン用 ウィンドウタスク | インストール用 ウィンドウタスク | |
---|---|---|
名前 | patch-windowtask-scan | patch-windowtask-install |
ターゲット | PatchWindowTaskAM2=SCAN |
PatchWindowTaskAM2=INSTALL |
Operationパラメータ | Scan | Install |
設計まとめ
改めて 実現したい環境と、その解決案をまとめます
- 時間的制約があるインスタンス へ重要パッチを適用させたい
- → Maintenance Window を活用
- 定期的にパッチが当たるようにしたい
- → Maintenance Window を活用
- 事前にどのパッチが当たるかを判断するために、「スキャンのみ」も実施できるようにしたい
- → SCAN用ターゲット/タスク、INSTALL用ターゲット/タスクを作成。
PatchWindowTaskAM2
タグで分類できるようにする
- → SCAN用ターゲット/タスク、INSTALL用ターゲット/タスクを作成。
- 検証環境/本番環境でパッチ内容を変えたい(例: タイミングをずらす)
- → STG用ベースライン、PRD用ベースラインを作成。
Patch Group
タグで分類できるようにする
- → STG用ベースライン、PRD用ベースラインを作成。
構築
Patch Manager ベースライン
前回ブログ と変わりません。 以下のような CloudFormation テンプレートを作成して、展開しています。 Patch Manager ベースラインを 2つ展開します。
AWSTemplateFormatVersion: '2010-09-09' Parameters: # --- PatchBaseline(STG) BaseLineNameSTG: Type: String Default: STG-AL2Baseline PatchGroupSTG: Type: String Default: STG ApproveAfterDaysSTG: Type: Number Default: 1 # --- PatchBaseline(PRD) BaseLineNamePRD: Type: String Default: PRD-AL2Baseline PatchGroupPRD: Type: String Default: PRD ApproveAfterDaysPRD: Type: Number Default: 31 Resources: # --- PatchBaseline(STG) STGBaseline: Type: AWS::SSM::PatchBaseline Properties: Name: !Ref BaseLineNameSTG OperatingSystem: AMAZON_LINUX_2 PatchGroups: - !Ref PatchGroupSTG ApprovalRules: PatchRules: - ApproveAfterDays: !Ref ApproveAfterDaysSTG ComplianceLevel: CRITICAL EnableNonSecurity: false PatchFilterGroup: PatchFilters: - Key: CLASSIFICATION Values: [Security] - Key: SEVERITY Values: [Critical] - ApproveAfterDays: !Ref ApproveAfterDaysSTG ComplianceLevel: HIGH EnableNonSecurity: false PatchFilterGroup: PatchFilters: - Key: CLASSIFICATION Values: [Security] - Key: SEVERITY Values: [Important] # --- PatchBaseline(PRD) PRDBaseline: Type: AWS::SSM::PatchBaseline Properties: Name: !Ref BaseLineNamePRD OperatingSystem: AMAZON_LINUX_2 PatchGroups: - !Ref PatchGroupPRD ApprovalRules: PatchRules: - ApproveAfterDays: !Ref ApproveAfterDaysPRD ComplianceLevel: CRITICAL EnableNonSecurity: false PatchFilterGroup: PatchFilters: - Key: CLASSIFICATION Values: [Security] - Key: SEVERITY Values: [Critical] - ApproveAfterDays: !Ref ApproveAfterDaysPRD ComplianceLevel: HIGH EnableNonSecurity: false PatchFilterGroup: PatchFilters: - Key: CLASSIFICATION Values: [Security] - Key: SEVERITY Values: [Important]
▼ (参考) STG用ベースライン
▼ (参考) PRD用ベースライン
Maintenance Window
以下 CloudFormation テンプレートを作成して、展開しました。 メンテナンスウィンドウ、およびウィンドウターゲット/タスクを作成しています。
AWSTemplateFormatVersion: '2010-09-09' Parameters: WindowName: Type: String Default: patch-window-am2 ScheduleExpression: Type: String Default: "cron(00 17 * * ? *)" DurationHours: Type: Number Default: 1 Cutoff: Type: Number Default: 0 TargetKey: Type: String Default: PatchWindowTaskAM2 TimeoutSeconds: Type: Number Default: 1800 # --- Window Target(Scan) TargetValueScan: Type: String Default: SCAN # --- Window Target(Install) TargetValueInstall: Type: String Default: INSTALL # --- Logging OutputS3BucketName: Type: String OutputS3KeyPrefixScan: Type: String Default: "patch/window/scan/" OutputS3KeyPrefixInstall: Type: String Default: "patch/window/install/" Resources: # --- Window Window: Type: AWS::SSM::MaintenanceWindow Properties: Name: !Ref WindowName AllowUnassociatedTargets: true Cutoff: !Ref Cutoff Duration: !Ref DurationHours Schedule: !Ref ScheduleExpression # --- Window Target/Task(Scan) WindowTargetScan: Type: AWS::SSM::MaintenanceWindowTarget Properties: Name: PatchingTargetScan ResourceType: INSTANCE Targets: - Key: !Sub "tag:${TargetKey}" Values: - !Ref TargetValueScan WindowId: !Ref Window WindowTaskScan: Type: AWS::SSM::MaintenanceWindowTask Properties: MaxConcurrency: "50%" MaxErrors: "50%" Name: PatchingTaskScan Priority: 1 Targets: - Key: WindowTargetIds Values: - !Ref WindowTargetScan TaskArn: AWS-RunPatchBaseline TaskType: RUN_COMMAND WindowId: !Ref Window TaskInvocationParameters: MaintenanceWindowRunCommandParameters: TimeoutSeconds: !Ref TimeoutSeconds Parameters: Operation: ["Scan"] RebootOption: ["NoReboot"] OutputS3BucketName: !Ref OutputS3BucketName OutputS3KeyPrefix: !Ref OutputS3KeyPrefixScan # --- Window Target/Task(Install) WindowTargetInstall: Type: AWS::SSM::MaintenanceWindowTarget Properties: Name: PatchingTargetInstall ResourceType: INSTANCE Targets: - Key: !Sub "tag:${TargetKey}" Values: - !Ref TargetValueInstall WindowId: !Ref Window WindowTaskInstall: Type: AWS::SSM::MaintenanceWindowTask Properties: MaxConcurrency: "50%" MaxErrors: "50%" Name: PatchingTaskInstall Priority: 1 Targets: - Key: WindowTargetIds Values: - !Ref WindowTargetInstall TaskArn: AWS-RunPatchBaseline TaskType: RUN_COMMAND WindowId: !Ref Window TaskInvocationParameters: MaintenanceWindowRunCommandParameters: TimeoutSeconds: !Ref TimeoutSeconds Parameters: Operation: ["Install"] RebootOption: ["NoReboot"] OutputS3BucketName: !Ref OutputS3BucketName OutputS3KeyPrefix: !Ref OutputS3KeyPrefixInstall
▼ ざっくりリソース解説
大枠として patch-window-am2
というメンテナンスウィンドウを作成します。
毎日 AM2:00 -- AM3:00
の間をメンテナンス期間とします。
このウィンドウ配下にターゲット、およびタスクを登録していきます。
次に、それぞれターゲット(WindowTarget[Scan|Install]
)を作成します。
タグ指定です。 PatchWindowTaskAM2
タグによって、どちらのターゲットかを指定します。
そして、それぞれタスク(WindowTask[Scan|Install]
)を作成しています。
タスクは「ターゲット」と「実行するSSMドキュメント」の組み合わせです。
SCAN用ターゲットには 「Operation=Scan」パラメータを渡した AWS-RunPatchBaseline
を、
INSTALL用ターゲットには 「Operation=Install」パラメータを渡した AWS-RunPatchBaseline
をタスクとして登録します。
また、SSMドキュメントの実行ログを S3バケットへ格納する設定を入れています。 S3バケットへ格納しない場合は、 Run Command のコンソールから実行ログ(24,000文字まで)を確認できます。 AWS-RunPatchBaseline の実行ログは多いため、ほぼ 24,000文字以降のログが省略されます。 証跡を残すためにも S3へ保存しましょう。
▼ (参考) メンテナンスウィンドウ
▼ (参考) メンテナンスウィンドウ ターゲット
▼ (参考) メンテナンスウィンドウ タスク
確認
STG環境インスタンスへ「スキャン」を行う
以下のようなタグ情報を付与したEC2インスタンスを作成しました。
1日経った後にメンテナンスウィンドウを確認します。履歴からパッチスキャン実行を確認できました。
Run Command の実行ログも コンソールで確認。さらに S3バケットへ格納されていることを確認できました。
PRD環境インスタンスへ「パッチ当て」を行う
次に以下 タグ情報を付与したEC2インスタンスを作成してみます。
1日経った後にメンテナンスウィンドウを確認します。履歴からパッチインストール実行を確認できました。
Run Command の実行ログも コンソールで確認。さらに S3バケットへ格納されていることを確認できました。
おわりに
以上、メンテナンスウィンドウを使ったパッチ適用環境の一例でした。
前回ブログ の State Managerとの使い分けを簡単にまとめます
- 定期的なパッチ当てをしたい → どちらでもできます
- Auto Scaling から起動されるインスタンスも等しくパッチ適用されている状態にしたい → State Manager がおすすめです
- 時間的制約があるインスタンスへパッチ適用したい → Maintenance Windows がおすすめです
Patch Manager 活用の際の参考になれば幸いです。
参考
- AWS Documents
- DevelopersIO