اذهب إلى المحتوى

أتمتة إعداد خادم باستخدام أداة Ansible


Ola Abbas

تلعب عملية أتمتة الخادم server automation الآن دورًا أساسيًا في إدارة الأنظمة نظرًا لطبيعة بيئات التطبيقات الحديثة التي تُستخدَم لمرة واحدة ثم يمكنك التخلص منها، إذ تُستخدَم أدوات إدارة الضبط Configuration management مثل أداة Ansible لتبسيط عملية إعداد الخادم من خلال إنشاء إجراءات معيارية للخوادم الجديدة، مما يقلل من الأخطاء البشرية المرتبطة بالإعدادات اليدوية. لذا تقدّم أداة Ansible معمارية مبسَّطة لا تتطلب تثبيت برامج خاصة على العُقد، وتوفر مجموعة من الميزات والوحدات المبنية مسبقًا والتي تسهل كتابة سكربتات الأتمتة.

سيوضح هذا المقال كيفية إعداد ملف المخزون Inventory File وتنفيذ مجموعة من سكربتات الإعداد المسبَق Provisioning لأتمتة عملية إعداد خادم حزمة LEMP أو (Linux و ‎(E)nginx و MariaDB و PHP-FPM) على أوبنتو ونشر تطبيق لارافيل Laravel التجريبي على هذا النظام.

ملاحظة: يهدف هذا المقال إلى توضيح كيفية استخدام أدلة التشغيل Playbooks لأتمتة إعداد الخادم باستخدام أداة Ansible، ونشجعك على تعديل وتكييف الإعداد المضمَّن ليناسب احتياجاتك الخاصة بالرغم من أننا سنستخدم تطبيق لارافيل الذي يعمل على خادم LEMP.

المتطلبات الأساسية

ستحتاج ما يلي لمتابعة هذا المقال:

  • عقدة تحكم Ansible واحدة: وهي جهاز يعمل بنظام أوبنتو 22.04 مع تثبيت أداة Ansible عليه وضبطه للاتصال بمضيفات Ansible باستخدام مفاتيح SSH. تأكّد من أن عقدة التحكم لديها مستخدم عادي يمتلك أذونات مستخدم sudo (أذونات المستخدم الجذر) مع تفعيل جدار حماية، وتعلّم كيفية تثبيت وضبط Ansible على أوبنتو لإعداد الأداة Ansible.
  • مضيف Ansible واحد أو أكثر: هو خادم أوبنتو واحد أو أكثر، إذ يجب أن يكون لكل مضيفٍ المفتاح العام لعقدة التحكم الذي يُضاف إلى ملف authorized_keys. إن أردتَ استخدام أجهزة DigitalOcean Droplets الافتراضية بوصفها عقدًا، فيمكنك استخدام لوحة التحكم لإضافة مفتاحك العام إلى مضيفات Ansible.

الخطوة الأولى: نسخ المستودع التجريبي

يجب أولًا نسخ المستودع الذي يحتوي على سكربتات Ansible للإعداد المسبَق وتطبيق لارافيل التجريبي الذي سننشره على الخوادم البعيدة، حيث يمكن العثور على جميع الملفات الضرورية في مستودع جيت هَب do-community/ansible-laravel-demo.

انسخ المستودع بعد تسجيل الدخول إلى عقدة تحكم Ansible كمستخدم جذر sudo، وانتقل إلى المجلد الذي ينشئه الأمر git كما يلي:

git clone https://github.com/do-community/ansible-laravel-demo.git
cd ansible-laravel-demo

يمكنك الآن تشغيل الأمر ls لفحص محتويات المستودع المنسوخ كما يلي:

ls -l --group-directories-first

وسترى خرجًا يشبه التالي:

drwxrwxr-x 3 sammy sammy 4096 Mar 24 15:24 application
drwxrwxr-x 2 sammy sammy 4096 Mar 24 15:24 group_vars
drwxrwxr-x 7 sammy sammy 4096 Mar 24 15:24 roles
-rw-rw-r-- 1 sammy sammy  102 Mar 24 15:24 inventory-example
-rw-rw-r-- 1 sammy sammy 1987 Mar 24 15:24 laravel-deploy.yml
-rw-rw-r-- 1 sammy sammy  794 Mar 24 15:24 laravel-env.j2
-rw-rw-r-- 1 sammy sammy  920 Mar 24 15:24 readme.md
-rw-rw-r-- 1 sammy sammy  318 Mar 24 15:24 server-setup.yml

إليك نظرة عامة على المجلدات والملفات السابقة:

  • application/‎: يحتوي هذا المجلد على تطبيق لارافيل التجريبي الذي سننشره على الخادم البعيد في النهاية.
  • group_vars/‎: يحتوي هذا المجلد على ملفات المتغيرات التي تحتوي على خيارات مُخصَّصة لإعداد التطبيق مثل ثبوتيات Credentials قاعدة البيانات ومكان تخزين ملفات التطبيق على الخادم البعيد.
  • roles/‎: يحتوي هذا المجلد على أدوار Ansible المختلفة التي تعالج الإعداد المسبَق لخادم Ubuntu LEMP.
  • inventory-example: يمكن استخدام هذا الملف بوصفه قاعدةً لإنشاء مخزون مُخصَّص لبنيتك التحتية.
  • laravel-deploy.yml: دليل التشغيل الذي سينشر تطبيق لارافيل التجريبي على الخادم البعيد.
  • laravel-env.j2: يستخدم دليلُ التشغيل laravel-deploy.yml هذا القالب لإعداد ملف بيئة التطبيق.
  • readme.md: يحتوي هذا الملف على معلومات عامة حول الإعداد المسبَق المتضمن في هذا المستودع.
  • server-setup.yml: سيُعِدّ دليل التشغيل هذا مسبقًا خادم LEMP باستخدام الأدوار المُحدَّدة في المجلد roles/‎.

الخطوة الثانية: إعداد ملف المخزون واختبار الاتصال بالعقد

سننشئ الآن ملف مخزون لسرد المضيفين الذين نريد إدارتهم باستخدام أداة Ansible. انسخ أولًا الملف inventory-example إلى ملف جديد يسمى hosts:

cp inventory-example hosts

استخدم محرر النصوص الذي تريده لفتح ملف المخزون الجديد وحدّثه باستخدام خوادمك الخاصة، إذ سنستخدم في مثالنا محرر النصوص nano:

nano hosts

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

[dev]
203.0.113.0.101

[prod]
203.0.113.0.102

[all:vars]
ansible_python_interpreter=/usr/bin/python3

ملاحظة: يحدّد المتغير ansible_python_interpreter المسار إلى ملف بايثون التنفيذي على المضيف البعيد، ونطلب هناك من أداة Ansible أن تضبط هذا المتغير لجميع المضيفات في ملف المخزون.

احفظ وأغلق الملف عند الانتهاء، فإذا أردتَ استخدام محرر النصوص nano، فيمكنك ذلك عن طريق الضغط على الاختصار "CTRL+X" ثم نضغط "Y" وزر الادخال "ENTER" للتأكيد.

يمكنك بعد الانتهاء من ضبط ملف المخزون تنفيذ وحدة ping الخاصة بالأداة Ansible لاختبار ما إذا كانت عقدة التحكم قادرة على الاتصال بالمضيفين كما يلي:

ansible all -i hosts -m ping -u root

لنتعرّف على الأمر السابق بالتفصيل:

  • all: يخبر هذا الخيار أداة Ansible بتشغيل الأمر الذي يليه على جميع المضيفات من ملف المخزون المحدَّد.
  • ‎-i hosts: يحدد المخزون الذي يجب استخدامه، وإن لم يتوفّر هذا الخيار، فستحاول أداة Ansible استخدام المخزون الافتراضي الذي يوجد عادةً في المجلد ‎/etc/ansible/hosts.
  • ‎-m ping: سيؤدي هذا الأمر إلى تنفيذ وحدة ping الخاصة بأداة Ansible، والتي ستختبر الاتصال بالعقد وما إذا كان يمكن العثور على ملف بايثون التنفيذي على الأنظمة البعيدة أم لا.
  • ‎-u root: يحدّد هذا الخيار المستخدم البعيد الذي يجب استخدامه للاتصال بالعقد، إذ نستخدم حساب الجذر في مثالنا لأنه الحساب الوحيد المتاح على خوادم جديدة. يمكن أن تكون خيارات الاتصال الأخرى ضرورية بناءً على مزود البنية التحتية وضبط SSH.

إذا ضُبِط اتصال SSH بالعقد بصورة صحيحة، فستحصل على الخرج التالي:

203.0.113.0.101 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
203.0.113.0.102 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

تعني الاستجابة pong أن عقدة التحكم الخاصة بك قادرة على الاتصال بالعقد المُدارة، وأن أداة Ansible قادرة على تنفيذ أوامر بايثون على المضيفين البعيدين.

الخطوة الثالثة: إعداد ملفات المتغيرات

يجب أولًا قبل تشغيل أدلة التشغيل المُضمَّنة في مثالنا تعديلُ ملف المتغيرات الذي يحتوي على إعدادات مثل اسم المستخدم البعيد الذي سيُنشَأ وثبوتيات قاعدة البيانات لإعدادها باستخدام قاعدة بيانات MariaDB.

افتح الملف group_vars/all باستخدام محرر النصوص الذي تريده كما يلي:

nano group_vars/all.yml

يحتوي هذا الملف على المحتويات التالية:

---
# Initial Server Setup
remote_user: sammy

# MySQL Setup
mysql_root_password: MYSQL_ROOT_PASSWORD
mysql_app_db: travellist
mysql_app_user: travellist_user
mysql_app_pass: DB_PASSWORD

# Web Server Setup
http_host: "{{ ansible_facts.eth0.ipv4.address }}"
remote_www_root: /var/www
app_root_dir: travellist-demo
document_root: "{{ remote_www_root }}/{{ app_root_dir }}/public"

# Laravel Env Variables
app_name: Travellist
app_env: dev
app_debug: true
app_url: "http://{{ http_host }}"
db_host: localhost
db_port: 3306
db_database: "{{ mysql_app_db }}"
db_user: "{{ mysql_app_user }}"
db_pass: "{{ mysql_app_pass }}"

المتغيرات التي يجب معرفتها هي:

  • remote_user: سيُنشَأ المستخدم المُحدَّد على الخادم البعيد وسيُمنَح صلاحيات المستخدم الجذر sudo.
  • mysql_root_password: يحدّد هذا المتغير كلمة مرور قاعدة البيانات الجذر لخادم MariaDB، ولاحظ أنه يجب أن تكون كلمة مرور آمنة من اختيارك.
  • mysql_app_db: اسم قاعدة البيانات المُراد إنشاؤها لتطبيق لارافيل. لست بحاجة إلى تغيير هذه القيمة، ولكن لك الحرية في تغييرها إذا أردتَ ذلك، حيث ستُستخدَم هذه القيمة لإعداد ملف ضبط لارافيل ‎.env.
  • mysql_app_user: اسم مستخدم قاعدة البيانات لتطبيق لارافيل. لست بحاجة إلى تغيير هذه القيمة، ولكن لك الحرية في تغييرها إذا أردتَ ذلك.
  • mysql_app_pass: كلمة مرور قاعدة البيانات لتطبيق لارافيل، إذ يجب أن تكون كلمة مرور آمنة من اختيارك.
  • http_host: اسم النطاق أو عنوان IP للمضيف البعيد. نستخدم في مثالنا حقيقة Fact خاصة بأداة Ansible التي تحتوي على عنوان IPv4 لواجهة الشبكة eth0. إذا كان هناك أسماء نطاقات تؤشّر إلى مضيفاتك البعيدة، فيمكن أن ترغب في إنشاء ملفات متغيرات منفصلة لكل منها، وتعديل هذه القيمة ليحتوي ضبطُ خادم Nginx على اسم المضيف الصحيح لكل خادم.

احفظ الملف وأغلقه عندما تنتهي من تعديل هذه القيم.

إنشاء ملفات متغيرات إضافية لبيئات متعددة

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

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

cp group_vars/all.yml group_vars/production.yml
nano group_vars/production.yml

يحتوي ملف all.yml على القيم الافتراضية التي يجب أن تكون صالحة لجميع البيئات، لذا يمكنك إزالة جميع المتغيرات التي لن تحتاج إلى تغييرها من ملف production.yml الجديد. المتغيرات التي يجب تحديثها لكل بيئة هي:

  • prod_user
  • MYSQL_PROD_ROOT_PASSWORD
  • MYSQL_PROD_APP_PASSWORD
  • prod
  • false

وذلك في الشيفرة التالية:

---
# Initial Server Setup
remote_user: prod_user

# MySQL Setup
mysql_root_password: MYSQL_PROD_ROOT_PASSWORD
mysql_app_pass: MYSQL_PROD_APP_PASSWORD

# Laravel Env Variables
app_env: prod
app_debug: false

لاحظ أننا غيّرنا قيمة app_env إلى prod وضبطنا قيمة app_debug على false، وهذه هي إعدادات لارافيل الموصَى بها لبيئات الإنتاج.

احفظ الملف وأغلقه بعد الانتهاء من تخصيص متغيرات الإنتاج.

تشفير ملفات المتغيرات باستخدام ميزة Vault الخاصة بأداة Ansible

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

شغّل الأمر التالي لتشفير ملف متغيرات الإنتاج:

ansible-vault encrypt group_vars/production.yml

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

ansible-vault view group_vars/production.yml

سيُطلَب منك تقديم كلمة المرور نفسها التي حددتها عند تشفير هذا الملف باستخدام ansible-vault، ثم ستظهر محتويات الملف في طرفيتك Terminal بعد تقديم كلمة المرور، ويمكنك الخروج من عرض الملف من خلال الضغط على q.

استخدم الأمر edit التالي لتعديل ملف مُشفَّر مسبقًا باستخدام Ansible Vault:

ansible-vault edit group_vars/production.yml

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

انتهيت الآن من إعداد ملفات المتغيرات، وسنشغّل في الخطوة التالية دليل التشغيل لإعداد Nginx و PHP-FPM و MariaDB (والتي تشكل مع نظام التشغيل المستند إلى لينكس مثل أوبنتو حزمة LEMP) على الخادم أو الخوادم البعيدة.

الخطوة الرابعة: تنفيذ دليل تشغيل حزمة LEMP

يجب إعداد بيئة LEMP التي تخدّم التطبيق قبل نشر تطبيق لارافيل التجريبي على الخادم أو الخوادم البعيدة، إذ يتضمن دليل التشغيل server-setup.yml أدوار Ansible الضرورية لإعدادها. يمكنك فحص محتويات دليل التشغيل server-setup.yml من خلال تشغيل الأمر التالي:

cat server-setup.yml

وسيظهر الخرج التالي:

---
- hosts: all
  become: true
  roles:
    - { role: setup, tags: ['setup'] }

    - { role: mariadb, tags: ['mysql', 'mariadb', 'db', 'lemp'] }

    - { role: php, tags: ['php', 'web', 'php-fpm', 'lemp'] }

    - { role: nginx, tags: ['nginx', 'web', 'http', 'lemp'] }

    - { role: composer, tags: ['composer'] }

إليك نظرة عامة على جميع الأدوار المضمنة في دليل التشغيل السابق:

  • setup: يحتوي على المهام اللازمة لإنشاء مستخدم جديد للنظام ومنحه صلاحيات المستخدم الجذر sudo بالإضافة إلى تفعيل جدار الحماية ufw.
  • mariadb: يثبّت خادم قاعدة بيانات MariaDB وينشئ قاعدة بيانات ومستخدم التطبيق.
  • php: يثبّت وحدات php-fpm و PHP الضرورية لتشغيل تطبيق لارافيل.
  • nginx: يثبّت خادم الويب Nginx ويتيح الوصول إلى المنفذ 80.
  • composer: تثبيت مدير الحزم Composer على المستوى العام.

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

سينفّذ الأمر التالي دليل التشغيل على جميع الخوادم من ملف مخزونك، حيث يُعَد ‎--ask-vault-pass ضروريًا فقط في حالة استخدام ansible-vault لتشفير ملفات المتغيرات في الخطوة السابقة:

ansible-playbook -i hosts server-setup.yml -u root --ask-vault-pass

وستحصل على خرج يشبه ما يلي:

PLAY [all] **********************************************************************************************

TASK [Gathering Facts] **********************************************************************************
ok: [203.0.113.0.101]
ok: [203.0.113.0.102]

TASK [setup : Install Prerequisites] ********************************************************************
changed: [203.0.113.0.101]
changed: [203.0.113.0.102]

...

RUNNING HANDLER [nginx : Reload Nginx] ******************************************************************
changed: [203.0.113.0.101]
changed: [203.0.113.0.102]

PLAY RECAP **********************************************************************************************
203.0.113.0.101             : ok=31   changed=27   unreachable=0    failed=0    skipped=0    rescued=0    ignored=1   
203.0.113.0.102            : ok=31   changed=27   unreachable=0    failed=0    skipped=0    rescued=0    ignored=1  

أصبحت عقدتك (أو مجموعة عقدك) جاهزةً الآن لتخديم تطبيقات PHP باستخدام Nginx و PHP-FPM مع خادم قاعدة بيانات MariaDB، وسننشر في الخطوة التالية تطبيق لارافيل التجريبي المُضمَّن باستخدام دليل تشغيل Ansible الذي هو laravel-deploy.yml.

الخطوة الخامسة: نشر تطبيق لارافيل

أصبح لديك الآن بيئة LEMP تعمل على الخادم أو الخوادم البعيدة، فيمكنك تنفيذ دليل التشغيل laravel-deploy.yml الذي سينفّذ المهام التالية:

  1. إنشاء المستند الجذر للتطبيق على الخادم البعيد، إن لم يُنشَأ فعليًا.
  2. مزامنة مجلد التطبيق المحلي مع الخادم البعيد باستخدام الوحدة sync.
  3. استخدام الوحدة acl لضبط أذونات مستخدم www-data في مجلد التخزين.
  4. إعداد ملف التطبيق ‎.env بناءً على القالب laravel-env.j2.
  5. تثبيت اعتماديات التطبيق باستخدام مدير الحزم Composer.
  6. توليد مفتاح أمان التطبيق.
  7. إعداد رابط عام للمجلد storage.
  8. تشغيل عمليات تهجير Migration قاعدة البيانات والبذر Seeder.

يجب أن ينفِّذ مستخدمٌ غير جذر لديه أذونات sudo دليلَ التشغيل، ويجب أن يكون هذا المستخدم مُنشَأً عند تنفيذ دليل التشغيل server-setup.yml في الخطوة السابقة باستخدام الاسم الذي يحدّده المتغير remote_user.

شغّل دليل التشغيل laravel-deploy.yml باستخدام الأمر التالي:

ansible-playbook -i hosts laravel-deploy.yml -u sammy --ask-vault-pass

يُعَد ‎--ask-vault-pass ضروريًا فقط في حالة استخدام ansible-vault لتشفير ملفات المتغيرات في الخطوة السابقة.

وستحصل على خرج يشبه ما يلي:

PLAY [all] **********************************************************************************************

TASK [Gathering Facts] **********************************************************************************
ok: [203.0.113.0.101]
ok: [203.0.113.0.102]

TASK [Make sure the remote app root exists and has the right permissions] *******************************
ok: [203.0.113.0.101]
ok: [203.0.113.0.102]

TASK [Rsync application files to the remote server] *****************************************************
ok: [203.0.113.0.101]
ok: [203.0.113.0.102]

...

TASK [Run Migrations + Seeders] *************************************************************************
ok: [203.0.113.0.101]
ok: [203.0.113.0.102]

PLAY RECAP **********************************************************************************************
203.0.113.0.101             : ok=10   changed=9    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
203.0.113.0.102             : ok=10   changed=9    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

يمكنك عند انتهاء التنفيذ الوصول إلى التطبيق التجريبي من خلال توجيه متصفحك إلى اسم نطاق أو عنوان IP الخاص بعقدتك:

http://node_domain_or_IP

وسترى صفحة تشبه ما يلي:

01_travellist_version1-0.png

الخلاصة

أوضح هذا المقال كيفية إعداد ملف مخزون الأداة Ansible والاتصال بالعقد البعيدة، وكيفية تشغيل أدلة تشغيل Ansible لإعداد خادم LEMP ونشر تطبيق لارافيل التجريبي عليه. اطّلع على مستودع جيت هَب التجريبي الذي يحتوي على جميع الملفات الضرورية لمتابعة العمل.

ترجمة -وبتصرُّف- للمقال Automating Server Setup with Ansible: A DigitalOcean Workshop Kit لصاحبته Erika Heidi.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...