SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-21

Ansible check mode और --diff का उपयोग कैसे करें

Ansible check mode और --diff का उपयोग करके बदलावों की जांच कैसे करें। जानें कि कौन से modules check mode का समर्थन नहीं करते और dry run के दौरान गलत परिणाम क्यों मिल सकते हैं।

Ansible check mode क्या करता है

Ansible check mode एक dry run है: ansible-playbook --check play में मौजूद प्रत्येक host से जुड़ता है, हर module से पूछता है कि क्या वर्तमान स्थिति आपके द्वारा मांगी गई स्थिति से मेल खाती है, और बिना कुछ लिखे यह रिपोर्ट करता है कि क्या बदलाव किए जाएंगे। --diff जोड़ने पर यह उन फाइलों की पहले और बाद की सामग्री भी प्रिंट करता है जिन्हें यह प्रभावित करेगा। ये दोनों मिलकर उस सवाल का जवाब देते हैं जिसे हर वास्तविक run से पहले पूछना चाहिए: इन servers पर क्या बदलने वाला है?

Check mode आपके playbook का simulation नहीं है। सर्वर का कोई model कहीं मौजूद नहीं होता। हर module से केवल लिखने के बजाय देखने के लिए कहा जाता है। जो module read-only जवाब दे सकता है, वह changed रिपोर्ट करता है और आगे बढ़ जाता है। जो module जवाब नहीं दे सकता, वह कुछ नहीं करता और कुछ भी रिपोर्ट नहीं करता। Ansible documentation इसे एक पंक्ति में स्पष्ट करता है: "जो modules check mode का समर्थन नहीं करते, वे कुछ भी रिपोर्ट नहीं करते और कुछ भी नहीं करते।" यही वह अंतर है जहाँ dry run आपको गलत जवाब दे सकता है, इसलिए इस guide का अधिकांश हिस्सा इसी अंतर के बारे में है।

Dry run चलाएं: --check और --diff

ansible-playbook -i inventory.ini site.yml --check --diff --limit web1

-C और -D इन दो flags के संक्षिप्त रूप हैं। --limit का उपयोग जानबूझकर किया गया है। एक host का diff ऐसा होता है जिसे आप पढ़ सकते हैं। बीस hosts का diff ऐसा होता है जिसे आप केवल scroll करके छोड़ देते हैं।

चार परिणामी शब्द पूरी रिपोर्ट का सार बताते हैं।

  • ok: [web1] का अर्थ है कि module ने जांच की और state पहले से ही मेल खाती है। कुछ भी नहीं बदलेगा।
  • changed: [web1] का अर्थ है कि module ने कुछ लिखा होता। --diff के साथ, इसके ऊपर की पंक्तियाँ दिखाती हैं कि क्या बदलाव होता।
  • skipping: [web1] का अर्थ है कि task का मूल्यांकन नहीं किया गया। या तो कोई when गलत (false) था, या module check mode में नहीं चल सकता।
  • fatal: [web1] का अर्थ है कि जांच के दौरान task विफल हो गया। यह मानने से पहले कि playbook खराब है, संदेश को ध्यान से पढ़ें।

--diff file modules के लिए एक unified diff प्रिंट करता है, जिसमें हटाई गई पंक्तियाँ - के साथ और जोड़ी गई पंक्तियाँ + के साथ चिह्नित होती हैं। यह एक header के नीचे होता है जिसकी पंक्तियाँ --- before और +++ after से शुरू होती हैं और destination path का नाम बताती हैं। जो modules फाइलें नहीं लिखते, वे अपना 'before' और 'after' प्रिंट करते हैं, इसलिए ansible.builtin.user फाइल सामग्री के बजाय उन attributes को दिखाता है जिन्हें वह बदलता।

ansible.cfg में diff को स्थायी रूप से चालू करें ताकि आप कभी भी flag लगाना न भूलें:

[diff]
always = true
context = 5

Check mode से पहले दो सस्ते (cheaper) checks का उपयोग करना चाहिए। ansible-playbook site.yml --syntax-check किसी भी host से संपर्क किए बिना YAML और play structure को पार्स करता है। ansible-playbook site.yml --list-tasks उन tasks को प्रिंट करता है जो चलेंगे, जिससे आपको पता चलता है कि जिस role को आप tagged समझ रहे थे, वह वास्तव में tagged नहीं है। इनमें से कोई भी connection नहीं बनाता, इसलिए दोनों तुरंत परिणाम देते हैं।

Check mode स्वयं connection बनाता है। यह pattern में मौजूद हर host के लिए SSH खोलता है और facts इकट्ठा करता है, इसलिए जो host down है, उसका dry run विफल हो जाता है। यह अपने आप में एक उपयोगी संकेत है, और यही कारण है कि CI में dry run डालने से पहले unreachable hosts के लिए playbook क्या करे, यह तय करना महत्वपूर्ण है।

Fresh सर्वर पर check mode विफल क्यों होता है

यह playbook सही है। इसे एक ऐसे सर्वर पर --check के साथ चलाएं जिसमें अभी तक nginx नहीं है, तो इसका अधिकांश भाग विफल हो जाएगा।

- name: Install nginx
  ansible.builtin.apt:
    name: nginx
    state: present

- name: Write the site config
  ansible.builtin.template:
    src: site.conf.j2
    dest: /etc/nginx/conf.d/site.conf

- name: Start and enable nginx
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: true

apt task changed रिपोर्ट करता है, और यह सही है: package मौजूद नहीं है, इसलिए वास्तविक run इसे install कर देगा। Check mode ने इसे install नहीं किया। इसके बाद template task विफल हो जाता है, क्योंकि इस host पर /etc/nginx/conf.d/ मौजूद नहीं है और किसी भी चीज़ ने इसे बनाया नहीं है। service task भी विफल हो जाता है, क्योंकि query करने के लिए वहां कोई nginx unit नहीं है। इनमें से कोई भी विफलता playbook में bug नहीं है। Dry run उस state से बाहर हो गया जिसकी उसे आवश्यकता थी, और documentation का यही अर्थ है जब वह चेतावनी देता है कि check mode उस task के लिए उपयोगी output नहीं दे सकता जिसका input किसी पिछले task के बदलाव पर निर्भर करता है।

इसलिए नियम का ईमानदार संस्करण यह है: check mode उस host के लिए सटीक है जिसे playbook पहले ही converge कर चुका है, और एक नए host के लिए यह शोर (noisy) पैदा करता है। एक --check run जहां हर task ok रिपोर्ट करता है, वह एक converged host के बारे में एक वास्तविक स्थिति है, क्योंकि इसका मतलब है कि कुछ भी नहीं बदलेगा। बिल्कुल नए host पर, --check मुख्य रूप से आपको यह बताता है कि host नया है। जब आप VPS पर अपनी पहली Ansible playbook लिखते हैं, तो पहले dry run में बहुत सारी त्रुटियों (wall of red) की अपेक्षा करें, और playbook का मूल्यांकन दूसरे run से करें।

Check mode में command और shell tasks को क्यों छोड़ दिया जाता है

ansible.builtin.command और ansible.builtin.shell को यह जानकारी नहीं होती कि आपका command क्या करता है। किसी भी arbitrary binary को चलाने का कोई read-only तरीका नहीं है, इसलिए check mode में module इसे चलाने से मना कर देता है। task के परिणाम में skipped: true होता है और संदेश Command would have run if not in check mode होता है, और आपका output skipping: [web1] दिखाता है।

module documentation इसके check mode support को "आंशिक" (partial) कहता है, और जो workaround यह बताता है वह creates और removes है। task को एक creates path दें और check mode कम से कम file test का मूल्यांकन कर सकता है:

- name: Extract the release bundle
  ansible.builtin.command: /usr/bin/tar xf /tmp/app.tar.gz -C /opt/app
  args:
    creates: /opt/app/bin/app

यदि /opt/app/bin/app पहले से मौजूद है, तो check mode Would not run command since '/opt/app/bin/app' exists रिपोर्ट करता है, जो एक सटीक उत्तर है। यदि path मौजूद नहीं है, तो आपको Command would have run if not in check mode मिलता है, जो कि एक सटीक उत्तर है। creates के बिना, वह task आपके dry run में एक खाली जगह की तरह होता है।

इसका दुष्प्रभाव खाली जगह से भी बुरा होता है। एक skipped task अभी भी एक परिणाम दर्ज करता है, लेकिन वह परिणाम एक skip परिणाम होता है और इसमें कोई stdout key नहीं होती। इसके बाद वाले task की condition तब विफल हो जाती है जब उसका मूल्यांकन किया जा रहा होता है, और error 'dict object' has no attribute 'stdout' के करीब होती है। आपका playbook वास्तविक run में काम करता है और dry run में टूट जाता है, जो इस पूरी सुविधा में सबसे भ्रमित करने वाली विफलता है।

check_mode: false, और इसका सही स्थान

check_mode: false का किसी task पर उपयोग करने का अर्थ है "इसे वास्तविक रूप में चलाएं, भले ही --check सक्रिय हो"। यह skipped-command समस्या का समाधान है, और यह केवल उन tasks पर सुरक्षित है जो केवल डेटा पढ़ते हैं (read-only)।

- name: Read the installed app version
  ansible.builtin.command: /usr/local/bin/app --version
  register: app_version
  check_mode: false
  changed_when: false

वह task दोनों modes में ईमानदार रहता है। यह एक version पढ़ता है और कभी कुछ लिखता नहीं है, changed_when: false इसे बिना किए गए बदलाव की रिपोर्ट देने से रोकता है, और check_mode: false यह सुनिश्चित करता है कि dry run के दौरान app_version.stdout मौजूद रहे, ताकि उस पर आधारित conditions का मूल्यांकन सही ढंग से हो सके।

इस keyword को कहीं और इस्तेमाल करने से पहले इसके अर्थ को ध्यान से समझें। check_mode: false वाला task ansible-playbook --check के दौरान आपके servers पर बदलाव लिख सकता है। इसे किसी apt task या template task पर लगाने से dry run देखने में भले ही साफ-सुथरा लगे, लेकिन वह फिर dry run नहीं रह जाता। जब किसी writing task को सुरक्षित नहीं बनाया जा सकता, तो उसे इसके बजाय guard करें:

- name: Apply the database migration
  ansible.builtin.command: /usr/local/bin/app migrate --apply
  when: not ansible_check_mode

ansible_check_mode एक magic variable है जिसे Ansible चेक रन के दौरान true पर सेट करता है। इसका विपरीत keyword भी मौजूद है। check_mode: true किसी task को हमेशा check mode में ही रखता है, वास्तविक रन के दौरान भी, जो इसे एक drift probe में बदल देता है: परिणाम को register करें, और changed रिपोर्ट का अर्थ है कि host अब उस स्थिति में नहीं है जो task द्वारा अपेक्षित है।

हर बार रन करने पर टास्क 'changed' क्यों दिखाता है

Playbook को बिना किसी बदलाव के लगातार दो बार चलाएं। दूसरी बार चलाने पर हर टास्क को ok रिपोर्ट करना चाहिए। यदि कोई टास्क अभी भी changed रिपोर्ट कर रहा है, तो इसका मतलब है कि या तो मॉड्यूल उस स्टेट को देख नहीं पा रहा है जिसे वह मैनेज करता है, या फिर जो इनपुट आप दे रहे हैं वह स्थिर (stable) नहीं है। दोनों ही समस्याओं को ठीक किया जा सकता है और इन्हें नजरअंदाज नहीं किया जाना चाहिए।

  • command और shell जिनमें कोई creates, removes या changed_when नहीं होता, वे हर बार changed रिपोर्ट करते हैं, क्योंकि मॉड्यूल के पास यह जानने का कोई तरीका नहीं है कि कुछ हुआ है या नहीं। इसमें creates जोड़ें, या आउटपुट में किसी स्ट्रिंग के विरुद्ध changed_when सेट करें।
  • ansible.builtin.file के साथ state: touch का उपयोग करने पर यह हर बार changed रिपोर्ट करता है, क्योंकि फाइल को टच करने से उसका टाइमस्टैम्प अपडेट हो जाता है। यदि आप केवल ओनर या मोड सेट करना चाहते हैं, तो state: file का उपयोग करें।
  • एक template जिसका रेंडर किया गया आउटपुट बदलता रहता है, वह हर बार फाइल को फिर से लिखता है। ansible_date_time से प्राप्त टाइमस्टैम्प, now() को कॉल करना, या हर बार नया जनरेट होने वाला पासवर्ड, ये सभी अलग-अलग बाइट्स बनाते हैं, इसलिए मॉड्यूल सही तरीके से बदलाव की रिपोर्ट करता है। बदलते हुए मान को टेम्पलेट से हटा दें।
  • ansible.builtin.user के साथ password: "{{ pw | password_hash('sha512') }}" हर बार बदलता है, क्योंकि password_hash हर बार कॉल किए जाने पर एक रैंडम साल्ट चुनता है, इसलिए परिणामी हैश कभी भी /etc/shadow में मौजूद हैश से मेल नहीं खाता। किसी स्थिर मान से प्राप्त एक स्पष्ट साल्ट (explicit salt) का उपयोग करें।
  • पैकेज मॉड्यूल पर state: latest तब changed रिपोर्ट करता है जब कोई अपग्रेड उपलब्ध होता है। यह सही व्यवहार है। यही कारण है कि state: latest का उपयोग करने पर आपको ऐसी playbook मिलती है जिसका परिणाम आप पहले से नहीं बता सकते। state: present का उपयोग करें और जानबूझकर अपग्रेड करें।
  • बिना creates के किसी URL पर पॉइंट किया गया ansible.builtin.unarchive हर बार फाइल को फिर से फेच और एक्सट्रैक्ट करता है। इसे एक creates पाथ दें।

इनके बीच अंतर बताने का सबसे तेज़ तरीका --diff है। यदि कोई टास्क changed कहता है और डिफ (diff) में बाइट्स अलग दिखते हैं, तो आपका इनपुट अस्थिर है। यदि यह changed कहता है और डिफ में कुछ भी नहीं दिखता है, तो मॉड्यूल यह नहीं बता पा रहा है कि उसने क्या बदला है, जिसका अर्थ आमतौर पर एक command टास्क या केवल मेटाडेटा (जैसे टाइमस्टैम्प) में बदलाव है।

किसी शोर मचाने वाले टास्क को शांत करने के लिए changed_when: false का उपयोग न करें। यह रिपोर्ट को दबा देता है, इसलिए notify कभी ट्रिगर नहीं होता और सर्विस को रीस्टार्ट करने वाला हैंडलर कभी नहीं चलता। इसके बजाय टास्क को ठीक करें।

ब्लास्ट रेडियस को सीमित करना: --limit, --tags और --step

Check mode आपको बताता है कि क्या बदलाव होंगे। ये flags तय करते हैं कि एक बार में कितनी मशीनों पर बदलाव लागू होंगे।

--limit प्ले को इन्वेंट्री के एक सबसेट तक सीमित कर देता है। यह वही पैटर्न लेता है जो hosts: लेता है, इसलिए --limit web1 और --limit 'webservers:!web3' दोनों काम करते हैं। पैटर्न को कोट (quote) करें। एक इंटरैक्टिव bash सेशन में बिना कोट किया हुआ ! history expansion on the exclamation mark को ट्रिगर कर देता है, और Ansible के पास पहुँचने से पहले ही आपका शेल कमांड को फिर से लिख देता है।

पैटर्न पर भरोसा करने से पहले उसे कन्फर्म करें। ansible-playbook site.yml --limit 'webservers:!web3' --list-hosts मेल खाने वाले होस्ट्स को प्रिंट करता है और किसी से भी कनेक्ट किए बिना बाहर निकल जाता है। जो पैटर्न किसी से मेल नहीं खाता वह सुरक्षित है, क्योंकि Ansible पूरी इन्वेंट्री पर वापस नहीं जाता है। यह एक चेतावनी प्रिंट करता है कि यह होस्ट पैटर्न से मेल नहीं खा सका, फिर एक एरर के साथ बाहर निकल जाता है कि होस्ट्स और --limit किसी भी होस्ट से मेल नहीं खाते। इन्वेंट्री फ़ाइल उन समूहों को कैसे परिभाषित करती है, यह जानना ही पैटर्न को पूर्वानुमानित बनाता है।

--tags deploy केवल टैग किए गए टास्क चलाता है, और --skip-tags packages बाकी सब कुछ चलाता है। --list-tags उपलब्ध टैग्स को प्रिंट करता है। टैग्स तब उपयोगी होते हैं जब प्ले इतना बड़ा हो जाए कि आप उसे पूरा चलाने के इच्छुक न हों, जो कि एक लंबे प्लेबुक को रोल्स में विभाजित करने के कारणों में से एक है।

--start-at-task "Write the site config" एक विफल रन को एक नामित टास्क से फिर से शुरू करता है। इसे रिकवरी के लिए उपयोग करें, और समझें कि इसकी कीमत क्या है: उस टास्क से पहले की हर चीज़ छोड़ दी जाती है, जिसमें वे टास्क भी शामिल हैं जो फैक्ट्स सेट करते हैं या उन वेरिएबल्स को रजिस्टर करते हैं जिन्हें बाद के टास्क पढ़ते हैं।

--step प्रत्येक टास्क से पहले प्रॉम्प्ट करता है और आपके हाँ, ना, या जारी रखने के उत्तर की प्रतीक्षा करता है। यह धीमा है, और जब आप पहली बार कुछ विनाशकारी चला रहे हों तो यह सही टूल है, क्योंकि आप बीस टास्क के बाद के बजाय दो टास्क के बीच में ही रुक सकते हैं।

serial के साथ बदलाव लागू करना

डिफ़ॉल्ट रूप से Ansible अगला task शुरू करने से पहले play में मौजूद हर host पर एक task चलाता है। यह तेज़ है, लेकिन इसका मतलब यह है कि एक खराब task उसी सेकंड में पूरे fleet तक पहुँच जाता है। जब तक आप error पढ़कर Ctrl-C दबाते हैं, तब तक बदलाव हर जगह हो चुका होता है।

serial play को batches में विभाजित करता है। पूरी play पहले batch पर चलती है, फिर अगले पर।

- name: Roll out the web tier
  hosts: webservers
  serial: [1, 5, "30%"]
  max_fail_percentage: 0
  tasks:
    - name: Deploy the release
      ansible.builtin.include_role:
        name: webapp

पहला batch एक host का होता है। यदि वह ठीक रहता है, तो दूसरा batch पाँच hosts का होता है, और उसके बाद के सभी batches play के कुल hosts का 30 प्रतिशत होते हैं। max_fail_percentage: 0 जैसे ही किसी batch में कोई host fail होता है, play को समाप्त कर देता है, इसलिए एक खराब release केवल एक मशीन पर रुक जाती है। any_errors_fatal: true अधिक कठोर संस्करण है, जो पहले host के fail होते ही सभी के लिए play को समाप्त कर देता है।

पहले एक host पर चलाना paranoia नहीं है, और इसका कारण विशिष्ट है। Inventory groups में बदलाव (drift) आ जाता है। दूसरों के छह महीने बाद जोड़ा गया सर्वर शायद अलग distribution release चला रहा हो, या उसमें किसी ने हाथ से कोई service install की हो, या उसकी disks अलग तरह से व्यवस्थित हों। Playbook group के लिए सही हो सकती है लेकिन उस एक host के लिए गलत, और converged host पर किया गया कोई भी dry run इसे नहीं दिखाएगा। Linux servers के बेड़े का प्रबंधन मुख्य रूप से बदलाव होने से पहले ही अजीब host को ढूँढने का अभ्यास है।

चीजों को चलाने का क्रम

  1. ansible-playbook site.yml --syntax-check बिना किसी नेटवर्क के YAML और संरचना संबंधी गलतियों को पकड़ता है।
  2. ansible-playbook site.yml --limit web1 --list-hosts यह सिद्ध करता है कि आपका पैटर्न उसी से मेल खाता है जिससे आप मेल खाना चाहते हैं।
  3. ansible-playbook site.yml --limit web1 --check --diff यह एक ड्राई रन है। diff को पढ़ें।
  4. ansible-playbook site.yml --limit web1 --diff इसे उस एक होस्ट पर लागू करें।
  5. चरण 4 को फिर से चलाएँ। सब कुछ ok रिपोर्ट करना चाहिए। जो कुछ भी अभी भी changed है, वह एक ऐसा कार्य है जिसे बाकी फ्लीट (fleet) को प्रभावित करने से पहले ठीक करना आवश्यक है।
  6. ansible-playbook site.yml --check --diff अब पूरे इन्वेंट्री में एक सार्थक उत्तर देता है, क्योंकि कन्वर्ज्ड (converged) होस्ट शांत हैं और जो शेष है वह वास्तविक डेल्टा (delta) है।

चरण 3 के बारे में एक चेतावनी। --diff फाइल की सामग्री को आपके टर्मिनल और आपके CI जॉब लॉग में प्रिंट करता है, इसलिए एक टेम्प्लेट जो डेटाबेस पासवर्ड रेंडर करता है, वह उस पासवर्ड को लॉग में रेंडर कर देता है। उस आउटपुट को दबाने के लिए उस टास्क पर diff: false सेट करें, या पूरे परिणाम को छिपाने के लिए no_log: true का उपयोग करें, और मान (value) को रिपॉजिटरी के बजाय एक एन्क्रिप्टेड Ansible Vault फाइल में रखें।

FAQ

क्या ansible-playbook --check सर्वर पर कुछ बदलता है?

नहीं, केवल एक अपवाद को छोड़कर जिसे आप नियंत्रित करते हैं। चेक मोड में हर module को लिखने के बजाय रिपोर्ट करने के लिए कहा जाता है, और जो modules ऐसा नहीं कर सकते वे कुछ भी रिपोर्ट नहीं करते और न ही कुछ करते हैं। अपवाद check_mode: false task keyword है, जो उस एक task को --check रन के दौरान भी वास्तव में निष्पादित (execute) करने के लिए मजबूर करता है। ड्राई रन पर भरोसा करने से पहले अपने playbooks और roles में check_mode: false खोजें, और सुनिश्चित करें कि हर match केवल state पढ़ने वाला task है।

--check और --diff में क्या अंतर है?

--check यह तय करता है कि क्या वास्तव में कुछ भी चलेगा। --diff यह तय करता है कि आपको कितनी विस्तृत जानकारी दिखाई देगी। --check अकेले आपको यह बताता है कि कोई फाइल बदलेगी। --diff अकेले बदलाव लागू करता है और आपको बदली हुई पंक्तियाँ दिखाता है। एक ऐसे ड्राई रन के लिए जो आप वास्तव में पढ़ सकें, इनका एक साथ उपयोग करें, और वास्तविक रन के लिए भी --diff को चालू रखें, जिसके लिए ansible.cfg में [diff] के अंतर्गत always = true सेट करें।

मेरा Ansible task हर रन पर changed क्यों रिपोर्ट करता है?

क्योंकि module उस state को नहीं देख पाता जिसे वह manage करता है, या जो value आप उसे देते हैं वह हर बार अलग होती है। command और shell हमेशा changed रिपोर्ट करते हैं जब तक कि आप creates या changed_when न जोड़ें। state: touch के साथ file अपनी प्रकृति से ही बदलाव करता है। एक template जो timestamp या नया जनरेट किया गया password रेंडर करता है, हर रन पर अलग bytes बनाता है, इसलिए फाइल वास्तव में हर बार फिर से लिखी जा रही है। playbook को लगातार दो बार चलाएं: दूसरे पास पर जो भी अभी भी changed है, वही वह task है जिसे ठीक करने की आवश्यकता है।

ड्राई रन के दौरान मेरे command और shell tasks क्यों छोड़ (skip) दिए जाते हैं?

क्योंकि किसी भी मनमानी command को चलाने का कोई read-only तरीका नहीं है। चेक मोड में command module Command would have run if not in check mode संदेश के साथ skipped: true सेट कर देता है। creates या removes जोड़ें ताकि चेक मोड फाइल टेस्ट का मूल्यांकन कर सके। केवल state पढ़ने वाले task के लिए, check_mode: false को changed_when: false के साथ सेट करें, ताकि ड्राई रन के दौरान registered result मौजूद रहे और उस पर आधारित conditions काम करती रहें।

चेक मोड नए सर्वर पर विफल क्यों होता है लेकिन मौजूदा सर्वर पर पास हो जाता है?

क्योंकि चेक मोड वह state नहीं बनाता जिस पर बाद के tasks निर्भर करते हैं। nginx के बिना किसी host पर ड्राई रन install को changed रिपोर्ट करता है, फिर उस task पर विफल हो जाता है जो /etc/nginx/conf.d/ में लिखता है, क्योंकि वह directory कभी बनाई ही नहीं गई थी। यह अपेक्षित व्यवहार है। चेक मोड उन hosts के लिए drift detector है जिन पर playbook पहले ही लागू हो चुका है। यह पहले रन को validate नहीं कर सकता। नए host पर, playbook को एक मशीन पर लागू करें और दूसरे रन को पढ़ें।

#ansible#check-mode#idempotency#automation#safety