Ansibleのcheckモードとdiffでドライラン検証する方法|本番適用前に変更内容を確認する運用設計

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Ansible > Ansibleのcheckモードとdiffでドライラン検証する方法|本番適用前に変更内容を確認する運用設計
「Playbookを本番に流したら予想外のファイルが書き換わった」「サービスが再起動してダウンタイムが発生した」——

Ansibleは冪等性を持つ強力なツールですが、Playbook内容のミスや環境差異が積み重なると、本番環境で思わぬ変更が走ることがあります。これを防ぐ第一の手段が --check(ドライランモード)と --diff の組み合わせです。

この記事では、ansible-playbook --check --diff を使って本番適用前に変更内容を正確に把握する方法を、実際の出力例を交えて解説します。checkモードの仕組みから始まり、diff出力の読み方、check非対応モジュールの回避策、現場で使える安全運用フローまでを網羅します。

この記事のポイント

・ansible-playbook --check --diffで本番変更内容を事前に確認できる
・diffの「---」が変更前、「+++」が変更後の内容を示す
・commandとshellモジュールはcheckモードでスキップされる点に注意
・本番適用前は「check→出力確認→apply」の3ステップが基本形


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も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

以下は実際の出力例(ホスト名はマスク済み)です。Nginx設定ファイルの 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

保存したログをGitリポジトリにコミットしておくと、「いつ、どんな変更を確認してから適用したか」の記録になります。セキュリティ監査や障害調査での証跡としても機能します。

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モードで誤って実行すると問題が起きる処理を安全にスキップするパターンとして使えます。

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: falsecommand タスクを強制実行することです。

# 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

大規模なPlaybookでは、変更対象のコンポーネントだけを --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
Ansibleの --check --diff を使った事前確認の習慣は、本番障害を未然に防ぐ最もシンプルかつ効果的な手段です。特に複数ホストに同時適用するPlaybookや、長期間更新していなかったサーバーへの適用では、必ずこの手順を踏むようにしましょう。

checkモードの限界(commandのスキップや依存関係の連鎖)を理解した上で適切に使いこなすことが、Ansibleを信頼できる運用ツールにする第一歩です。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

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

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

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

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

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

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

登録10秒/合わなければ解除3秒 / 詳細はこちら

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

この記事を書いた人

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

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

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