SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor

Ansible --check ও --diff dry run কী সত্যিই দেখায়

Ansible-এর --check ও --diff কী প্রমাণ করে দেখুন: কোন module check mode সমর্থন না করায় dry run ভুল ফল দেয়, এবং বাস্তব প্রয়োগে কী বদলাতে পারে।

Ansible check mode কী করে

Ansible check mode হলো একটি dry run: ansible-playbook --check play-এর প্রতিটি host-এ সংযোগ করে, প্রতিটি module-কে জিজ্ঞেস করে বর্তমান state আপনার নির্ধারিত state-এর সঙ্গে মিলে কি না, এবং কোনো কিছু write না করেই কী পরিবর্তন হতে পারে তা জানায়। --diff যোগ করলে যে file-গুলোতে পরিবর্তন করা হতো, সেগুলোর আগের ও পরের content-ও দেখায়। এই দুটির সাহায্যে প্রতিটি বাস্তব run-এর আগে গুরুত্বপূর্ণ প্রশ্নটির উত্তর পাওয়া যায়: এই server-গুলোতে এখন কী পরিবর্তন হতে যাচ্ছে?

Check mode আপনার playbook-এর simulation নয়। কোথাও server-এর কোনো model তৈরি হয় না। প্রতিটি module-কে শুধু write করার পরিবর্তে দেখার নির্দেশ দেওয়া হয়। যে module read-only অবস্থায় উত্তর দিতে পারে, সেটি changed জানিয়ে পরবর্তী কাজে যায়। যে module উত্তর দিতে পারে না, সেটি কিছু করে না এবং কিছু জানায়ও না। Ansible documentation-এ বিষয়টি এক লাইনে বলা হয়েছে: "যে module check mode সমর্থন করে না, সেটি কিছু জানায় না এবং কিছু করে না।" এই সীমাবদ্ধতার কারণেই dry run ভুল উত্তর দিতে পারে; তাই এই guide-এর অধিকাংশ অংশ এই সীমাবদ্ধতা নিয়ে।

Dry run চালান: --check এবং --diff

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

-C এবং -D হলো দুটি flag-এর সংক্ষিপ্ত রূপ। --limit ইচ্ছাকৃত। একটি host-এর diff পড়া যায়। 20টি host-এর diff সাধারণত শুধু scroll করে পার হতে হয়।

চারটি ফলাফলের শব্দ পুরো report-এর অর্থ বহন করে।

  • ok: [web1] এর অর্থ task চলেছে এবং কোনো পরিবর্তন report করেনি। apt বা template-এর মতো state পরিচালনাকারী module-এর ক্ষেত্রে এর অর্থ, module state পরীক্ষা করেছে এবং state ইতিমধ্যেই মিলে গেছে। debug বা set_fact-এর ক্ষেত্রে এর অর্থ শুধু task চলেছে।
  • changed: [web1] এর অর্থ module অনুমান করছে যে এটি কিছু লিখত। --diff থাকলে তার ওপরের লাইনগুলোতে কী লিখত তা দেখানো হয়। অধিকাংশ module সঠিকভাবে অনুমান করে। তবে partial check mode support থাকা কয়েকটি module তাদের documentation-এ সতর্ক করে। যেমন, get_url check mode-এ শুধু HEAD request পাঠায় এবং জানায় যে এটি ভুল changed status report করবে।
  • skipping: [web1] এর অর্থ task চলেনি। হয় এর when evaluate হয়ে false হয়েছে, অথবা module check mode-এ চলতে পারে না।
  • fatal: [web1] এর অর্থ check করার সময় task ব্যর্থ হয়েছে। Playbook নষ্ট হয়েছে ধরে নেওয়ার আগে message পড়ুন।

--diff file module-এর জন্য unified diff print করে। অপসারিত লাইনগুলো - এবং যোগ করা লাইনগুলো + দিয়ে চিহ্নিত থাকে। এগুলো এমন একটি header-এর অধীনে থাকে, যার লাইন --- before এবং +++ after দিয়ে শুরু হয় এবং destination path-এর নাম দেয়। যে module file লেখে না, সেটি নিজের before এবং after ফলাফল print করে। তাই ansible.builtin.user file content-এর বদলে যে attribute পরিবর্তন করার কথা, তা দেখায়।

ansible.cfg-এ diff স্থায়ীভাবে চালু করুন, যাতে flag-টি ভুলে না যান:

[diff]
always = true
context = 5

Check mode-এর আগে দুটি কম খরচের check করা উচিত। ansible-playbook site.yml --syntax-check কোনো host-এর সঙ্গে যোগাযোগ না করেই YAML এবং play structure parse করে। ansible-playbook site.yml --list-tasks কোন task চলত তা print করে। এর মাধ্যমে বোঝা যায়, আপনি যে role-কে tagged মনে করেছিলেন সেটি আসলে tagged নয়। কোনোটিই connection তৈরি করে না, তাই দুটিই সঙ্গে সঙ্গে শেষ হয়।

Check mode নিজে connection তৈরি করে। এটি pattern-এর প্রতিটি host-এ SSH খোলে এবং facts সংগ্রহ করে। তাই কোনো host down থাকলে dry run ব্যর্থ হয়। এটি নিজেই একটি কার্যকর signal। একই কারণে CI-তে dry run যোগ করার আগে unreachable host নিয়ে playbook কী করবে তা নির্ধারণ করা গুরুত্বপূর্ণ।

নতুন সার্ভারে check mode কেন ব্যর্থ হয়

এই play সঠিক। nginx এখনো ইনস্টল করা নেই এমন সার্ভারে --check দিয়ে এটি চালালে এর বেশির ভাগ অংশ ব্যর্থ হবে।

- 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 হলে এটি ইনস্টল করা হতো। Check mode package-টি ইনস্টল করেনি। এরপর template task-টি ব্যর্থ হয়, কারণ এই host-এ /etc/nginx/conf.d/ নেই এবং কোনো কিছু এটি তৈরি করেনি। service task-টিও ব্যর্থ হয়, কারণ query করার মতো কোনো nginx unit নেই। এই ব্যর্থতাগুলোর কোনোটিই playbook-এর bug নয়। Dry run-এর জন্য প্রয়োজনীয় state তৈরি হয়নি। কোনো task-এর input আগের task-এর change-এর ওপর নির্ভর করলে check mode কার্যকর output দিতে পারে না—documentation-এর সতর্কবার্তাটি এটাই বোঝায়।

তাই নিয়মটির সঠিক ব্যাখ্যা হলো: playbook যে host-এ আগে থেকেই converge করেছে, সেই host-এর বিরুদ্ধে check mode সবচেয়ে নির্ভুল। নতুন host-এর বিরুদ্ধে এটি অনেক অতিরিক্ত error দেখায়। এমন host-এ --check run-এ প্রতিটি task ok জানালে সেটি converge করা host সম্পর্কে বাস্তব তথ্য দেয়, কারণ এর অর্থ কোনো কিছু পরিবর্তন হবে না। তবে যেকোনো host-এর ক্ষেত্রেই দুটি ব্যতিক্রম মনে রাখতে হবে: skipped command task কোনো উত্তর নয়, বরং একটি ফাঁকা স্থান; এবং get_url-এর মতো partial check mode support থাকা module changed status ভুল জানাতে পারে। একেবারে নতুন host-এ --check মূলত শুধু জানায় যে host-টি নতুন। আপনি যখন কোনো VPS-এর জন্য আপনার প্রথম Ansible playbook লিখবেন, তখন প্রথম dry run-এ অনেক red output দেখা যাবে—এটি প্রত্যাশিত। Playbook-এর বিচার করুন দ্বিতীয় run দেখে।

check mode-এ command এবং shell task কেন এড়িয়ে যাওয়া হয়

ansible.builtin.command এবং ansible.builtin.shell আপনার command কী করে তা জানে না। নির্বিচারে কোনো binary চালানোর read-only পদ্ধতি নেই। তাই check mode-এ module সেটি চালাতে অস্বীকার করে। task result-এ skipped: true থাকে এবং Command would have run if not in check mode message দেখা যায়। আপনার 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 report করে। এটি একটি প্রকৃত ফলাফল। path অনুপস্থিত হলে Command would have run if not in check mode পাওয়া যায়। এটিও একটি প্রকৃত ফলাফল। creates ছাড়া dry run-এ ওই task-টি ফাঁকা থেকে যায়।

এর পরবর্তী প্রভাব এই ফাঁকা ফলাফলের চেয়েও খারাপ। এড়িয়ে যাওয়া command task-ও একটি result নিবন্ধন করে। সেই result-এ stdout থাকে, তবে সেটি একটি empty string, কারণ কিছুই চালানো হয়নি। পরের task-এর condition ওই empty string-এর বিরুদ্ধে মূল্যায়িত হয় এবং নীরবে ভুল branch বেছে নেয়। version check কোনো version পায় না, এবং 'active' in svc.stdout-এর মতো test false হিসেবে গণ্য হয়। ফলে real run-এ playbook একটি ফলাফল দেয়, আর dry run-এ অন্য ফলাফল দেয়। কোনো error না থাকায় কারণ শনাক্ত করার উপায় থাকে না। এই feature-এর মধ্যে এটিই সবচেয়ে বিভ্রান্তিকর failure। 'dict object' has no attribute 'stdout' error ভিন্ন ধরনের skip-এর ক্ষেত্রে প্রযোজ্য। কোনো task-এর when false হওয়ার কারণে task এড়িয়ে গেলে result নিবন্ধিত হয়, কিন্তু তাতে stdout key একেবারেই থাকে না।

check_mode: false, এবং এটি যে একমাত্র স্থানে ব্যবহার করা যায়

check_mode: false কোনো task-এ থাকলে --check-এর অধীনেও সেটি বাস্তবে চালানো হয়। স্কিপ হওয়া command-এর সমস্যার সমাধান এটি। তবে এটি শুধু read-only task-এ নিরাপদ।

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

উভয় mode-এই task-টি সঠিকভাবে কাজ করে। এটি একটি version পড়ে এবং কখনো কিছু লেখে না। changed_when: false task-টি যে পরিবর্তন করেনি, তা পরিবর্তন হিসেবে report করা বন্ধ করে। check_mode: false dry run-এর সময় app_version.stdout-তে খালি string-এর বদলে প্রকৃত version রাখে। ফলে এর ওপর নির্ভর করা condition-গুলোও সঠিকভাবে evaluate হয়।

অন্য কোথাও paste করার আগে keyword-টির অর্থ আক্ষরিকভাবে বুঝে নিন। check_mode: false-সহ কোনো task ansible-playbook --check চলাকালে আপনার server-এ write করে। এটি কোনো 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, যা check run চলাকালে Ansible true হিসেবে সেট করে। এর বিপরীত keyword-ও আছে। check_mode: true একটি task-কে সব সময় check mode-এ চালায়, এমনকি real run-এর সময়ও। এতে task-টি drift probe হিসেবে কাজ করে: ফলাফল register করুন, এবং changed report-এর অর্থ হলো host আর task-এ নির্ধারিত অবস্থার সঙ্গে মেলে না।

প্রতিটি রানেই কোনো task changed রিপোর্ট করার কারণ

playbook-টি পরপর দুইবার চালান। মাঝখানে কোনো পরিবর্তন করবেন না। দ্বিতীয় রানে প্রতিটি task-এর ok রিপোর্ট করার কথা। কোনো task এখনও changed রিপোর্ট করলে এর দুটি কারণের একটি রয়েছে: module যে state পরিচালনা করে, সেটি দেখতে পাচ্ছে না; অথবা আপনি যে input দিচ্ছেন, সেটি স্থিতিশীল নয়। দুটিই ঠিক করা যায়। কোনোটিই উপেক্ষা করার মতো noise নয়।

  • command এবং shell-এ কোনো creates, removes বা changed_when না থাকলে প্রতিবারই changed রিপোর্ট হবে, কারণ module-এর পক্ষে কিছু ঘটেছে কি না জানার কোনো উপায় নেই। creates যোগ করুন, অথবা output-এর কোনো string-এর সঙ্গে changed_when সেট করুন।
  • ansible.builtin.file-এর সঙ্গে state: touch থাকলে প্রতিটি রানে changed রিপোর্ট হবে। কারণ file স্পর্শ করলে তার timestamp আপডেট হয়। আপনার উদ্দেশ্য শুধু owner বা mode নির্ধারণ করা হলে state: file ব্যবহার করুন।
  • কোনো template-এর rendered output পরিবর্তিত হলে প্রতিটি রানে file নতুন করে লেখা হয়। ansible_date_time থেকে আসা timestamp, now()-এ একটি call, অথবা প্রতিবার নতুন করে তৈরি করা password—সবই আলাদা byte তৈরি করে। তাই module সঠিকভাবেই change রিপোর্ট করে। পরিবর্তনশীল value-টি template-এর বাইরে রাখুন।
  • ansible.builtin.user-কে password: "{{ pw | password_hash('sha512') }}"-এর সঙ্গে ব্যবহার করলে প্রতিটি রানে পরিবর্তন হবে। কারণ password_hash প্রতিবার call হলে random salt বেছে নেয়। ফলে তৈরি হওয়া hash কখনও /etc/shadow-এ থাকা hash-এর সঙ্গে মেলে না। স্থিতিশীল কোনো value থেকে তৈরি explicit salt দিন।
  • package module-এ state: latest ব্যবহার করলে upgrade উপলভ্য হলেই changed রিপোর্ট হবে। এটি সঠিক রিপোর্ট। এ কারণেই state: latest ব্যবহার করলে এমন playbook পাওয়া যায়, যার ফল আগে থেকে নির্ধারণ করা যায় না। state: present ব্যবহার করুন এবং ইচ্ছাকৃতভাবে upgrade করুন।
  • ansible.builtin.unarchive-কে কোনো URL-এর দিকে নির্দেশ করালে এবং creates না থাকলে প্রতিটি রানে archive আবার download হবে। archive type-এর ক্ষেত্রে এটি destination-এর সঙ্গে তুলনাও করতে পারে না, তাই archive আবার unpack হবে। একটি creates path দিন।

--diff ব্যবহার করাই এই কারণগুলো দ্রুত আলাদা করার উপায়। কোনো task changed বললে এবং diff-এ ভিন্ন byte দেখা গেলে input স্থিতিশীল নয়। যদি changed বলে এবং diff-এ কিছুই না দেখা যায়, তাহলে module কী পরিবর্তন করেছে তা প্রকাশ করতে পারছে না। সাধারণত এর অর্থ task-টি command, অথবা timestamp-এর মতো metadata-only write ঘটেছে।

কোনো noisy task নীরব করতে changed_when: false ব্যবহার করবেন না। এটি report দমন করে। ফলে notify কখনও চালু হয় না এবং service restart করা handler-ও চলে না। পরিবর্তে task-টি ঠিক করুন।

পরিবর্তনের প্রভাব সীমিত রাখুন: --limit, --tags এবং --step

Check mode কী পরিবর্তন হতে পারে তা দেখায়। একসঙ্গে কতগুলো মেশিনে তা কার্যকর হবে, এই flag-গুলো তা নির্ধারণ করে।

--limit inventory-এর একটি উপসেটে play সীমাবদ্ধ করে। এটি hosts:-এর মতো একই pattern গ্রহণ করে, তাই --limit web1 এবং --limit 'webservers:!web3'—দুটিই কাজ করে। Pattern-টি quote করুন। Interactive bash session-এ unquoted ! ব্যবহার করলে exclamation mark-এ history expansion সক্রিয় হয়, এবং Ansible সেটি দেখার আগেই আপনার shell command-টি পরিবর্তন করে।

Pattern-টির ওপর নির্ভর করার আগে এটি নিশ্চিত করুন। ansible-playbook site.yml --limit 'webservers:!web3' --list-hosts মিলে যাওয়া host-গুলো দেখায় এবং কোনো host-এর সঙ্গে সংযোগ না করেই প্রস্থান করে। কোনো pattern-এর সঙ্গে কিছু না মিললেও এটি নিরাপদ, কারণ Ansible পুরো inventory-তে fallback করে না। এটি একটি warning দেখায় যে host pattern-এর সঙ্গে মেলানো যায়নি। এরপর error দেখিয়ে প্রস্থান করে যে inventory, host pattern এবং --limit-এ target করার মতো কোনো host অবশিষ্ট নেই। inventory file-এ group-গুলো কীভাবে সংজ্ঞায়িত করা হয়েছে তা জানা থাকলেই শুরু থেকেই pattern নির্ভরযোগ্যভাবে ব্যবহার করা যায়।

--tags deploy শুধু tagged task চালায়, আর --skip-tags packages বাকি সব task চালায়। --list-tags উপলভ্য tag-গুলো দেখায়। কোনো play এত বড় হয়ে গেলে যে পুরো play চালাতে আপনি আর আগ্রহী নন, তখন tag কার্যকর হয়। এটিই দীর্ঘ playbook-কে role-এ ভাগ করার অন্যতম কারণ।

--start-at-task "Write the site config" নামযুক্ত task থেকে ব্যর্থ run পুনরায় চালু করে। এটি recovery-র জন্য ব্যবহার করুন, তবে এর খরচ বুঝে নিন: ওই task-এর আগের সব task বাদ পড়ে। এর মধ্যে এমন task-ও থাকে যেগুলো fact সেট করে বা পরবর্তী task যে variable পড়ে তা register করে।

--step প্রতিটি task-এর আগে prompt দেখায় এবং আপনার yes, no অথবা continue উত্তর দেওয়ার অপেক্ষা করে। এটি ধীর। প্রথমবার কোনো destructive কাজ চালানোর সময় এটিই সঠিক tool, কারণ বিশটি task শেষ হওয়ার পরে নয়, বরং দুটি task-এর মাঝেই আপনি থামতে পারবেন।

ধাপে ধাপে পরিবর্তন প্রয়োগ করুন

ডিফল্টভাবে Ansible পরবর্তী task শুরু করার আগে play-তে থাকা প্রতিটি host-এর বিরুদ্ধে একটি task চালায়। এটি দ্রুত, কিন্তু এর ফলে কোনো ভুল task একই সেকেন্ডে পুরো fleet-এ পৌঁছে যায়। Error পড়ে Ctrl-C চাপার আগেই পরিবর্তনটি সর্বত্র প্রয়োগ হয়ে যায়।

serial play-কে একাধিক batch-এ ভাগ করে। পুরো play প্রথম batch-এর বিরুদ্ধে চলে, তারপর পরবর্তী 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-এ পাঁচটি host থাকে, এবং এরপরের প্রতিটি batch-এ play-এর host-গুলোর 30 percent থাকে। কোনো batch-এ যেকোনো host ব্যর্থ হলেই max_fail_percentage: 0 play-এর বাকি অংশ বন্ধ করে, কারণ threshold অতিক্রম করতে হয় এবং শূন্যের বেশি যেকোনো failure সেই threshold অতিক্রম করে। একটি host-এর নিশ্চয়তা ওই setting থেকে আসে না; এটি আসে প্রথম batch থেকে। এমন release যা সর্বত্র সমস্যা তৈরি করে, batch one-এর একক host-এই ব্যর্থ হয় এবং সেখানেই থেমে যায়। পাঁচ-হোস্টের batch-এ যে failure কেবল তখন দেখা দেয়, সেটি ওই batch-এর অন্য host-গুলোতেও ইতিমধ্যে পৌঁছে গেছে, কারণ Ansible পরবর্তী task শুরু করার আগে পুরো batch-এর বিরুদ্ধে প্রতিটি task চালায়। any_errors_fatal: true হলো আরও কঠোর সংস্করণ; প্রথম host failure-এই এটি সবার জন্য play বন্ধ করে।

প্রথমে একটি host-এর বিরুদ্ধে চালানো paranoia নয়। এর নির্দিষ্ট কারণ আছে। Inventory group সময়ের সঙ্গে বদলে যায়। অন্যগুলোর ছয় মাস পরে যোগ করা কোনো server-এ ভিন্ন distribution release থাকতে পারে, কেউ হাতে করে ইনস্টল করা কোনো service থাকতে পারে, অথবা তার disk layout ভিন্ন হতে পারে। Playbook-টি group-এর জন্য সঠিক হলেও ওই একক host-এর জন্য ভুল হতে পারে। Converged host-এর বিরুদ্ধে কোনো dry run এটি প্রকাশ করবে না। Linux server fleet পরিচালনা-এর বড় অংশ হলো পরিবর্তনটি সমস্যাটি প্রকাশ করার আগে ব্যতিক্রমী host খুঁজে বের করা।

যেভাবে ধাপগুলো চালাবেন

  1. ansible-playbook site.yml --syntax-check কোনো network ছাড়াই YAML এবং structure-এর ভুল শনাক্ত করে।
  2. ansible-playbook site.yml --limit web1 --list-hosts নিশ্চিত করে যে আপনার pattern প্রত্যাশামতোই match করছে।
  3. ansible-playbook site.yml --limit web1 --check --diff dry run চালায়। diff পড়ুন।
  4. ansible-playbook site.yml --limit web1 --diff এটি ওই একটি host-এ প্রয়োগ করে।
  5. ধাপ 4 আবার চালান। সবকিছুর ফলাফল ok হওয়া উচিত। কোনো কিছু এখনও changed থাকলে, বাকি fleet-এ প্রয়োগের আগে সেটি ঠিক করতে হবে।
  6. এখন পুরো inventory-তে ansible-playbook site.yml --check --diff চালালে অর্থবহ ফলাফল পাওয়া যাবে, কারণ সঠিক অবস্থায় আনা host-গুলো নীরব থাকবে এবং অবশিষ্ট ফলাফলই প্রকৃত delta দেখাবে।

ধাপ 3 সম্পর্কে একটি সতর্কতা আছে। --diff file-এর content আপনার terminal এবং CI job log-এ output করে। তাই কোনো template-এ database password থাকলে সেই password-ও log-এ চলে যাবে। Output বন্ধ করতে ওই task-এ diff: false সেট করুন, অথবা পুরো result আড়াল করতে no_log: true ব্যবহার করুন। প্রকৃত value repository-তে না রেখে একটি encrypted Ansible Vault file-এ রাখুন।

FAQ

ansible-playbook --check কি সার্ভারে কোনো পরিবর্তন করে?

না, তবে একটি ব্যতিক্রম আছে, যা আপনি নিয়ন্ত্রণ করতে পারেন। Check mode-এ প্রতিটি module-কে write করার পরিবর্তে report করতে বলা হয়। যে module এই কাজ করতে পারে না, সেটি কিছু report করে না এবং কিছু পরিবর্তনও করে না। ব্যতিক্রমটি হলো check_mode: false task keyword। এটি --check run চললেও ওই নির্দিষ্ট task-কে বাস্তবে execute করতে বাধ্য করে। Dry run-এর ওপর নির্ভর করার আগে আপনার playbook এবং role-এ check_mode: false খুঁজুন। প্রতিটি match শুধু state পড়ে এমন task কি না, তা নিশ্চিত করুন।

--check এবং --diff-এর মধ্যে পার্থক্য কী?

--check নির্ধারণ করে বাস্তবে কিছু execute হবে কি না। --diff নির্ধারণ করে আপনি কতটা বিস্তারিত তথ্য দেখবেন। একা --check ব্যবহার করলে শুধু জানা যায় যে একটি file পরিবর্তিত হবে। একা --diff ব্যবহার করলে পরিবর্তন প্রয়োগ হয় এবং কোন কোন line পরিবর্তিত হয়েছে তা দেখায়। পাঠযোগ্য dry run-এর জন্য দুটিকে একসঙ্গে ব্যবহার করুন। বাস্তব run-এর সময়ও --diff চালু রাখুন। এর জন্য ansible.cfg-এ [diff]-এর অধীনে always = true সেট করুন।

আমার Ansible task প্রতিটি run-এ changed report করে কেন?

কারণ module যে state পরিচালনা করে, সেটি দেখতে পারে না। অথবা আপনি যে value দিচ্ছেন, তা প্রতিবার আলাদা হচ্ছে। command এবং shell-এ changed সবসময় report হয়, যদি না আপনি creates বা changed_when যোগ করেন। state: touch-সহ file নকশা অনুযায়ী পরিবর্তন করে। যে template timestamp বা সদ্য তৈরি password render করে, সেটি প্রতিবার আলাদা byte তৈরি করে। তাই file-টি সত্যিই প্রতিবার rewrite হয়। Playbook পরপর 2 বার চালান। দ্বিতীয় pass-এও যা changed থাকে, সেটিই সংশোধন করার task।

Dry run-এর সময় আমার command এবং shell task skip হয় কেন?

কারণ নির্বিচারে চালানো কোনো command execute করার read-only পদ্ধতি নেই। Check mode-এ command module skipped: true সেট করে এবং Command would have run if not in check mode message দেখায়। File test-টি check mode-এ evaluate করার জন্য creates বা removes যোগ করুন। যে task শুধু state পড়ে, সেখানে changed_when: false-এর সঙ্গে check_mode: false সেট করুন। এতে dry run-এর সময় registered result-এ বাস্তব output থাকবে এবং এর ওপর নির্ভরশীল condition-গুলো কাজ করতে থাকবে।

নতুন server-এ check mode ব্যর্থ হয়, কিন্তু বিদ্যমান server-এ সফল হয় কেন?

কারণ check mode পরবর্তী task-গুলোর প্রয়োজনীয় state তৈরি করে না। nginx ছাড়া কোনো host-এ dry run চালালে install-টি changed হিসেবে report হয়। এরপর /etc/nginx/conf.d/-এ লেখার task-এ ব্যর্থ হয়, কারণ ওই directory কখনো তৈরি হয়নি। এটি প্রত্যাশিত আচরণ। যে host-এ playbook ইতিমধ্যে convergence সম্পন্ন করেছে, check mode তার drift শনাক্ত করে। এটি প্রথম run validate করতে পারে না। নতুন host-এ একটি machine-এ playbook apply করুন এবং দ্বিতীয় run-এর ফলাফল পরীক্ষা করুন।

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