المتغيرات والحقائق والقوالب
المتغيرات والحقائق والقوالب
الأوامر المباشرة والدفاتر الثابتة لن تأخذك بعيداً. في اللحظة التي تحتاج فيها إلى نفس الدفتر لضبط جهاز التطوير بشكل مختلف عن جهاز الإنتاج — حدود ذاكرة مختلفة، ونقاط وصول مختلفة، وشهادات TLS مختلفة — تحتاج إلى متغيرات. وفي اللحظة التي تحتاج فيها إلى كتابة ملف إعداد يعتمد محتواه على مقدار الذاكرة الفعلية أو عنوان IP للمضيف المستهدف، تحتاج إلى قوالب Jinja2. وحين تكتشف Ansible تلقائياً طبيعة المضيف دون أن تُشفّر أي شيء يدوياً — هذه هي الحقائق.
هذه الآليات الثلاث هي محرك Ansible الإنتاجي في أي مؤسسة هندسية جادة. إتقان تفاعلها، وخاصة ترتيب الأولوية بينها، يمنع فئات كاملة من الأخطاء.
أولوية المتغيرات — المكدّس الكامل
تدمج Ansible المتغيرات من مصادر عديدة. عندما يظهر نفس اسم المتغير في أكثر من مكان، تطبّق Ansible سلسلة أولوية صارمة: المصدر الأعلى في القائمة يكسب. من أدنى إلى أعلى أولوية:
- الإعدادات الافتراضية للأدوار (
roles/myrole/defaults/main.yml) - متغيرات المجموعة في ملف الجرد أو السكريبت
- ملفات
group_vars/allفي الجرد - ملفات
group_vars/<groupname>في الجرد - ملفات
host_vars/<hostname>في الجرد - حقائق المضيف (تُجمع تلقائياً)
- متغيرات اللعبة (مفتاح
vars:في الدفتر) vars_files:وvars_prompt:في اللعبة- متغيرات الأدوار (
roles/myrole/vars/main.yml) - متغيرات الكتل والمهام (
vars:على مهمة) - متغيرات الإدراج (
include_vars) - نتائج
set_fact/register - المتغيرات الإضافية (
-e/--extra-varsعلى سطر الأوامر) — أعلى أولوية، تكسب دائماً
roles/myrole/vars/main.yml (الأولوية 9) يتجاوز بصمت كل شيء تحته، بما في ذلك group_vars. إذا ضبط دور ما قيمة nginx_worker_processes في vars/main.yml، سيُتجاهل إعدادك على مستوى الجرد بصمت. ضع دائماً القيم القابلة للتعديل من قِبل المشغل في defaults/main.yml؛ استخدم vars/main.yml فقط للثوابت الداخلية للدور التي لا يحتاج المشغلون لمسّها.
النموذج الذهني العملي على نطاق المؤسسات الكبيرة: الإعدادات الافتراضية هي "الخط الأساسي الآمن"، group_vars وhost_vars هي "طبقة البيئة"، و-e على سطر الأوامر هي "التجاوز الطارئ". يجب ألا تستخدم خطوط CI المتغيرات -e للترقية العادية؛ هذا مخرج بشري للطوارئ.
تعريف المتغيرات — الجرد وgroup_vars وhost_vars
التخطيط المفضل لأي جرد إنتاجي هو مجلد، لا ملف مسطح. هذا يتوسع بشكل نظيف ويتيح تجاوزات لكل مجموعة ولكل مضيف في ملفات منفصلة قابلة للمراجعة.
داخل الدفتر، تُشير إلى أي متغير بقوسين معقوفين مزدوجين: {{ app_port }}. تحل Ansible القيمة في وقت التشغيل بعد تطبيق سلسلة الأولوية الكاملة.
group_vars كما هو موضح، لذا يظل النمط متسقاً.
الحقائق المجمّعة — ذكاء مجاني عن المضيف
عندما تتصل Ansible بمضيف وgather_facts: true (الإعداد الافتراضي)، تُشغّل وحدة setup التي تجمع مئات الحقائق عن الهدف: عائلة نظام التشغيل، إصدار النواة، إجمالي الذاكرة، عدد المعالجات، جميع عناوين IP، أنظمة الملفات المركّبة، نوع الافتراضية، والمزيد. كل هذه المعلومات متاحة كمتغيرات بادئتها ansible_.
الحقائق الأساسية التي ستستخدمها باستمرار في دفاتر الإنتاج:
ansible_os_family— "Debian" أو "RedHat" أو "Archlinux" — استخدمها للتثبيت الشرطي للحزمansible_memtotal_mb— إجمالي الذاكرة؛ اشتق منه حدود كومة JVM أو عمال Nginxansible_processor_vcpus— عدد المعالجات؛ ضعnginx_worker_processesتلقائياًansible_default_ipv4.address— عنوان IP الأساسي؛ استخدمه في ملفات الإعداد وقواعد الجدار الناريansible_hostname/ansible_fqdn— هوية المضيفansible_distribution/ansible_distribution_version— نظام التشغيل الدقيق وإصداره
/etc/ansible/facts.d/ على العقدة المُدارة (اسم الملف ينتهي بـ.fact). تظهر تحت ansible_local. تستخدم الفرق هذا لتسجيل طوابع زمنية للنشر وإصدارات التطبيقات ومعرّفات البيئات — كلها قابلة للاستعلام في تشغيلات الدفتر اللاحقة.
يضيف جمع الحقائق نحو 0.5 إلى 2 ثانية لكل مضيف. على نطاق 1,000 مضيف هذا ملحوظ. يمكنك تعطيل الجمع كلياً بـgather_facts: false في رأس اللعبة للدفاتر السريعة جداً التي لا تحتاج معلومات النظام، أو تخزين الحقائق مؤقتاً في Redis أو ملف JSON بـfact_caching في ansible.cfg.
قوالب Jinja2 — ملفات الإعداد التي تعرف مضيفها
وحدة template تنسخ ملفاً من المتحكم إلى العقدة المُدارة، لكنها قبل النسخ تُمرّر المحتوى عبر Jinja2. كل تعبير {{ متغير }} يُوسَّع، وكل كتلة {% if %} أو {% for %} تُقيَّم. النتيجة ملف نصي مُصيَّر بالكامل — إعداد Nginx، أو ملف خيارات JVM، أو وحدة systemd، أو إعداد استخلاص Prometheus — صحيح تماماً لذلك المضيف بعينه.
ملفات مصدر القوالب تعيش في مجلد templates/ للدور وتحمل اصطلاحاً امتداد .j2. مهمة الدفتر تبدو هكذا:
هذا القالب الواحد ينتج إعداد Nginx مُضبوطاً بدقة على كل مضيف ويب: عدد العمال يتطابق مع المعالج الفعلي، كتلة upstream تُبنى من القائمة الحية لمضيفي مجموعة التطبيق، واسم الخادم هو FQDN الحقيقي — كل هذا دون أن ينظر أي إنسان لتلك القيم.
مرشّحات Jinja2 — تحويل القيم
يأتي Jinja2 مع مكتبة غنية من المرشّحات تتيح لك تحويل قيم المتغيرات بشكل مضمّن. تضيف Ansible عشرات المرشّحات الإضافية. الأكثر فائدة في الإنتاج:
{{ nginx_worker_processes | default(4) }}— قيمة افتراضية آمنة عند احتمال عدم تعريف المتغير{{ app_name | upper }}— معالجة النصوص{{ ansible_memtotal_mb * 0.75 | int }}— حسابات؛ اشتق-XmxلـJVM من الذاكرة الفعلية{{ groups['app'] | length }}— عدّ المضيفين في مجموعة{{ my_list | join(',') }}— دمج قائمة لقيمة إعداد مفصولة بفواصل{{ secret_value | b64encode }}— ترميز base64 لبيان Kubernetes secret
set_fact — متغيرات ديناميكية في وقت التشغيل
أحياناً تحتاج إلى حساب متغير من مزيج من الحقائق ثم إعادة استخدامه عبر مهام متعددة. ansible.builtin.set_fact يُسند متغيراً في وقت التشغيل بنفس أولوية نتيجة register:
lineinfile لتعديل قيمة واحدة في ملف إعداد نصّبته حزمة. هذا هشّ — ترقية الحزمة قد تعيد الملف الأصلي وتتراجع عن تعديلك بصمت. النمط الإنتاجي: انشر ملف الإعداد كاملاً من قالب Jinja2 حتى تكون كل قيمة تحت سيطرتك مُتتبَّعة بالإصدار ومُطبَّقة بشكل صرفي في كل تشغيل.
الخلاصة الإنتاجية
في أي مؤسسة هندسية جادة تُشغّل Ansible على نطاق واسع، هذه الممارسات غير قابلة للتفاوض: ضع القيم القابلة للتعديل في defaults/ الأدوار حتى يتمكن المشغلون من تجاوزها؛ ضع تراكبات البيئة في group_vars/ وhost_vars/؛ اشتق قيم الإعداد من الحقائق المجمّعة حتى تتكيف دفاترك تلقائياً مع الأجهزة الفعلية؛ اكتب قوالب Jinja2 تمتلك ملف الإعداد بالكامل بدلاً من تعديل الأسطر الفردية؛ وتحقق دائماً من القالب المُصيَّر مقارنةً بمرجع معروف قبل النشر في الإنتاج.