Ansibleは冪等性を持つ強力なツールですが、Playbook内容のミスや環境差異が積み重なると、本番環境で思わぬ変更が走ることがあります。これを防ぐ第一の手段が
--check(ドライランモード)と --diff の組み合わせです。この記事では、
ansible-playbook --check --diff を使って本番適用前に変更内容を正確に把握する方法を、実際の出力例を交えて解説します。checkモードの仕組みから始まり、diff出力の読み方、check非対応モジュールの回避策、現場で使える安全運用フローまでを網羅します。この記事のポイント
・ansible-playbook --check --diffで本番変更内容を事前に確認できる
・diffの「---」が変更前、「+++」が変更後の内容を示す
・commandとshellモジュールはcheckモードでスキップされる点に注意
・本番適用前は「check→出力確認→apply」の3ステップが基本形
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜcheckモードとdiffが本番運用で必要なのか
Ansibleには「冪等性」という性質があります。同じPlaybookを何度実行しても、結果が同一になるように設計されている、という意味です。しかし、次のようなケースでは冪等性だけでは安心できません。
・初めて適用するサーバー(環境変数や既存設定の差異が未知)
・しばらく触っていなかったサーバー(手動変更が混在している可能性)
・既存の設定ファイルをテンプレートで上書きするタスク
・パッケージのバージョンを特定バージョンに固定するタスク
このような状況で「とりあえず流してみる」は危険です。本番サービスへの影響を最小化するために、checkモードとdiffを活用して「実際には何が変わるのか」を事前に可視化することが、Ansibleの安全運用の基本です。
セミナーで3,100名以上を指導してきた中で、「--checkを使っていれば防げた本番障害」のケースを何度も見てきました。5分のドライランが深夜の復旧作業を防ぎます。
--checkと--diffの基本的な使い方
1. --checkモードでドライランを実行する
--check オプションを付けると、Playbookのタスクを実際には実行せずに「実行した場合にどうなるか」をシミュレーションします。# ドライランモードで実行する(実際の変更は加えない) ansible-playbook site.yml -i inventory/production --check
ok(変更なし)か changed(変更が発生する予定)として報告されます。実際のコマンドは走りません。注意点として、
--check モードでも TASK [Gathering Facts] は実際にリモートホストへSSH接続してFact情報を収集します。接続が必要な点は本番実行と変わりません。2. --diffモードで変更内容を可視化する
--diff オプションを付けると、ファイルやテンプレートが変更される場合にunified diff形式で差分を表示します。# 差分を表示しながら実行する(実際に変更が適用される) ansible-playbook site.yml -i inventory/production --diff
--diff を単体で使うと実際にファイルを変更しながら差分も表示します。「適用前に確認」するためには次のステップで紹介する --check --diff の組み合わせが正解です。3. --check --diffを組み合わせた実行例
実務では2つのオプションを組み合わせて使うのが基本形です。# ドライラン + 差分表示(本番適用前の確認に使う) ansible-playbook site.yml -i inventory/production --check --diff
keepalive_timeout 値が変更される場合の出力を示しています。PLAY [webservers] ************************************************************ TASK [Gathering Facts] ******************************************************* ok: [web01.example.internal] ok: [web02.example.internal] TASK [nginx : ensure nginx package is installed] ***************************** ok: [web01.example.internal] ok: [web02.example.internal] TASK [nginx : deploy /etc/nginx/nginx.conf] ********************************** --- before: /etc/nginx/nginx.conf +++ after: /root/.ansible/tmp/ansible-tmp-1719820045.23-98723-45612/source @@ -10,7 +10,7 @@ sendfile on; - keepalive_timeout 65; + keepalive_timeout 75; server_tokens off; changed: [web01.example.internal] ok: [web02.example.internal] TASK [nginx : ensure nginx is running and enabled] *************************** ok: [web01.example.internal] ok: [web02.example.internal] PLAY RECAP ******************************************************************* web01.example.internal : ok=4 changed=1 unreachable=0 failed=0 web02.example.internal : ok=4 changed=0 unreachable=0 failed=0
・
--- が「変更前」の内容(現在のサーバーの設定)・
+++ が「変更後」の内容(Playbookが適用しようとしている設定)・
- で始まる行が削除される内容、+ で始まる行が追加される内容・
web01 のみ changed=1 となっており、web02はすでに最新状態このように「どのホストの、どのファイルの、どの行が、どう変わるのか」が一目でわかります。本番適用前にこの出力をチームでレビューするのが安全運用の基本です。
Ansibleの基礎からしっかり学びたい方へ
checkモードを正しく使いこなすには、Playbook設計・モジュールの挙動・インベントリ管理の理解が前提になります。
現役エンジニアによるハンズオン形式のセミナーで、実務で通用する構成管理スキルを体系的に身につけませんか。
>> Ansible実践セミナーの詳細はこちら
実務で使えるcheck運用パターン
1. 本番適用前の標準フロー(check→レビュー→apply)
現場での標準的な運用フローは次の3ステップです。・ステップ1:
--check --diff でドライラン実行 → 出力をログファイルに保存する・ステップ2:チームまたは担当者でdiff内容を確認・承認する
・ステップ3:問題なければ
--check を外して本番実行するステップ1の出力保存には
tee コマンドが便利です。# ドライラン結果をファイルに保存しながら画面にも表示する ansible-playbook site.yml -i inventory/production --check --diff | tee /tmp/ansible-check-$(date +%Y%m%d-%H%M%S).log
2. always_runでcheckモードでも確実に実行させる
checkモードはすべてのタスクをスキップして「シミュレーション」するわけではありません。一部のタスクはcheckモード中でも実際に実行させたい場合があります。その場合はcheck_mode: false(旧称 always_run: yes)を使います。# tasks/main.yml の例 # このタスクはcheckモードでも必ず実行する(例: 事前確認コマンド) - name: check disk free space command: df -h /var check_mode: false register: df_result changed_when: false # このタスクはcheckモードの通常の挙動に従う(シミュレーションのみ) - name: deploy application config template: src: app.conf.j2 dest: /etc/myapp/app.conf notify: restart myapp
changed_when: false を組み合わせることで、「実行はするが changed 扱いにしない」という制御が可能です。ディスク残量確認や事前ヘルスチェックコマンドに適しています。3. ansible_check_mode変数でPlaybook内の挙動を制御する
checkモードで実行中かどうかは、Playbook内でansible_check_mode 変数で判定できます。# checkモードかどうかによって処理を切り替える例 - name: show notice when running in check mode debug: msg: "ドライランモードで実行中です。実際の変更は行われません。" when: ansible_check_mode - name: run database migration (skip in check mode) command: /opt/myapp/bin/migrate --run when: not ansible_check_mode
checkモードで発生しやすいエラーと対処法
1. commandとshellモジュールはcheckモードでスキップされる
command モジュールと shell モジュールはcheckモード中に自動でスキップされます(changed=0 として扱われます)。このため、これらのモジュールの出力を後続のタスクで使う場合、checkモードで連鎖エラーが発生することがあります。# NG例: checkモードでは command がスキップされるため # result.stdout が存在せず後続タスクがエラーになる - name: get current config version command: /opt/myapp/bin/version --current register: result - name: apply config if version is old template: src: config.j2 dest: /etc/myapp/config when: result.stdout != "v2.0"
check_mode: false で command タスクを強制実行することです。# OK例: check_mode: false で強制実行して register を確実に取得する - name: get current config version command: /opt/myapp/bin/version --current register: result check_mode: false changed_when: false
2. ディレクトリ依存による連鎖エラー
次のようなケースでもcheckモードでエラーが発生することがあります。・ディレクトリを作成するタスク(
file モジュール)がcheckモードでスキップされた・後続のタスクがそのディレクトリの存在を前提にしている
このような依存関係がある場合、checkモードで
failed=1 が出ても「本番適用時には問題ない」ことがあります。checkモードの出力は参考情報として使い、個々のエラー内容を精査することが重要です。ディレクトリ作成タスクに
check_mode: false を設定する対処法もありますが、「checkモードで失敗しているタスクが本当に問題なのか、依存関係の連鎖なのか」を判断できるようになることが最も大切です。# ディレクトリ作成タスクをcheckモードでも実行する例 - name: ensure config directory exists file: path: /etc/myapp/conf.d state: directory mode: "0755" check_mode: false
3. checkモードと--tags・--limit の組み合わせ
checkモードは--tags や --limit と組み合わせることで、確認範囲を絞り込めます。# 特定のロールのみドライラン確認する ansible-playbook site.yml -i inventory/production --check --diff --tags nginx # 特定のホストのみドライラン確認する ansible-playbook site.yml -i inventory/production --check --diff --limit web01.example.internal
--tags で絞ってcheckすることで、出力量を減らして確認しやすくなります。本記事のまとめ
| やりたいこと | コマンド・設定 |
|---|---|
| ドライランで変更箇所を確認 | ansible-playbook site.yml --check |
| ドライラン + 差分表示(推奨) | ansible-playbook site.yml --check --diff |
| ドライラン結果をログに保存 | ansible-playbook site.yml --check --diff | tee check.log |
| 特定タグのみcheckする | ansible-playbook site.yml --check --diff --tags nginx |
| 特定ホストのみcheckする | ansible-playbook site.yml --check --diff --limit web01 |
| checkモードでも強制実行 | タスクに check_mode: false を設定 |
| checkモード中かどうか判定 | when: ansible_check_mode または when: not ansible_check_mode |
| commandをcheckでもスキップさせない | check_mode: false + changed_when: false |
--check --diff を使った事前確認の習慣は、本番障害を未然に防ぐ最もシンプルかつ効果的な手段です。特に複数ホストに同時適用するPlaybookや、長期間更新していなかったサーバーへの適用では、必ずこの手順を踏むようにしましょう。checkモードの限界(commandのスキップや依存関係の連鎖)を理解した上で適切に使いこなすことが、Ansibleを信頼できる運用ツールにする第一歩です。
Ansible実践ハンズオンの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 前のページへ:Ansibleの実行を高速化する方法|ansible.cfgのpipelining・forks・fact cachingチューニング
- この記事の属するカテゴリ:Ansibleへ戻る

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