تكوين إدارة 101: كتابة سيناريوهات Ansible

المقدمة

باختصار، إدارة تكوين الخادم (المشار إليها أيضًا باسم الأتمتة في تكنولوجيا المعلومات) هي حلا لتحويل إدارة البنية التحتية الخاصة بك إلى قاعدة بيانات، تصف جميع العمليات الضرورية لنشر خادم في مجموعة من السكربتات التموينية التي يمكن إصدارها بإصدار واستخدامها بسهولة. يمكن أن تحسن بشكل كبير نزاهة أي بنية تحتية للخادم مع مرور الوقت.

في الدليل السابق، تحدثنا عن الفوائد الرئيسية لتنفيذ استراتيجية إدارة التكوين لبنية تحتية للخادم الخاصة بك، وكيفية عمل أدوات إدارة التكوين، وما الذي يتشابه بهذه الأدوات بشكل عام.

سيقوم هذا الجزء من السلسلة بإرشادك خلال عملية أتمتة توفير الخادم باستخدام Ansible، أداة إدارة التكوين التي توفر إطار عمل تلقائي كامل وقدرات تنظيم، مع الحفاظ على هدف البساطة النهائية والحد الأدنى من الوحدات. سنركز على مصطلحات اللغة والبناء الجملي والميزات اللازمة لإنشاء مثال مبسط لتوفير الخادم Ubuntu 18.04 بشكل تلقائي باستخدام Apache.

تحتوي القائمة التالية على جميع الخطوات التي نحتاج إلى أتمتتها لتحقيق هدفنا:

  1. تحديث ذاكرة التخزين المؤقت لـ apt
  2. تثبيت Apache
  3. إنشاء دليل جذر مستند مخصص
  4. ضع ملف index.html في الجذر المخصص للمستندات
  5. قم بتطبيق قالب لإعداد خادم الاستضافة الظاهري المخصص
  6. أعد تشغيل Apache

سنبدأ بالنظر في المصطلحات المستخدمة بواسطة Ansible، تليها نظرة عامة على الميزات الرئيسية للغة التي يمكن استخدامها لكتابة الـ Playbooks. في نهاية الدليل، ستجد محتويات مثال كامل للتوفيق لتلقيم الخطوات الموضحة لإعداد Apache على Ubuntu 18.04.

ملاحظة: يهدف هذا الدليل إلى إلمامك بلغة Ansible وكيفية كتابة الـ Playbooks لتوفير تلقيم الخادم الخاص بك. للحصول على رؤية مقدمة أكثر عن Ansible، بما في ذلك الخطوات اللازمة لتثبيت والبدء في استخدام هذه الأداة، وكذلك كيفية تشغيل أوامر وـ Playbooks Ansible، تحقق من كيفية تثبيت وتكوين Ansible على Ubuntu 18.04 دليلنا.

البدء

قبل أن نتمكن من الانتقال إلى رؤية عملية أكثر حيوية لـ Ansible، من المهم أن نتعرف على المصطلحات والمفاهيم الهامة التي قدمتها هذه الأداة.

المصطلحات

القائمة التالية تحتوي على نظرة عامة سريعة على أكثر المصطلحات ذات الصلة المستخدمة في Ansible:

  • العقدة الرئيسية: الجهاز الذي تم تثبيت Ansible عليه، المسؤول عن تشغيل التوفير على الخوادم التي تديرها.
  • الجرد: ملف INI يحتوي على معلومات حول الخوادم التي تديرها.
  • دفتر اللعب: ملف YAML يحتوي على سلسلة من الإجراءات التي يجب أن تُؤتمن.
  • المهمة: كتلة تحدد إجراءً واحدًا يجب تنفيذه، مثلاً: تثبيت حزمة.
  • الوحدة: تجريبة عادة ما تجري مهمة النظام، مثل التعامل مع الحزم أو إنشاء وتغيير الملفات. تحتوي Ansible على العديد من الوحدات المضمنة، ولكن يمكنك أيضًا إنشاء وحدات مخصصة.
  • الدور: مجموعة من الدفاتر اللعب، والقوالب، وغيرها من الملفات ذات الصلة، منظمة بطريقة محددة مسبقًا لتسهيل إعادة الاستخدام والمشاركة.
  • اللعبة: التوفير المُنفَّذ من البداية إلى النهاية يُسمى لعبة.
  • الحقائق: متغيرات عامة تحتوي على معلومات حول النظام، مثل واجهات الشبكة أو نظام التشغيل.
  • المعالجون: تُستخدم لتحفيز تغييرات حالة الخدمة، مثل إعادة تشغيل أو إعادة تحميل خدمة.

تنسيق المهمة

A task defines a single automated step that should be executed by Ansible. It typically involves the usage of a module or the execution of a raw command. This is how a task looks:

- name: This is a task
  apt: name=vim state=latest

الجزء name في الواقع اختياري، ولكن يُوصى به، حيث يظهر في ناتج التوفير عند تنفيذ المهمة. الجزء apt هو جزء من وحدة Ansible المدمجة التي تجرد إدارة الحزم على توزيعات Debian. تُخبر مهمة المثال هذه Ansible أنه يجب تغيير حالة الحزمة vim إلى latest، مما سيؤدي إلى تثبيت هذه الحزمة في حالة عدم تثبيتها بعد.

تنسيق السيناريو

السيناريوهات هي ملفات YAML تحتوي على سلسلة من التوجيهات لتوفير الخادم تلقائيًا. يُعتبر المثال التالي سيناريو بسيط يُنفذ مهمتين: تحديث ذاكرة التخزين المؤقت لـ apt وتثبيت vim بعد ذلك:

---
- hosts: all
  become: true
  tasks:
     - name: Update apt-cache 
       apt: update_cache=yes

     - name: Install Vim
       apt: name=vim state=latest

يعتمد YAML على التأشير لتسلسل هياكل البيانات. لهذا السبب، عند كتابة السيناريوهات وخصوصًا عند نسخ الأمثلة، يجب عليك أن تكون حذرًا إضافيًا للحفاظ على التأشير الصحيح.

قبل نهاية هذا الدليل، سنرى مثالًا أكثر واقعية على سيناريو، مشروحًا بالتفصيل. سيقدم القسم التالي نظرة عامة على العناصر والميزات الأكثر أهمية التي يمكن استخدامها لكتابة سيناريوهات Ansible.

كتابة السيناريوهات

الآن بما أنك ملم بالمصطلحات الأساسية وتنسيق عموم السيناريوهات والمهام في Ansible، سنتعلم بعض ميزات السيناريوهات التي يمكن أن تساعدنا في إنشاء أتمتة أكثر تنوعًا.

العمل مع المتغيرات

هناك طرق مختلفة يمكنك استخدامها لتعريف المتغيرات في Ansible. أبسط طريقة هي باستخدام قسم vars في السيناريو. يقوم المثال أدناه بتعريف متغير package الذي يُستخدم فيما بعد داخل مهمة:

---
- hosts: all
  become: true
  vars:
     package: vim
  tasks:
     - name: Install Package
       apt: name={{ package }} state=latest

المتغير package لديه نطاق عالمي، مما يعني أنه يمكن الوصول إليه من أي نقطة في التوفير، حتى من الملفات المضمنة والقوالب.

استخدام الحلقات

تُستخدم الحلقات عادةً لتكرار مهمة باستخدام قيم إدخال مختلفة. على سبيل المثال، بدلاً من إنشاء 10 مهام لتثبيت 10 حزم مختلفة، يمكنك إنشاء مهمة واحدة واستخدام حلقة لتكرار المهمة مع جميع الحزم المختلفة التي تريد تثبيتها.

لإنشاء حلقة داخل مهمة، قم بتضمين الخيار with_items مع مصفوفة القيم. يمكن الوصول إلى المحتوى من خلال المتغير item للحلقة، كما هو موضح في المثال أدناه:

- name: Install Packages
  apt: name={{ item }} state=latest
  with_items:
     - vim
     - git
     - curl  

يمكنك أيضًا استخدام متغير مصفوفة لتعريف عناصرك:

---
- hosts: all
  become: true
  vars:
     packages: [ 'vim', 'git', 'curl' ]
  tasks:
     - name: Install Package
       apt: name={{ item }} state=latest
       with_items: "{{ packages }}"

استخدام الشروط

الشروط يمكن استخدامها لتقرر بشكل ديناميكي ما إذا كان يجب تنفيذ مهمة معينة أم لا، بناءً على متغير أو ناتج من أمر، على سبيل المثال.

المثال التالي سيقوم بإيقاف تشغيل الأنظمة المبنية على Debian فقط:

- name: Shutdown Debian Based Systems
  command: /sbin/shutdown -t now
  when: ansible_os_family == "Debian"

الشرط when يستقبل كمعامل تعبير يجب تقييمه. يتم تنفيذ المهمة فقط في حال تقييم التعبير إلى true. في مثالنا، اختبرنا الحقيقة للتحقق مما إذا كان نظام التشغيل من عائلة Debian أم لا.

A common use case for conditionals in IT automation is when the execution of a task depends on the output of a command. With Ansible, the way we implement this is by registering a variable to hold the results of a command execution, and then testing this variable in a subsequent task. We can test for the command’s exit status (if failed or successful). We can also check for specific contents inside the output, although this might require the usage of regex expressions and string parsing commands.

المثال التالي يوضح مهامًا مشروطة اثنتين استنادًا إلى ناتج من أمر php -v. سنختبر نتيجة الخروج من الأمر، لأننا نعلم أنه سيفشل في التنفيذ في حالة عدم تثبيت PHP على هذا الخادم. الجزء ignore_errors من المهمة مهم لضمان استمرار توفير الخدمة حتى عند فشل تنفيذ الأمر.

- name: Check if PHP is installed
  register: php_installed
  command: php -v
  ignore_errors: true

- name: This task is only executed if PHP is installed
  debug: var=php_install
  when: php_installed|success
  
- name: This task is only executed if PHP is NOT installed
  debug: msg='PHP is NOT installed'
  when: php_installed|failed

الوحدة debug المستخدمة هنا هي وحدة مفيدة لعرض محتويات المتغيرات أو رسائل التصحيح. يمكنها إما طباعة سلسلة نصية (عند استخدام المعامل msg) أو طباعة محتويات متغير (عند استخدام المعامل var).

العمل مع القوالب

القوالب عادة ما تُستخدم لإعداد ملفات التكوين، مما يتيح استخدام المتغيرات وميزات أخرى تهدف إلى جعل هذه الملفات أكثر مرونة وإعادة استخدامًا. يستخدم Ansible محرك النموذج Jinja2.

مثال التالي هو قالب لإعداد مضيف افتراضي لأباتشي، باستخدام متغير لإعداد مجلد المستندات الخاص بهذا المضيف:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot {{ doc_root }}

    <Directory {{ doc_root }}>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

يتم استخدام الوحدة المدمجة template لتطبيق القالب من مهمة. إذا كنت قد أطلقت اسمًا على ملف القالب أعلاه vhost.tpl، ووضعته في نفس دليل المهمة الخاصة بك، هكذا يمكنك تطبيق القالب لاستبدال المضيف الافتراضي لأباتشي:

- name: Change default Apache virtual host
  template: 
    src: vhost.tpl
    dest: /etc/apache2/sites-available/000-default.conf

تحديد وتشغيل المعالجين

يُستخدم المعالجون لتشغيل تغيير حالة في خدمة ما، مثل إعادة التشغيل أو التوقف. على الرغم من أنها قد تبدو مماثلة إلى حد ما للمهام العادية، إلا أن المعالجين لا يُنفَذون إلا عندما يتم تنشيطهم مسبقًا من خلال توجيه notify في مهمة. عادة ما يتم تعريفها كمصفوفة في قسم handlers في المخطط، لكن يمكن أيضًا أن توجد في ملفات منفصلة.

دعونا نأخذ في اعتبارنا مثال استخدام القالب السابق الخاص بنا، حيث قمنا بإعداد مضيف افتراضي لأباتشي. إذا كنت ترغب في التأكد من إعادة تشغيل أباتشي بعد تغيير المضيف الافتراضي، فيجب عليك أولاً إنشاء معالج لخدمة أباتشي. هكذا يتم تعريف المعالجين داخل المخطط:

handlers:
    - name: restart apache
      service: name=apache2 state=restarted
    
    - name: other handler
      service: name=other state=restarted

التوجيه name هنا مهم لأنه سيكون المعرف الفريد لهذا المعالج. لتنشيط هذا المعالج من مهمة، يجب عليك استخدام الخيار notify:

- name: Change default Apache virtual host
  template: 
    src: vhost.tpl
    dest: /etc/apache2/sites-available/000-default.conf
  notify: restart apache

لقد رأينا بعض أهم الميزات التي يمكنك استخدامها لبدء كتابة السيناريوهات في Ansible. في القسم التالي، سنقوم بالانغماس في مثال أكثر واقعية لسيناريو يقوم بتثبيت وتكوين أباتشي على أوبونتو.

سيناريو مثالي

الآن دعنا نلقي نظرة على سيناريو سيقوم بتثبيت خادم الويب أباتشي داخل نظام أوبونتو 18.04، كما تم مناقشته في مقدمة هذا الدليل.

يمكن العثور على المثال الكامل، بما في ذلك ملف النموذج لإعداد أباتشي وملف HTML ليتم تقديمه بواسطة خادم الويب، على Github. يحتوي المجلد أيضًا على ملف Vagrantfile يتيح لك اختبار السيناريو في إعداد مبسط، باستخدام جهاز افتراضي يتم إدارته بواسطة Vagrant.

محتويات السيناريو

يتوفر محتوى السيناريو الكامل هنا لراحتك:

playbook.yml
  1. ---
  2. - hosts: all
  3. become: true
  4. vars:
  5. doc_root: /var/www/example
  6. tasks:
  7. - name: Update apt
  8. apt: update_cache=yes
  9. - name: Install Apache
  10. apt: name=apache2 state=latest
  11. - name: Create custom document root
  12. file: path={{ doc_root }} state=directory owner=www-data group=www-data
  13. - name: Set up HTML file
  14. copy: src=index.html dest={{ doc_root }}/index.html owner=www-data group=www-data mode=0644
  15. - name: Set up Apache virtual host file
  16. template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
  17. notify: restart apache
  18. handlers:
  19. - name: restart apache
  20. service: name=apache2 state=restarted

لنفحص كل جزء من هذا السيناريو بمزيد من التفصيل:

المضيفون: الكل
الدفتر اللعب يبدأ بالبيان أنه يجب تطبيقه على الكل من المضيفين في جدول التخزين الخاص بك (المضيفون: الكل). يمكن تقييد تنفيذ الدفتر اللعب إلى مضيف معين، أو مجموعة من المضيفين. يمكن كتابة هذا الخيار في وقت التنفيذ.

تصبح: صحيح
الجزء تصبح: صحيح يخبر أنسيبل بتفويض الامتيازات (سودو) لتنفيذ جميع المهام في هذا الدفتر اللعب. يمكن كتابة هذا الخيار على أساس مهمة بمهمة.

متغيرات
يعرف متغيرًا، doc_root، الذي يُستخدم لاحقًا في مهمة. يمكن أن يحتوي هذا القسم على متغيرات متعددة.

المهام
القسم الذي يتم فيه تحديد المهام الفعلية. تحديث الخطوة الأولى آبت التخزين المؤقت، والخطوة الثانية تثبيت حزمة apache2.

المهمة الثالثة تستخدم الوحدة المدمجة ملف لإنشاء دليل لخدمة جذور المستندات لدينا. يمكن استخدام هذه الوحدة لإدارة الملفات والدلائل.

المهمة الرابعة تستخدم الوحدة نسخ لنسخ ملف محلي إلى الخادم البعيد. نحن ننسخ ملف HTML بسيط ليتم تقديمه كموقع ويب يتم استضافته بواسطة أباتشي.

المعالجون
أخيرًا، لدينا القسم المعالجون حيث يتم تعريف الخدمات. نحدد المعالج إعادة تشغيل أباتشي الذي يتم إشعاره من المهمة الرابعة، حيث يتم تطبيق قالب أباتشي.

تشغيل السيناريو

بمجرد الحصول على محتويات هذا السيناريو المُنزّل إلى جهاز التحكم في Ansible الخاص بك، يمكنك استخدام ansible-playbook لتنفيذه على أحد أو أكثر من العُقد في مخزونك. الأمر التالي سينفذ السيناريو على جميع الخوادم من ملف المخزون الافتراضي الخاص بك، باستخدام مصادقة مفتاح SSH للاتصال كمستخدم النظام الحالي:

  1. ansible-playbook playbook.yml

يمكنك أيضًا استخدام -l لتحديد التنفيذ إلى مضيف واحد أو مجموعة من المضيفين من مخزونك:

  1. ansible-playbook -l host_or_group playbook.yml

إذا كنت بحاجة إلى تحديد مستخدم SSH مختلف للاتصال بالخادم عن بُعد، يمكنك تضمين الوسيطة -u user في تلك الأمر:

  1. ansible-playbook -l host_or_group playbook.yml -u remote-user

لمزيد من المعلومات حول كيفية تشغيل أوامر وسيناريوهات Ansible، يرجى الرجوع إلى دليلنا حول كيفية تثبيت وتكوين Ansible على Ubuntu 18.04.

الاستنتاج

أنسيبل هو أداة تحكم في تقنيات المعلومات بسيطة تتميز بمنحنى تعلم منخفض، وتستخدم YAML لكتابة نصوص التوفير. تحتوي على عدد كبير من الوحدات المضمنة التي يمكن استخدامها لتجريد المهام مثل تثبيت الحزم والعمل مع القوالب. متطلبات البنية التحتية المبسطة واللغة البسيطة يمكن أن تكون مناسبة جيدًا لأولئك الذين يبدؤون في إدارة التكوين. ومع ذلك، قد تفتقر إلى بعض الميزات المتقدمة التي يمكن العثور عليها في أدوات أكثر تعقيدًا مثل Puppet و Chef.

في الجزء المقبل من هذه السلسلة، سنرى نظرة عامة عملية لـ Puppet، وهي أداة إدارة تكوين شهيرة وموثوقة تستخدم لغة برمجة مخصصة قوية ومعبّرة تعتمد على Ruby لكتابة نصوص التوفير.

Source:
https://www.digitalocean.com/community/tutorials/configuration-management-101-writing-ansible-playbooks