はじめに
こんにちは。satyamです。
EC2 インスタンスは、常に想定どおりの状態を維持できるわけではありません。サービスが停止したり、パッケージが削除されたり、わずかな設定ドリフトによってベースラインが崩れてしまうことがあります。
こうした状況になると、監視の信頼性が低下し、復旧作業が手動対応になってしまうケースも少なくありません。
本記事では、AWS Systems Manager の State Manager を利用し、EC2 に対してシンプルな「チェックして修復する」仕組みを継続的に適用します。 例として、CloudWatch Agent を常に稼働させ、EventBridge → SNS(メール)による異常通知の構成を紹介します。
目次
構成図
以下の図は、本記事で構築する構成を示しています。

【動作フロー】
- State Manager が対象の EC2 に対して関連付けのコマンドを実行します。
- EC2 は実行結果(Success / Failed)を State Manager に返します。
- 実行結果が Failed の場合、EventBridge が検知します。
- EventBridge から SNS を通じてメール通知が送信されます。
【前提条件】
- 対象の EC2 インスタンスが SSM Managed Instance として登録されていること
- EC2 インスタンスの IAM ロールに AmazonSSMManagedInstanceCore が含まれていること
- EC2 インスタンスの IAM ロールに CloudWatch Agent がメトリクスを送信するための権限が付与されていること
ワークフロー
- タグによる適用範囲の制御
- State Manager によるベースライン適用
- 通知設定(SNS + EventBridge)
- Step 1: SNS トピックを作成する
- Step 2: トピックにメールサブスクリプションを追加する
- Step 3: EventBridge ルールを作成する
- 動作確認
- Test 1: サービス停止(復旧確認)
- Test 2: サービス無効化(再有効化確認)
- Test 3: エージェントパッケージ削除(再インストール確認)
- Test 4: 失敗時の通知確認(EventBridge → SNS)
タグによる適用範囲の制御
AWS マネジメントコンソールから EC2 を選択します。
インスタンスを開き、対象のインスタンスを選択します。
次に、「タグ」タブを開き、
以下のタグを追加します。
- Key: Baseline
- Value: Enforced

State Manager によるベースライン適用
コンソール画面から Systems Manager を選択します。
ステートマネージャー → [関連付けの作成] を選択します。
名前:任意
ドキュメント:AWS-RunShellScript

※ 注意点
CloudWatch Agent を起動し継続的に動作させるためには、有効な JSON 形式の設定が必要です。本記事では、ルートファイルシステム(/)のディスク使用率を収集する 最小構成の設定を使用します。
パラメータ:
Commandsに、以下のスクリプトを貼り付けます。
set -euo pipefail
# CloudWatch Agent が未インストールの場合はインストールする
if ! rpm -q amazon-cloudwatch-agent >/dev/null 2>&1; then
yum install -y amazon-cloudwatch-agent
fi
# 設定ファイル(JSON)が存在しない場合のみ作成する(再インストール後も自動復旧できるようにする)
CFG=/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
if [ ! -f "$CFG" ]; then
mkdir -p /opt/aws/amazon-cloudwatch-agent/etc
cat > "$CFG" <<'JSON'
{
"agent": {
"metrics_collection_interval": 60,
"region": "ap-northeast-1"
},
"metrics": {
"namespace": "test-metric",
"append_dimensions": {
"InstanceId": "${aws:InstanceId}"
},
"metrics_collected": {
"disk": {
"resources": ["/"],
"measurement": ["used_percent"],
"metrics_collection_interval": 60
}
}
}
}
JSON
fi
# 起動時に自動起動するよう有効化し、設定ファイルを適用してエージェントを起動する
systemctl enable amazon-cloudwatch-agent
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config -m ec2 -c file:$CFG -s
# エージェントが稼働中であることを確認する(稼働していなければ失敗扱い)
systemctl is-active --quiet amazon-cloudwatch-agent
echo "[OK] amazon-cloudwatch-agent is running."

※ ヒント
Commands セクション内の JSON 設定を編集することで、必要なメトリクスやログを収集するように調整できます。
この設定は、タグベースの State Manager 関連付けを通じて適用されるため、各サーバーを個別に修正することなく、一元的に管理・更新できます。
ターゲットの選択 では、インスタンスタグを指定 を選択します。
以下のタグを設定します。
- タグキー:Baseline
- タグの値:Enforced

スケジュールを指定
CRON/Rate 式 を選択します。
例:cron(0 00 18 ? * * *)
※ 毎日 18:00 に実行

必要に応じてスケジュールを調整します。
※ 注意点
関連付けを作成すると、作成後まもなく一度自動的に実行されます。その後は、設定したスケジュールに従って継続的に自動実行されます。
そのほかの設定はデフォルトのままとし、[関連付けの作成]を選択します。
通知設定(SNS + EventBridge)
Step 1: Amazon SNS トピックを作成する
コンソール画面から Amazon SNS を選択します。
トピック → [トピックの作成] を選択する。
タイプ:スタンダード
名前:任意

そのほかの設定はデフォルトのままとし、[トピックの作成]を選択します。
Step 2: トピックにメールサブスクリプションを追加する
Step 1 で作成したトピックを開き、 [サブスクリプションの作成]を選択します。
プロトコル:E メール
エンドポイント:通知を受信するメールアドレス

設定後、[サブスクリプションの作成]を選択します。
エンドポイントに指定したメールアドレス宛に、確認メールが送信されます。
メール内の 「Confirm subscription」 を選択します。

サブスクリプションの ステータス が [確認済み] になっていることを確認します。

Step 3: EventBridge ルールを作成する
コンソール画面から Amazon EventBridge を選択します。
ルール → ルールを作成 を選択します。
構築タブの トリガーイベント で AWS サービスイベント を選択します。
検索ボックスで Systems Manager を検索し、
「EC2 State Manager Association State Change」をイベントとして追加します。

次に イベントパターン(フィルター) を編集し、
対象の関連付けが Failed の場合のみ、ルールが実行されるように設定します。
{
"source": ["aws.ssm"],
"detail-type": ["EC2 State Manager Association State Change"],
"detail": {
"association-id": ["<your-association-id>"],
"status": ["Failed"]
}
}

[ターゲット] タブに切り替えます。
検索ボックスで SNS を検索し、
「SNS トピック」をターゲットとして追加します。

ターゲットは次のように設定します。
ターゲットの場所:このアカウントのターゲット
トピック:Step 1 で作成した SNS トピック

そのほかの設定はデフォルトのままとします。
その後、[構築] → [設定] タブへ移動します。
ルール名:任意

残りの設定はデフォルトのままとし、[作成] を選択します。
動作確認
Test 1: サービス停止(復旧確認)
インスタンス上で CloudWatch Agent を停止します。
systemctl stop amazon-cloudwatch-agent
確認コマンド:
systemctl is-active amazon-cloudwatch-agent
結果: inactive

コンソール画面から Systems Manager を選択します。
ステートマネージャー → 関連付け を選択します。
作成した関連付けを開き、[Apply association now] を選択します。
その後、[実行履歴] で結果を確認します。

実行完了後、インスタンス上で再度確認します。
systemctl is-active amazon-cloudwatch-agent
結果: active

Test 2: サービス無効化(再有効化確認)
インスタンス上で CloudWatch Agent を無効化します。
systemctl disable amazon-cloudwatch-agent
確認コマンド:
systemctl is-enabled amazon-cloudwatch-agent
結果: disabled

Test 1 と同様に[Apply association now]を実行し、
[実行履歴] で実行結果を確認します。

実行完了後、インスタンス上で確認します。
systemctl is-enabled amazon-cloudwatch-agent
結果: enabled

Test 3: エージェントパッケージ削除(再インストール確認)
インスタンス上で CloudWatch Agent をアンインストールします。
yum remove -y amazon-cloudwatch-agent

確認コマンド:
rpm -q amazon-cloudwatch-agent
結果: package amazon-cloudwatch-agent is not installed

Test 1 と同様に[Apply association now]を実行し、
[実行履歴] で実行結果を確認します。

実行完了後、インスタンス上で確認します。
rpm -q amazon-cloudwatch-agent
結果: amazon-cloudwatch-agent-*.x86_64
systemctl is-active amazon-cloudwatch-agent
結果: active

メトリクスが送信されていることを確認します。
AWS マネジメントコンソールから CloudWatch を選択ます。
メトリクス → すべてのメトリクス → test-metric を開きます。

Test 4: 失敗時の通知確認(EventBridge → SNS)
通知動作を確認するため、関連付けを意図的に一度失敗させます。
コンソール画面から Systems Manager を選択します。
ステートマネージャー → 作成した関連付けを選択します。
Edit を選択します。
Commands の最後に以下の行を追加します。
exit 1

[変更内容を保存] を選択します。
関連付けを保存すると、更新したコマンドで関連付けが一度自動的に実行されます。
[実行履歴] で実行結果を確認します。
結果: Failed

失敗通知のメールが送信されることを確認します。
結果:
status: Failed

確認後、再度関連付けを Edit し、Commands から exit 1 を削除します。
まとめ
本記事では、AWS Systems Manager の State Manager を利用し、EC2 の設定ドリフトを自動的に管理する方法を紹介しました。 定期的な「チェックして修復する」処理を設定することで、サービス停止・パッケージ削除・エージェント無効化といった一般的な問題からインスタンスを自動的に復旧できます。
また、EventBridge → SNS(メール) を連携することで、自動復旧できなかった場合でも失敗をすぐに検知し、通知できるようになります。
この仕組みをベースラインとして導入することで、他のパッケージやサービスにも拡張しやすく、日常運用をシンプルかつ安定したものにできます。
おまけ
Rate control
多くのターゲットに対して関連付けを実行する際の実行方法を制御できます。同時実行性
同時にタスクを実行するターゲットの数または割合 (%) を指定エラーのしきい値
指定した数または割合 (%) のターゲットでタスクが失敗した後、タスクを停止
S3 への書き込み
実行ログを S3 に保存し、トラブルシュートや監査のために確認できます。CloudWatch alarm - オプション
関連付けが失敗した場合に、CloudWatch アラームを利用した通知を設定できます。