Systems Manager Patch Managerを試す
Terraformを使い、AWS Systems Manager Patch Managerで定期的にUbuntu EC2インスタンスのパッケージ更新を自動化する手順を紹介しています。適用前後の“apt upgrade”結果を比較することで、Patch Managerが有効にアップデートを行っている様子を確認できます。
目次
はじめに
- EC2に対して一括でパッチ適用できるSystems Manager Patch Managerを試してみました
- 参考
やること
- 1年程度前の古いUbuntu AMIのEC2を複数定義する
- ユーザー定義のパッチアップデート(AWSマネージドルール)をSystems managerから行う
- Patch Managerの機能というより実態はRun Commandの定期実行
- EC2にSession Managerで接続し、パッチのアップデート前後で
apt update, apt upgrade
を実行し、どの程度アップデートが必要かを比較する - Patch Managerによりアップデートが走っているはずなので、あとのほうが
apt upgrade
必要なダウンロード数は減っているはずである
Patch Managerのコード
Terraformではこのように書くらしい
- 「OS」というタグが「Ubuntu 24.04 LTS」のEC2を対象にアップデートする
- AWS定義のベースラインのパッチを適用する(
AWS-RunPatchBaseline
) - 実験用に結果を早く得たいので1時間に1回定義している
###############################
# Systems Manager Patch Manager Association:
# タグ "OS" が "Ubuntu 24.04 LTS" のインスタンスに対してパッチ適用を実行
###############################
resource "aws_ssm_association" "patch_manager_association" {
name = "AWS-RunPatchBaseline" # AWS提供のパッチ実行ドキュメント
# タグフィルターで対象のEC2インスタンスを選択
targets {
key = "tag:OS"
values = ["Ubuntu 24.04 LTS"]
}
# パラメータ設定
# Operation: "Install" にすることでパッチのインストールを実施
# RebootOption: "RebootIfNeeded" にすることで必要に応じて再起動を実行
parameters = {
Operation = "Install"
RebootOption = "RebootIfNeeded"
}
# スケジュール設定:1時間ごとにパッチ適用を実施
# ※「rate(7 days)」は CloudWatch Events の rate 式です。必要に応じて cron 式等に変更可能です。
schedule_expression = "rate(1 hour)"
}
結果
パッチ適用前のapt upgrade
apt update→apt upgradeの結果
267 upgraded, 12 newly installed, 0 to remove and 2 not upgraded.
77 standard LTS security updates
Need to get 303 MB of archives.
After this operation, 327 MB of additional disk space will be used.
327MBの追加が必要
パッチ適用後のapt upgrade
188 upgraded, 6 newly installed, 0 to remove and 2 not upgraded.
Need to get 166 MB of archives.
After this operation, 141 MB of additional disk space will be used.
141MBの追加が必要。したがって、Patch Managerのパッチアップデートで必要なアップデートが一定行われている。
マネジメントコンソールからの確認
「パッチポリシーに基づかないオペレーション」「パッチポリシーに基づかないお繰り返しタスク」に追加されている。
terraform apply
するとすぐにパッチアップデートが走る
NATインスタンスを見ると急にトラフィックが増えている。これは裏でパッチアップデートが走って、インターネット経由のトラフィックが出ているため。
しばらくすると4個が成功している。失敗している1個はSession Managerの途中で、apt upgrade
の確認画面で放置し、apt upgradeの競合が置きているため。Patch Managerそのもののエラーではない。
Terraformのコード
EC2の定義。Session Managerが使える条件と、Patch Managerが使える条件はほぼイコールで、インスタンスプロファイル(EC2のIAMロール)にAmazonSSMManagedInstanceCore
を追加しておけば良い。
古いAMI
var.old_ami_id
には次のものを使っている。以下の内容だった。
variable "old_ami_id" {
type = string
description = "古いUbuntuAMIのID"
default = "ami-01bef798938b7644d"
}
検証済みプロバイダー
ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-20240423
ami-01bef798938b7644d
Canonical, Ubuntu, 24.04 LTS, amd64 noble image build on 2024-04-23
OwnerAlias: amazon
プラットフォーム: –
アーキテクチャ: x86_64
所有者: 099720109477
発行日: 2024-04-25
ルートデバイスタイプ: ebs
仮想化: hvm
ENA 有効: はい
ブートモード: uefi-preferred
全体コード
###############################
# IAMロール:EC2がSSMに接続するためのロールを作成
###############################
resource "aws_iam_role" "ssm_role" {
name = "ec2_ssm_role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Action = "sts:AssumeRole",
Effect = "Allow",
Principal = {
Service = "ec2.amazonaws.com"
}
}]
})
}
###############################
# IAMロールポリシーアタッチメント:SSM用のマネージドポリシーをアタッチ
###############################
resource "aws_iam_role_policy_attachment" "ssm_managed" {
role = aws_iam_role.ssm_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
###############################
# IAMインスタンスプロファイル:EC2にIAMロールを紐付けるためのプロファイルを作成
###############################
resource "aws_iam_instance_profile" "ssm_instance_profile" {
name = "ec2_ssm_instance_profile"
role = aws_iam_role.ssm_role.name
}
###############################
# セキュリティグループ:SSM通信(アウトバウンドHTTPS通信)を許可する設定
###############################
resource "aws_security_group" "ec2_sg" {
name = "ec2_ssm_sg"
description = "Allow outbound traffic for SSM communication"
vpc_id = var.vpc_id
# 全てのアウトバウンドトラフィックを許可
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
}
###############################
# EC2インスタンス作成:UbuntuのEC2インスタンスを5台作成
###############################
resource "aws_instance" "ubuntu_ec2" {
count = 5
ami = var.old_ami_id
instance_type = "t3.micro" # 必要に応じて変更してください
subnet_id = var.private_subnet_ids[count.index % length(var.private_subnet_ids)]
iam_instance_profile = aws_iam_instance_profile.ssm_instance_profile.name
# セキュリティグループを紐付け
vpc_security_group_ids = [aws_security_group.ec2_sg.id]
tags = {
Name = "UbuntuEC2-${count.index + 1}"
OS = "Ubuntu 24.04 LTS"
}
}
所感
- 多分これがPatch Managerの本来の使い方ではないと思うけど、結構簡単にできた。ベースラインのパッチでも長期間動かすインスタンスに対してはやっておくのがいいのではないかと思われる。
Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内
技術書コーナー
北海道の駅巡りコーナー