Ansibleで設定ドリフトを自動検出する設計|定期checkモードとSlack通知で構成ずれを継続監視する方法

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Ansible > Ansibleで設定ドリフトを自動検出する設計|定期checkモードとSlack通知で構成ずれを継続監視する方法
「Ansibleで管理しているはずなのに、いつの間にかサーバーの設定が変わっている。」
サーバー台数が増えると、誰かが直接ログインして施した一時的な修正、パッケージの自動アップデート、クラウドエージェントによる設定書き換え——「PlaybookにないN変更」が静かに積み重なります。

問題が表面化するのは大抵インシデントの最中です。手元のPlaybookを見ても、実態との分岐点が分からない。

この記事では、Ansibleの--checkモードを使った設定ドリフト自動検出の設計を解説します。cron定期実行とSlack通知を組み合わせれば、複数サーバーの構成ずれを継続監視できます。Rocky Linux 9 / RHEL 9 / Ubuntu 22.04 LTS で動作確認済みです。

この記事のポイント

・--checkと--diffの組み合わせで、実変更なしにドリフトを可視化できる
・exitコード2(changedあり)をシェルで評価してSlack通知できる
・「自動修正するか・しないか」の判断軸と運用ルール設計が実運用の鍵
・AWXのScheduleジョブで複数環境の監視を一元管理できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

設定ドリフトとは何か——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

web-prod-02 の Timeout が `120` に書き換えられており(Playbookの宣言は `60`)、web-prod-03 の firewalldポリシーが変わっていることが分かります。これが設定ドリフトの実態です。

ドリフト検出をスケジュール化する設計

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コードの意味を押さえることが重要です。`ansible-playbook` は以下のコードを返します。

・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

このスクリプトをcronから呼び出します。ログは日付ごとにファイル分割するので、後追い調査も容易です。

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

本番環境に多くのPlaybookを持つ場合、全タスクをcheckすると実行時間が長くなります。重要度の高いタグから段階的に監視範囲を広げていくのが現実的な設計です。

よくあるトラブルと対処法

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)で検出範囲を段階的に拡張
設定ドリフトの管理は「インシデント後に気づく」から「継続的に把握する」への転換です。check+diff → 通知 → 判断 → 修正の一連のフローを設計することで、Ansibleによる構成管理の信頼性が大幅に向上します。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、AnsibleによるIaC自動化・構成管理設計を含むLinuxサーバー運用スキルをハンズオンで習得できる実践講座を開催しています。詳細はこちらからご確認ください。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。