آشنایی با Ansible (اختیاری)

بخش اختیاری

این بخش اختیاری است و برای دانشجویانی است که می‌خواهند با Configuration Management و ابزارهای declarative آشنا شوند. البته اختیاری بودن به معنای کم اهمیت بودن نیست؛ در دنیای واقعی، ابزارهایی مثل Ansible بسیار مهم‌اند و دانستن آن‌ها به شما کمک می‌کند درک بهتری از مفاهیم declarative و idempotency داشته باشید.

Configuration Management چیست؟

فرض کنید ۱۰ سرور دارید و می‌خواهید روی همهٔ آن‌ها:

  • یک پکیج خاص نصب باشد
  • یک فایل پیکربندی مشخص وجود داشته باشد
  • یک سرویس در حال اجرا باشد

می‌توانید SSH کنید به هر سرور و دستی این کارها را انجام دهید. اما اگر ۱۰۰ سرور داشته باشید؟ یا اگر بخواهید مطمئن شوید همهٔ سرورها دقیقاً یکسان پیکربندی شده‌اند؟

Configuration Management یعنی تعریف desired state — وضعیت مطلوب — و اجازه دادن به یک ابزار که خودش سیستم‌ها را به آن وضعیت برساند.

چرا Ansible؟

ابزارهای زیادی برای Configuration Management وجود دارند (Ansible، Puppet، Chef، SaltStack)، اما Ansible ساده‌ترین است:

  • Agentless — نیازی به نصب نرم‌افزار روی سرورهای مدیریت‌شده نیست
  • SSH-based — از SSH که قبلاً دارید استفاده می‌کند
  • YAML — syntax ساده و خوانا
  • Idempotent — می‌توانید playbook را بارها اجرا کنید

نصب Ansible

روی سیستم کنترل (جایی که Ansible را اجرا می‌کنید):

1# Ubuntu/Debian
2sudo apt update
3sudo apt install -y ansible
4
5# تأیید نصب
6ansible --version
نکته

Ansible را روی سیستمی که می‌خواهید سرورها را از آنجا مدیریت کنید نصب می‌کنید، نه روی خود سرورها. اگر فقط یک VM لینوکس دارید، همان را به‌عنوان control node و managed node استفاده کنید.

Inventory — لیست سرورها

Ansible باید بداند روی کدام سرورها کار کند. این لیست در فایل Inventory نوشته می‌شود.

یک فایل ساده inventory.ini بسازید:

1[local]
2localhost ansible_connection=local
3
4[webservers]
5192.168.1.10
6192.168.1.11
7
8[databases]
9192.168.1.20

برای تمرین، فقط از localhost استفاده می‌کنیم:

1[local]
2localhost ansible_connection=local

اولین دستور Ad-Hoc

یک دستور ساده بدون نوشتن playbook:

1ansible -i inventory.ini local -m ping

خروجی:

1localhost | SUCCESS => {
2    "changed": false,
3    "ping": "pong"
4}

این یعنی Ansible توانست به localhost متصل شود.

یک دستور دیگر — اجرای یک command:

1ansible -i inventory.ini local -m command -a "uptime"

اولین Playbook

یک Playbook فایل YAML است که مجموعه‌ای از taskها را تعریف می‌کند. هر task از یک module استفاده می‌کند.

فایل setup.yml بسازید:

 1---
 2- name: Setup basic system
 3  hosts: local
 4  become: yes
 5  tasks:
 6    - name: Ensure curl is installed
 7      apt:
 8        name: curl
 9        state: present
10        update_cache: yes
11
12    - name: Create a directory
13      file:
14        path: /opt/myapp
15        state: directory
16        mode: '0755'
17
18    - name: Create a simple file
19      copy:
20        content: "Hello from Ansible\n"
21        dest: /opt/myapp/hello.txt
22        mode: '0644'

اجرای playbook:

1ansible-playbook -i inventory.ini setup.yml

خروجی نشان می‌دهد چه taskهایی changed شدند (تغییر کردند) و چه taskهایی ok بودند (قبلاً در وضعیت مطلوب بودند).

حالا دوباره همین playbook را اجرا کنید:

1ansible-playbook -i inventory.ini setup.yml

این بار همهٔ taskها ok هستند — هیچ چیز تغییر نکرده چون سیستم قبلاً در وضعیت مطلوب بوده. این همان idempotency است.

مفاهیم کلیدی Ansible

1. Modules

هر task از یک module استفاده می‌کند. چند module پرکاربرد:

  • apt/yum — نصب پکیج
  • copy — کپی فایل
  • file — مدیریت فایل و دایرکتوری
  • systemd — مدیریت سرویس
  • user — مدیریت کاربر
  • command/shell — اجرای دستور (آخرین راه‌حل)

2. Idempotency

بیشتر moduleها idempotent هستند: اگر وضعیت مطلوب قبلاً برقرار باشد، هیچ کاری انجام نمی‌دهند.

1# این task فقط اگر nginx نصب نباشد، آن را نصب می‌کند
2- name: Ensure nginx is installed
3  apt:
4    name: nginx
5    state: present

3. State

در Ansible شما state می‌گویید:

  • state: present — باید وجود داشته باشد
  • state: absent — نباید وجود داشته باشد
  • state: started — سرویس باید running باشد
  • state: stopped — سرویس باید متوقف باشد

4. Handlers

اگر یک task تغییری ایجاد کند، می‌توانید یک handler را trigger کنید:

 1---
 2- name: Configure nginx
 3  hosts: local
 4  become: yes
 5  tasks:
 6    - name: Copy nginx config
 7      copy:
 8        src: nginx.conf
 9        dest: /etc/nginx/nginx.conf
10      notify: reload nginx
11
12  handlers:
13    - name: reload nginx
14      systemd:
15        name: nginx
16        state: reloaded

Handler فقط اگر task تغییری ایجاد کرده باشد، اجرا می‌شود.

مثال عملی: نصب و پیکربندی NGINX

یک playbook کامل که NGINX را نصب، پیکربندی و راه‌اندازی می‌کند:

 1---
 2- name: Setup nginx web server
 3  hosts: local
 4  become: yes
 5  tasks:
 6    - name: Ensure nginx is installed
 7      apt:
 8        name: nginx
 9        state: present
10        update_cache: yes
11
12    - name: Ensure nginx is running and enabled
13      systemd:
14        name: nginx
15        state: started
16        enabled: yes
17
18    - name: Create web root directory
19      file:
20        path: /var/www/mysite
21        state: directory
22        owner: www-data
23        group: www-data
24        mode: '0755'
25
26    - name: Deploy index page
27      copy:
28        content: |
29          <html>
30          <head><title>Deployed with Ansible</title></head>
31          <body>
32            <h1>Hello from Ansible!</h1>
33            <p>This page was deployed automatically.</p>
34          </body>
35          </html>
36        dest: /var/www/mysite/index.html
37        owner: www-data
38        group: www-data
39        mode: '0644'
40
41    - name: Configure nginx site
42      copy:
43        content: |
44          server {
45              listen 8080;
46              server_name _;
47              root /var/www/mysite;
48              index index.html;
49          }
50        dest: /etc/nginx/sites-available/mysite
51      notify: reload nginx
52
53    - name: Enable nginx site
54      file:
55        src: /etc/nginx/sites-available/mysite
56        dest: /etc/nginx/sites-enabled/mysite
57        state: link
58      notify: reload nginx
59
60  handlers:
61    - name: reload nginx
62      systemd:
63        name: nginx
64        state: reloaded

این playbook را به‌عنوان nginx-setup.yml ذخیره و اجرا کنید:

1ansible-playbook -i inventory.ini nginx-setup.yml

بعد از اجرا، بررسی کنید:

1curl http://localhost:8080

باید صفحهٔ HTML را ببینید.

حالا دوباره playbook را اجرا کنید — همه‌چیز ok است و handler اجرا نمی‌شود چون هیچ چیز تغییر نکرده.

Variables

می‌توانید مقادیر را به‌صورت متغیر تعریف کنید:

 1---
 2- name: Setup nginx
 3  hosts: local
 4  become: yes
 5  vars:
 6    nginx_port: 8080
 7    site_name: mysite
 8  tasks:
 9    - name: Configure nginx
10      copy:
11        content: |
12          server {
13              listen {{ nginx_port }};
14              server_name _;
15              root /var/www/{{ site_name }};
16              index index.html;
17          }
18        dest: /etc/nginx/sites-available/{{ site_name }}
19      notify: reload nginx

یادگیری بیشتر

این فقط یک آشنایی مقدماتی با Ansible بود. موضوعات پیشرفته‌تر:

  • Roles — سازماندهی playbook برای استفاده مجدد
  • Templates — فایل‌های پیکربندی پویا با Jinja2
  • Vault — مدیریت رمزها و secretها
  • Dynamic Inventory — گرفتن لیست سرورها از cloud provider
  • Ansible Galaxy — استفاده از roleهای آماده

اما برای این دوره، همین آشنایی کافی است. حالا شما می‌دانید:

  • Configuration Management چیست
  • Imperative و Declarative در عمل چه تفاوتی دارند
  • Idempotency چطور کار می‌کند
  • چطور یک ابزار مثل Ansible وضعیت سیستم را مدیریت می‌کند

این مفاهیم در هفته‌های بعد — به‌ویژه Docker Compose و Kubernetes — دوباره ظاهر می‌شوند.

منابع یادگیری

مستندات و مقالات

ویدیو