サーバー台数が増えると、誰かが直接ログインして施した一時的な修正、パッケージの自動アップデート、クラウドエージェントによる設定書き換え——「PlaybookにないN変更」が静かに積み重なります。
問題が表面化するのは大抵インシデントの最中です。手元のPlaybookを見ても、実態との分岐点が分からない。
この記事では、Ansibleの--checkモードを使った設定ドリフト自動検出の設計を解説します。cron定期実行とSlack通知を組み合わせれば、複数サーバーの構成ずれを継続監視できます。Rocky Linux 9 / RHEL 9 / Ubuntu 22.04 LTS で動作確認済みです。
この記事のポイント
・--checkと--diffの組み合わせで、実変更なしにドリフトを可視化できる
・exitコード2(changedあり)をシェルで評価してSlack通知できる
・「自動修正するか・しないか」の判断軸と運用ルール設計が実運用の鍵
・AWXのScheduleジョブで複数環境の監視を一元管理できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
設定ドリフトとは何か——Playbookで管理できない「隙間」
設定ドリフト(configuration drift)とは、管理対象サーバーの実際の状態が、Playbookで宣言した「あるべき姿」と乖離していくことです。IaC(Infrastructure as Code)を導入していても、ドリフトはほぼ確実に発生します。1. ドリフトが積み上がる典型的な4パターン
現場でよく見られるドリフトの発生源を整理します。・応急処置のSSH直接ログイン:「とりあえず直した」設定がPlaybookに反映されないまま残る
・パッケージ自動アップデート:dnf-automatic や unattended-upgrades がPlaybookの想定バージョンを書き換える
・クラウド・監視エージェント:CloudWatch Agentや各種SaaSのエージェントが設定ファイルを上書きする
・OS標準機能の自動動作:SELinuxのポリシー更新、systemdのUnitファイル再生成など
Ansibleの冪等性は「Playbookを実行すれば宣言した状態に戻せる」ことを保証しますが、それは「定期的に実行して状態を監視する」設計があってこそ機能します。
2. ドリフト検出と修正の2フェーズを分離する
重要な設計原則は、検出(detect)と修正(remediate)を別フェーズに分けることです。自動検出を先に走らせてSlack通知を送り、修正をPlaybook担当者が判断する——このフローが現場では最も安全に機能します。小さな変更まで自動修正すると、意図的な臨時変更(メンテナンス作業中など)まで巻き戻してしまうリスクがあるためです。
--checkと--diffを組み合わせたドリフト可視化の仕組み
Ansibleの `--check` オプション(ドライランモード)は、タスクを実際に実行せず「もし実行したらどうなるか」をシミュレートします。`--diff` を加えると、ファイルの具体的な変更内容をdiff形式で確認できます。1. --checkの動作原理
`ansible-playbook --check` を実行すると、各タスクの判定結果が以下のいずれかで返ります。・ok:現在の状態がPlaybookの宣言と一致している(変更なし)
・changed:Playbookを実行したら変更が生じる(ドリフトあり)
・skipped:when条件でスキップされた
・failed:タスク自体の実行に失敗(check不能なタスク等)
changed が返ったタスクがドリフトの箇所です。
2. --diffで変更内容を細かく確認する
`--diff` を組み合わせると、templateモジュールやcopyモジュールで管理しているファイルの変更内容をdiff形式で表示できます。設定ファイル(/etc/httpd/conf/httpd.conf など)がどの行で変わっているかが一目で把握できます。このときPlaybookでは `gather_facts` が有効なので、ファイルシステムの現在の状態をそのまま取得して差分を計算します。3. Rocky Linux 9での実機出力例
以下は Rocky Linux 9.4 の Webサーバー3台に対して check+diff を実行したときの出力例です(サーバー名はマスク済み)。$ ansible-playbook --check --diff -i inventory/production site.yml PLAY [webservers] ***************************************************** TASK [httpd : ensure httpd.conf is deployed] ************************** --- before: /etc/httpd/conf/httpd.conf +++ after: /tmp/ansible.diff/httpd.conf @@ -82,7 +82,7 @@ -Timeout 120 +Timeout 60 KeepAlive On ok: [web-prod-01.example.internal] changed: [web-prod-02.example.internal] ok: [web-prod-03.example.internal] TASK [firewalld : allow https port] *********************************** ok: [web-prod-01.example.internal] ok: [web-prod-02.example.internal] changed: [web-prod-03.example.internal] PLAY RECAP ************************************************************ web-prod-01.example.internal : ok=12 changed=0 web-prod-02.example.internal : ok=11 changed=1 web-prod-03.example.internal : ok=11 changed=1
ドリフト検出をスケジュール化する設計
check+diffを手動で実行するだけでは意味がありません。定期的に自動実行して結果を記録・通知する仕組みが必要です。1. cronで定期checkを自動実行する
コントロールノードにcronを設定して、毎朝checkモードを実行する構成です。# /etc/cron.d/ansible-drift-check # 平日毎朝8:00にドリフト検出を実行 0 8 * * 1-5 ansible /opt/ansible/scripts/drift-check.sh
・exit 0:全ホストで changed=0(ドリフトなし)
・exit 2:1台以上でchangedあり(ドリフト検出)
・exit 4:unreachableなホストあり(接続失敗)
exit 2 のときだけ通知する設計が基本形です。
2. AWXのスケジュールジョブで複数環境を管理する
AnsibleをAWX(Ansible Automation Platformのオープンソース版)で運用している場合、Job Templateにスケジュールを設定するだけでドリフト監視が組み込めます。コントロールノードのcron管理が不要になり、本番・ステージングなど複数環境のドリフト検出ジョブを一元的に可視化できます。Ansibleの体系的な構成管理設計を学びたい場合は、Ansible実践コースでハンズオンを通じて習得できます。
検出時にSlackへ通知する設計
ドリフトを検出しても誰も気づかなければ意味がありません。実運用での通知設計パターンを2つ紹介します。1. shellラッパーでexitコード判定してSlack通知する
最もシンプルな設計は、シェルスクリプトで ansible-playbook のexitコードを評価して curl でSlack通知する方法です。#!/bin/bash # /opt/ansible/scripts/drift-check.sh LOG=/var/log/ansible/drift-$(date +%Y%m%d-%H%M).log SLACK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" ansible-playbook --check --diff -i /opt/ansible/inventory/production /opt/ansible/site.yml > "$LOG" 2>&1 EXIT=$? if [ $EXIT -eq 2 ]; then # changed検出時のみSlack通知 SUMMARY=$(grep -E 'changed=[^0]' "$LOG" | head -5) curl -s -X POST "$SLACK_URL" -H 'Content-type: application/json' --data "{"text":"⚠️ Ansible drift detected ($(date +%Y-%m-%d)): ${SUMMARY}"}" elif [ $EXIT -ne 0 ]; then # 接続失敗など異常時も通知 curl -s -X POST "$SLACK_URL" -H 'Content-type: application/json' --data "{"text":"[ERROR] Ansible check failed (exit ${EXIT}). Log: ${LOG}"}" fi
2. PlaybookのSlackモジュールで通知を組み込む方法
`community.general.slack` モジュールを使って、Playbook内にSlack通知タスクを含める方法もあります。ただし、`--check` 実行中は `changed_when` の制御が効かないケースがあるため、shellラッパーによるexitコード判定の方が確実です。複雑な条件評価より「exit 2 → 通知」のシンプルな設計を推奨します。ドリフト修正の判断軸と運用ルール設計
ドリフトを検出した後のプロセス設計こそが、実運用の品質を左右します。1. 自動修正か手動確認かの判断軸
「ドリフト検出したら即Playbookで修正」は一見合理的ですが、現場では危険です。・自動修正のリスク:メンテナンス作業中の一時変更を意図せず巻き戻す。緊急対応で施した設定が消える
・推奨設計:検出 → 通知 → 担当者が判断 → 次のデプロイで適用 or 手動修正
ただし、セキュリティ関連の設定(SSH設定・firewalld・sudoers)は許容範囲外のドリフトとして定義し、速やかな修正をルール化することを推奨します。
2. 「意図的な変更」をPlaybookへ取り込むフロー
ドリフトには「本来Playbookに反映すべき正当な変更」が混在することがあります。このフローが現場で機能します。・Step1: check+diffでドリフトの内容を確認する
・Step2: 変更が「意図的(正当)」なら → Playbookを更新してcommit・PR
・Step3: 変更が「意図せず(不正)」なら → Playbookを適用して元に戻す
・Step4: 変更が「緊急対応中」なら → タグで対象外にして次回以降のcheckをスキップする
この判断フローをRunbook(運用手順書)として整備しておくことで、担当者が変わっても同じ基準で対応できます。
3. タグで検出対象を絞る設計
Ansibleのタグ機能を使えば、「セキュリティ設定のみをドリフト検出する」のような範囲指定が可能です。# セキュリティ設定のみを対象にcheckを実行 ansible-playbook --check --diff --tags "security,firewalld" -i /opt/ansible/inventory/production /opt/ansible/site.yml
よくあるトラブルと対処法
commandモジュールが常にchangedを返す問題
commandモジュールやshellモジュールは、check実行時も常に「changed」を返します。ドリフト検出の精度を上げるには、冪等なモジュール(file・copy・template・serviceなど)に置き換えるか、`changed_when: false` を適切に設定することが先決です。--checkで失敗するタスクの扱い
前のタスクで生成したファイルやリソースが存在しないと、--checkで「failed」になるタスクがあります。`ignore_errors: "{{ ansible_check_mode }}"` を設定すると、check実行時だけエラーを無視できます。本番適用時は正常に動作します。接続失敗とドリフト検出を混同しない
exitコード 4(unreachable)はドリフト検出ではなく接続失敗です。Slack通知のメッセージでexitコードを区別することで、「サーバーに繋がらない」と「設定がズレている」を別のアラートとして運用できます。まとめ
Ansibleで設定ドリフトを継続監視するための設計要素を整理します。| 設計要素 | 推奨アプローチ |
|---|---|
| ドリフト検出 | ansible-playbook --check --diff |
| 定期実行 | cron(シンプル)またはAWX Scheduleジョブ(複数環境) |
| 通知トリガー | exitコード 2(changedあり)をシェルで評価 |
| 通知先 | Slack webhook(curlまたはcommunity.general.slackモジュール) |
| 修正判断 | 自動修正せず担当者が判断してから適用 |
| 精度向上 | commandモジュールをchanged_when制御または冪等モジュールへ置き換え |
| 対象絞り込み | タグ(--tags)で検出範囲を段階的に拡張 |
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:AnsibleでPythonカスタムモジュールを開発する方法|べき等性を持つ独自操作をroleに組み込む設計入門
- この記事の属するカテゴリ:Ansibleへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます