Ansible Check Mode: راجع تغييرات الـ VM قبل التنفيذ
هتكسب من المقال ده طريقة عملية تمنع تغيير إعدادات NGINX أو SSH على كل الـ VMs قبل ما تشوف بالظبط إيه اللي هيتغير.
مستوى القارئ: متوسط
المشكلة باختصار
الطريقة الشائعة الغلط إنك تعدل ملف config على VM واحدة، وبعدها تنسخ نفس التغيير يدويًا أو تشغل playbook مباشرة على كل السيرفرات. الطريقة دي بتفشل لما template صغير يطلع فيه typo، أو لما شرط في playbook يشتغل على group أكبر من المتوقع.
الافتراض إن عندك 5 إلى 40 VM، وتستخدم Ansible لإدارة ملفات مثل /etc/nginx/nginx.conf أو /etc/ssh/sshd_config. في الحالة دي، هدفك مش إن Ansible ينفذ أسرع فقط. هدفك إنك تعرف التغيير قبل التنفيذ.
مثال بسيط: قبل ما تفتح gzip على كل السيرفرات
ركز في المثال ده. عندك موقع على 8 VMs خلف load balancer. عايز تضيف gzip في NGINX. التغيير نفسه صغير، لكن الخطأ هيقع على كل السيرفرات لو شغلت playbook مباشرة.
بدل ما تنفذ فورًا، اعمل playbook ينسخ template، ثم شغله أولًا بـ --check --diff. حسب توثيق Ansible الرسمي، check mode يحاكي التنفيذ بدون تغيير الأنظمة البعيدة، وdiff mode يعرض مقارنة قبل وبعد للملفات المدعومة.
# playbooks/nginx.yml
- name: Manage NGINX config safely
hosts: web
become: true
tasks:
- name: Render nginx main config
ansible.builtin.template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: "0644"
notify: Reload nginx
handlers:
- name: Reload nginx
ansible.builtin.service:
name: nginx
state: reloaded
الخطوات العملية في CI أو على جهازك
- اكتب التغيير في branch، وليس على السيرفر مباشرة.
- شغل محاكاة على سيرفر واحد فقط عشان تقلل الضوضاء.
- راجع الـ diff. لو ظهر تغيير غير مقصود، ارجع للـ template.
- نفذ على VM واحدة كـ canary.
- بعد 10 دقائق مراقبة، نفذ على باقي المجموعة.
# 1) راجع التغيير بدون تعديل فعلي
ansible-playbook -i inventory.ini playbooks/nginx.yml \
--check --diff --limit web-01
# 2) لو diff واضح ومقبول، نفذ على VM واحدة
ansible-playbook -i inventory.ini playbooks/nginx.yml \
--limit web-01
# 3) بعد مراقبة logs و 5xx، نفذ على باقي السيرفرات
ansible-playbook -i inventory.ini playbooks/nginx.yml \
--limit webلو عندك 12 VM، تشغيل dry-run على VM واحدة قد يأخذ 20 إلى 40 ثانية. ده أبطأ من التنفيذ المباشر بنصف دقيقة تقريبًا، لكنه أرخص من 45 دقيقة debugging بعد تعطل reload على المجموعة كلها.
الـ trade-off هنا
المكسب إنك بتحوّل التغيير من مفاجأة على production إلى diff قابل للمراجعة. كمان بتقدر تراجع PR وفيه output واضح بدل كلام عام عن “تعديل NGINX”.
التكلفة إن check mode ليس حقيقة كاملة. بعض modules لا تعطي نتيجة دقيقة، وبعض tasks تعتمد على نتائج مسجلة من tasks سابقة. توثيق Ansible يذكر أن check mode مجرد simulation، وقد لا يولد output مفيدًا في حالات تعتمد على registered variables. لذلك لا تعتبره بديلًا عن canary execution.
في ملفات فيها أسرار، لا تشغل --diff بدون تفكير. Ansible يدعم تعطيل diff على task محددة باستخدام diff: false. استخدمها مع templates التي تحتوي tokens أو passwords.
- name: Render secret config without leaking diff
ansible.builtin.template:
src: secret.conf.j2
dest: /etc/app/secret.conf
mode: "0600"
diff: falseسيناريو واقعي بأرقام
لو عندك موقع بـ 50K زائر يوميًا و8 VMs، خطأ reload في NGINX ممكن يظهر كـ 5xx خلال دقيقة. بدون بوابة مراجعة، غالبًا هتكتشف المشكلة من alert بعد 3 إلى 5 دقائق، ثم تبدأ rollback يدوي. متوسط الوقت الواقعي هنا ممكن يوصل 45 دقيقة من أول commit لحد الاستقرار.
مع check mode وcanary، الخطأ الشائع يظهر في diff أو على VM واحدة. القياس المحافظ: 7 دقائق لاكتشاف typo في template، و12 دقيقة لو احتجت canary فعلي. الرقم تقديري، لكنه مبني على فرق واضح: أنت بتفشل قبل الانتشار، مش بعده.
متى لا تستخدم هذه الطريقة
لا تعتمد على check mode وحده لو التغيير فيه migrations، أو commands بتغير state خارجي، أو tasks تستخدم APIs لا تدعم dry-run. لا تستخدم --diff على أسرار أو ملفات credentials. ولا تطبق playbook على كل السيرفرات مباشرة لمجرد إن dry-run طلع نظيف؛ dry-run يقلل المخاطرة، لكنه لا يلغي اختبار canary.
مصادر
- Ansible: Validating tasks with check mode and diff mode
- Ansible Inventory Guide
- ansible.builtin.template module
الخطوة التالية
افتح آخر playbook بيعدل ملف config عندك، وشغله مرة واحدة بـ --check --diff --limit اسم_سيرفر_واحد. لو الـ diff مش مفهوم في أقل من دقيقتين، أصلح الـ template قبل ما تضيف أي automation جديدة.