Ansible playbook: Ubuntu 24.04 VPS پر پہلی بار
Ubuntu 24.04 پر pipx سے Ansible انسٹال کریں، inventory اور playbook بنائیں جو نئے VPS کو سخت بنائے۔ Permission denied اور sudo errors کے حل بھی شامل ہیں۔
آپ کیا بنا رہے ہیں
ایک کنٹرول مشین جس میں Ansible انسٹال ہوگا۔ اس کے ساتھ ایک یا زیادہ بالکل نئے Ubuntu 24.04 VPS ہوں گے جن پر صرف اسٹاک ایمیج موجود ہوگی۔ اس گائیڈ کے اختتام تک آپ کے پاس ایک انوینٹری فائل ہوگی جو آپ کے سرورز کے نام بتاتی ہے۔ ایک ad-hoc ping ثابت کرے گا کہ تصدیق کا عمل سر تا سر کام کرتا ہے۔ ایک playbook پورے نئے VPS کی چیک لسٹ کو کوڈ کی صورت میں چلائے گا: ایک deploy یوزر آپ کی SSH کلید کے ساتھ، سخت شدہ sshd، fail2ban، بغیر نگرانی کے اپ گریڈز، اور ایک فائر وال جو سب سے پہلے OpenSSH کی اجازت دیتا ہے اور پھر باقی سب کچھ بلاک کرتا ہے۔ اسے ایک سرور پر چلائیں یا بیس پر۔ اسے دو بار چلائیں اور دوسری بار چلانے پر کچھ بھی تبدیل نہیں ہوگا — یہی اس کا بنیادی مقصد ہے۔
پندرہ سال کے VPS پروویژننگ کے تجربے کے بعد میں آپ کو حقیقت بتاتا ہوں: ہر کوئی پہلے پانچ سرورز کو دستی طور پر سیٹ اپ کرتا ہے۔ پھر چھٹے سرور پر ایک پورا ویکینڈ ضائع کر دیتا ہے کیونکہ کسی کو یاد نہیں ہوتا کہ پہلے پانچ میں کیا کیا تھا۔ یہ گائیڈ متعدد لینکس سرورز کا انتظام میں دی گئی معلومات کو مزید گہرا کرتا ہے — جس دن آپ خود کو ایک ہی apt install کو تین مختلف ٹرمینلز میں ٹائپ کرتے ہوئے پائیں، اسی دن اسے اپنائیں۔
Ansible دراصل کیا ہے، ایک پیراگراف میں
Ansible ایجنٹ لیس ہے۔ اس کے زیرِ انتظام سرورز پر کوئی ڈیمن انسٹال کرنے کی ضرورت نہیں: کنٹرول مشین عام SSH کے ذریعے منسلک ہوتی ہے، ہدف پر ایک چھوٹا Python ماڈیول کاپی کرتی ہے، اسے چلاتی ہے، جو JSON وہ پرنٹ کرتا ہے اسے پڑھتی ہے، اور پھر اسے حذف کر دیتی ہے۔ ہدف کو درک کار واحد چیز python3 ہے، جو پہلے سے ہر اسٹاک Ubuntu امیج میں موجود ہوتی ہے۔ اہم لفظ idempotent ہے، اور اس کا مطلب بالکل واضح ہے: ایک ٹاسک ایک حالت (state) کی وضاحت کرتا ہے، کسی عمل کی نہیں۔ کسی پیکیج کے لیے state: present کا مطلب ہے "یقینی بنائیں کہ یہ انسٹال ہے"، نہ کہ "انسٹالر چلائیں"۔ اگر حالت پہلے سے موجود ہو تو Ansible کچھ چھوتا نہیں اور اسے ok کے طور پر رپورٹ کرتا ہے، changed کے بجائے۔ یہی خصوصیت پورا پروڈکٹ ہے — یہی وجہ ہے کہ پلے بک کو دوبارہ چلانا محفوظ ہوتا ہے، اور محفوظ دوبارہ چلانا ہی شیل اسکرپٹ کو انفراسٹرکچر میں تبدیل کرتا ہے۔
پیش نیازات، اور شروع میں ہی جان لیوا مسائل
- ایک کنٹرول مشین: آپ کا لیپ ٹاپ یا ایک چھوٹا VPS۔ میں Ubuntu 24.04 فرض کرتا ہوں؛ macOS بھی بالکل ایسا ہی کام کرتا ہے جب Homebrew سے pipx انسٹال ہو جائے۔
- ایک یا زیادہ ہدف VPS، KVM پر Ubuntu 24.04 چلا رہے ہوں، اور root تک قابل رسائی ہوں۔ ان پر کچھ انسٹال نہیں ہوگا۔
- ہر ہدف تک SSH کلید تصدیق۔ Ansible بالکل اسی طرح تصدیق شدہ ہے جیسے آپ کا
sshکمانڈ — اگرssh root@hostپاس ورڈ مانگے، تو Ansible ناکام ہو جاتا ہے۔ - Ubuntu 24.04 پر،
pip install ansibleerror: externally-managed-environmentکے ساتھ ختم ہو جاتا ہے۔ یہ جان بوجھ کر ڈسٹریبیوشن کی پالیسی ہے، کوئی خرابی نہیں۔ pipx استعمال کریں۔ - YAML میں خالی جگہ (whitespace) نحو (syntax) کا حصہ ہے۔ غلط انڈینٹیشن
mapping values are not allowed in this contextپیدا کرتی ہے، اور کہیں بھی tab کریکٹر جان لیوا ہے۔ - جب تک پلے بک sshd کو سخت (harden) کر رہا ہو، ہر ہدف پر ایک کام کرنے والا SSH سیشن کھلا رکھیں۔ جن کسٹمرز کو میں نے لاک آؤٹ ہونے سے بحال کرنے میں مدد کی، ان سب نے آخری سیشن "صاف حالت سے ٹیسٹ کرنے" کے لیے بند کر دیا تھا۔
مرحلہ 1: کنٹرول مشین پر Ansible کو pipx کے ساتھ انسٹال کریں، pip کے ساتھ نہیں
روایتی رجحان pip3 install ansible ہے۔ بالکل نئی 24.04 امیج پر یہ ایک مرحلہ پہلے ہی ناکام ہو جاتا ہے — Command 'pip3' not found, but can be installed with: sudo apt install python3-pip — اور pip انسٹال کرنا آپ کو صرف اصل رکاوٹ تک پہنچاتا ہے:
pip3 install ansibleerror: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.Ubuntu 24.04 سسٹم Python کو externally managed (PEP 668) کے طور پر نشان زد کرتا ہے، اس لیے pip اسی فائلز پر apt سے ٹکر نہیں لے سکتا۔ --break-system-packages کی طرف مت بڑھیں؛ یہ flag اپنے نام کے مطابق کام کرتا ہے۔ درست حل pipx ہے، جو Ansible کو اس کا اپنا الگ تھلگ virtualenv دیتا ہے اور binaries کو آپ کے PATH پر رکھتا ہے:
sudo apt update && sudo apt install -y pipx
pipx ensurepath
pipx install --include-deps ansiblepipx ensurepath کے بعد ایک نیا shell کھولیں تاکہ PATH کی تبدیلی لاگو ہو جائے۔ --include-deps محرف آرائش نہیں ہے: ansible پیکیج اپنے کوئی console scripts شامل نہیں کرتا — ansible، ansible-playbook، اور باقی سب اس کے ansible-core انحصار کے entry points ہیں — اس لیے flag کے بغیر pipx No apps associated with package ansible or its dependencies کے ساتھ انسٹالیشن سے انکار کر دیتا ہے۔ اور ansible پیکیج انسٹال کریں، خالی ansible-core نہیں — مکمل پیکیج community collections کو شامل کرتا ہے، اور یہ playbook ان میں سے دو (ansible.posix اور community.general) کے ماڈیولز استعمال کرتا ہے۔
ansible --versionدرست نتیجہ ansible [core 2.19.x] جیسی ایک لائن سے شروع ہوتا ہے اور وہ Python بتاتا ہے جس کے تحت یہ چلتا ہے؛ یہاں کے لیے کوئی بھی موجودہ core release بھی کام کرے گی۔ ansible: command not found کا مطلب ہے کہ ~/.local/bin ابھی آپ کے PATH پر نہیں ہے — نیا shell کھولیں، یا source ~/.bashrc۔
یہ مکمل انسٹالیشن ہے۔ ہدف مشینوں پر کچھ انسٹال نہیں کرنا۔
مرحلہ 2: ہر ہدف تک SSH کلید کی رسائی
ssh-keygen -t ed25519 -C "ansible control"
ssh-copy-id root@10.0.0.10
ssh-copy-id root@10.0.0.20پھر اسے ثابت کریں، ہر ہوسٹ کے لیے ایک بار:
ssh root@10.0.0.10 true && echo okیہ ایک لائن دو کام کرتی ہے: یہ تصدیق کرتی ہے کہ پاس ورڈ کے بغیر کلید کی توثیق کام کرتی ہے، اور یہ ہوسٹ کلید کو known_hosts میں محفوظ کرتی ہے۔ یہ اب کریں، کیونکہ Ansible غیر محفوظ شدہ ہوسٹ کلید کو چلنے کے درمیان دبی ہوئی انٹرایکٹو پرامپٹ کے طور پر ظاہر کرتا ہے، جو بالکل اسی طرح پڑھا جاتا ہے جیسے عمل رک گیا ہو۔
مرحلہ 3: انوینٹری — پہلے INI، بڑھنے پر YAML
انوینٹری ایک ٹیکسٹ فائل ہے جس میں وہ مشینیں درج ہوتی ہیں جن تک Ansible رسائی حاصل کر سکتا ہے۔ ایک نئے پروجیکٹ ڈائریکٹری میں inventory.ini بنائیں:
[vps]
web1 ansible_host=10.0.0.10
web2 ansible_host=10.0.0.20
[vps:vars]
ansible_user=rootweb1 آپ کا منتخب کردہ اسم مستعار ہے — یہ آؤٹ پٹ میں ظاہر ہوتا ہے اور اسی کو آپ --limit web1 کے ساتھ ہدف بناتے ہیں۔ ansible_host حقیقی پتہ ہے۔ [vps] ایک گروپ ہے، اور [vps:vars] اس میں موجود ہر ہوسٹ کے لیے متغیرات طے کرتا ہے؛ ansible_user وہ صارف ہے جس کے طور پر Ansible لاگ ان ہوتا ہے۔ اس کے ساتھ ساتھ ایک ansible.cfg رکھیں تاکہ آپ کو دوبارہ -i ٹائپ نہ کرنا پڑے:
[defaults]
inventory = inventory.iniAnsible موجودہ ڈائریکٹری سے ansible.cfg کو پڑھتا ہے۔ YAML میں وہی انوینٹری — اسے inventory.yml کے نام سے محفوظ کریں اور ansible.cfg کو اسی نام کی طرف اشارہ کریں — وہ ہے جسے آپ ترجیح دیں گے جب ایک ہوسٹ کے ساتھ کئی متغیرات منسلک ہوں:
vps:
hosts:
web1:
ansible_host: 10.0.0.10
web2:
ansible_host: 10.0.0.20
vars:
ansible_user: rootیہ دونوں مساوی ہیں۔ دو سرورز پر INI کو پڑھنا آسان ہے؛ بیس سرورز پر YAML بہتر توسیع کرتا ہے۔ کوئی ایک منتخب کریں اور اس کے بارے میں سوچنا چھوڑ دیں۔
مرحلہ 4: ad-hoc کمانڈز — وہ سبز pong جو سب کچھ ثابت کرتا ہے
ansible all -m pingیہ ICMP نہیں ہے۔ ping ماڈیول ایک مکمل ریہرسل ہے: SSH لاگ ان، ماڈیول کاپی، ہدف پر Python کی عملدرآمد، اور صفائی۔ درست نتیجہ سبز ہوتا ہے، ہر ہوسٹ کے لیے ایک بلاک:
web1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}سبز SUCCESS کا مطلب ہے کہ تصدیق، Python مترجم، اور ٹرانسپورٹ سب کام کر رہے ہیں — playbook بھی کام کرے گی۔ سرخ UNREACHABLE! کا مطلب ہے کہ کوئی ماڈیول چلنے سے پہلے ہی ٹرانسپورٹ ناکام ہو گیا؛ عیب کی علامات کا صحیح متن اور اس کا حل نیچے ناکامی کے طریقوں والے حصے میں ہے۔ دو اور ad-hoc کمانڈز جنہیں جاننا مفید ہے:
ansible all -a "uptime"
ansible all -m apt -a "update_cache=true upgrade=dist" --becomeAd-hoc کمانڈز ایک بار کے کاموں اور چیکس کے لیے ہیں۔ جو کچھ بھی آپ دو بار چلائیں گے وہ playbook میں ہونا چاہیے۔
مرحلہ 5: پہلا پلے بک — نئی VPS کی چیک لسٹ کو کوڈ کی صورت میں
یہ وہ سب کچھ ہے جو آپ ایک نئے سرور پر پہلے دس منٹوں میں دستی طور پر کرتے۔ اسے site.yml کے نام سے محفوظ کریں:
---
- name: Baseline a fresh Ubuntu VPS
hosts: vps
become: true
vars:
deploy_user: deploy
deploy_pubkey: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
baseline_packages:
- fail2ban
- unattended-upgrades
- ufw
baseline_services:
- fail2ban
- unattended-upgrades
tasks:
- name: Create the deploy user
ansible.builtin.user:
name: "{{ deploy_user }}"
groups: sudo
append: true
shell: /bin/bash
- name: Install the deploy user's SSH key
ansible.posix.authorized_key:
user: "{{ deploy_user }}"
key: "{{ deploy_pubkey }}"
- name: Passwordless sudo for the deploy user
ansible.builtin.copy:
dest: /etc/sudoers.d/deploy
content: "{{ deploy_user }} ALL=(ALL) NOPASSWD:ALL\n"
mode: "0440"
validate: /usr/sbin/visudo -cf %s
- name: Install baseline packages
ansible.builtin.apt:
name: "{{ baseline_packages }}"
state: present
update_cache: true
- name: Enable and start baseline services
ansible.builtin.service:
name: "{{ item }}"
state: started
enabled: true
loop: "{{ baseline_services }}"
- name: Harden sshd with a drop-in
ansible.builtin.copy:
dest: /etc/ssh/sshd_config.d/00-hardening.conf
content: |
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
X11Forwarding no
mode: "0644"
validate: /usr/sbin/sshd -t -f %s
notify: Restart ssh
- name: Allow OpenSSH through ufw
community.general.ufw:
rule: allow
name: OpenSSH
- name: Enable ufw with default deny
community.general.ufw:
state: enabled
policy: deny
handlers:
- name: Restart ssh
ansible.builtin.service:
name: ssh
state: restartedوہ سطریں جنہیں سمجھنا ضروری ہے، صرف کاپی کرنے سے بہتر:
ویری ایبلز vars: کے تحت موجود ہوتے ہیں اور "{{ deploy_user }}" کے ذریعے حوالہ دیے جاتے ہیں۔ جب کسی ویلیو کی شروعت بریک سے ہو تو پورے ایکسپریشن کو کوٹ کریں، ورنہ YAML پارسر اسے غلط پڑھ لیتا ہے۔ lookup('file', ...) رن ٹائم پر آپ کی پبلک کلید کو کنٹرول مشین سے پڑھتا ہے، اس لیے پلے بک میں کوئی کلید مواد موجود نہیں ہوتا۔
لوپ۔ loop: "{{ baseline_services }}" سروس ٹاسک کو ہر آئٹم پر ایک بار چلاتا ہے، اور آؤٹ پٹ میں ہر آئٹم علیحدہ سطر پر نظر آتا ہے۔ نوٹ کریں کہ apt ٹاسک پورے پیکیج لسٹ کو ایک ہی مرتبہ میں لے لیتا ہے۔ ایک apt ٹرانزیکشن تیز ہوتا ہے اور پیکیجز کے لیے یہ ترجیحی طریقہ ہے۔ لوپس ان ماڈیولز کے لیے ہیں جو واقعی ایک وقت میں صرف ایک چیز پر عمل کرتے ہیں۔
ہینڈلر وہ تصور ہے جسے ذہن میں بٹانا ہوگا۔ notify: Restart ssh کا مطلب "ssh ابھی ری اسٹارٹ کرو" نہیں ہے۔ یہ ہینڈلر کو قطار میں لگاتا ہے، جو پلے کے اختتام پر صرف ایک بار چلتا ہے، اور وہ بھی صرف اس صورت میں جب نوٹیفائنگ ٹاسک نے واقعی changed رپورٹ کیا ہو۔ کل پلے بک دوبارہ چلائیں: ڈراپ ان فائل پہلے ہی درست ہوگی، کاپی ٹاسک ok رپورٹ کرے گا، اور sshd کو کبھی ری اسٹارٹ نہیں کیا جائے گا۔ validate: سطر ٹرگر پر سیفٹی ہے۔ sshd پرانی فائل کو تبدیل کرنے سے پہلے نئی فائل کی جانچ کرتا ہے، اس لیے ٹائپنگ کی غلطی ڈیمن کو توڑنے کے بجائے ٹاسک کو ناکام کر دیتی ہے۔
PermitRootLogin prohibit-password، نہیں no — جان بوجھ کر۔ یہ پلے بک کلید کے ساتھ root لاگ ان ہوتا ہے۔ prohibit-password root کے پاس ورڈ لاگ ان بند کر دیتا ہے جبکہ آپ کا اپنا لاگ ان برقرار رکھتا ہے۔ جب ڈپلائی یوزر کی تصدیق ہو جائے (ssh deploy@10.0.0.10 sudo true — پلین ایڈریس، کیونکہ web1 صرف Ansible کا جانا ہوا ایک ایلیاس ہے)، انوینٹری میں ansible_user=deploy کو تبدیل کریں اور بعد کی رن میں اسے no تک سخت کریں۔ ایسے ترتیب میں سیکیورٹی بڑھائیں جو آپ کو لاک آؤٹ نہ کر دے۔
00- پری فکس اہم ہے۔ اکثر کلیدی الفاظ کے لیے sshd جو پہلا وقوعہ پارس کرتا ہے اسی پر عمل کرتا ہے، اور Ubuntu کا sshd_config لیکسیکل ترتیب میں اپنے باڈی سے پہلے sshd_config.d/*.conf کو شامل کرتا ہے۔ Ubuntu 24.04 کلاؤڈ امیجز میں پہلے سے اس ڈائریکٹری میں 60-cloudimg-settings.conf موجود ہوتا ہے، اور جو فراہم کنندگان cloud-init کے ذریعے پاس ورڈ لاگ ان فعال کرتے ہیں وہ 50-cloud-init.conf میں PasswordAuthentication yes شامل کرتے ہیں۔ ہماری فائل کا نام 00-hardening.conf رکھنا اسے پہلے ترتیب میں لاتا ہے اور دونوں پر فوقیت دلاتا ہے۔
ٹاسک کی ترتیب فائر وال سیفٹی ہے۔ Allow OpenSSH ڈینائی پالیسی کے ساتھ Enable ufw سے پہلے چلتا ہے۔ Ansible ٹاسکس کو قطعی ترتیب میں چلاتا ہے، اس لیے دیوار کھڑی ہونے سے پہلے سوراخ موجود ہو جاتا ہے۔ fail2ban کو یہاں مفید بننے کے لیے کوئی کنفیگریشن کی ضرورت نہیں۔ اس کی Ubuntu ڈیفالٹس باکس سے باہر sshd کی نگرانی کرتی ہیں، اور جیلز دراصل کیا کرتے ہیں — اور کیا ٹیون کیا جائے — اس کی تفصیل Ubuntu 24.04 پر fail2ban گائیڈ میں دی گئی ہے۔
مرحلہ 6: --check کے ساتھ خشک آزمائش کریں، پھر اسے حقیقت میں چلائیں
ansible-playbook site.yml --checkCheck mode کنیکٹ ہوتا ہے، حساب لگاتا ہے کہ وہ کیا کرے گا، اور کچھ تبدیل نہیں کرتا۔ نیچے PLAY RECAP میں changed= کاؤنٹ پڑھیں — یہ ہر ہوسٹ پر تبدیل کرنے والے ٹاسک کی تعداد ہے۔ ایک صاف انتباہ: check mode کی ایک ساختی حد ہے جہاں کوئی بعد کا ٹاسک کسی پہلے ٹاسک کی تبدیلیوں پر منحصر ہو۔ Ubuntu کا معیاری سرور امیج پہلے سے ufw شامل کرتا ہے، اس لیے یہ پلے بک خشک آزمائش میں بغیر کسی خامی کے چلتی ہے — لیکن اس کے بغیر کسی کم سے کم امیج پر، ufw ٹاسک check mode میں ناکام ہو جاتے ہیں، کیونکہ check mode نے پیکیج واقعی انسٹال نہیں کیا اور پھر ماڈیول کے پاس کال کرنے کے لیے کچھ نہیں ہوتا۔ یہ خشک آزمائش کی حد ہے، آپ کی پلے بک میں کوئی خامی نہیں۔ جب منصوبہ درست لگے:
ansible-playbook site.ymlہر ٹاسک ہر ہوسٹ کے لیے ایک لائن پرنٹ کرتا ہے — پیلا changed، سبز ok — اور خلاصہ یہ ہونا چاہیے:
PLAY RECAP *********************************************************************
web1 : ok=10 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web2 : ok=10 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0دس ok فیکٹ اکٹھا کرنے کے ساتھ ساتھ آٹھ ٹاسک اور ہینڈلر ہیں۔ آپ کا changed میرے سے ایک یا دو تک مختلف ہو سکتا ہے: Ubuntu کا معیاری امیج پہلے سے ufw اور unattended-upgrades شامل کرتا ہے، اور fail2ban اسی وقت خود کو اسٹارٹ کرتا ہے جیسے ہی apt اسے انسٹال کرتا ہے، اس لیے کوئی ٹاسک اپنے پہلے چلنے پر بجا طور پر ok رپورٹ کر سکتا ہے — وہ حالت جس کا وہ دعویٰ کرتا ہے وہ پہلے سے موجود ہے۔ جن اعداد کا صفر ہونا ضروری ہے وہ unreachable اور failed ہیں۔ become: true پر ایک بات: جب تک آپ root کے طور پر کنیکٹ کرتے ہیں یہ ایک رسم ہے، لیکن جیسے ہی آپ ansible_user کو deploy میں بدلتے ہیں، sudo حقیقی ہو جاتا ہے — اور NOPASSWD sudoers فائل جو یہ پلے بک انسٹال کرتا ہے وہی ہے جو -K کو آپ کی کمانڈ لائن سے دور رکھتی ہے۔ اس کے بغیر آپ کو Missing sudo password ملتا ہے، جس کا ذکر نیچے کیا گیا ہے۔
مرحلہ 7: اسے دو بار چلائیں — idempotence کیسی نظر آتی ہے
فوراً اسی کمانڈ کو دوبارہ چلائیں:
web1 : ok=9 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0changed=0، اور ok ایک کمی آئی کیونکہ un-notified ہینڈلر کبھی نہیں چلا۔ کچھ بھی دوبارہ انسٹال نہیں ہوا، sshd دوبارہ شروع نہیں ہوا، ufw کو ہاتھ نہیں لگا۔ اسی وجہ سے پلے بک ایک آڈٹ بھی ہے جتنا کہ ایک پروویژنر: اگلے مہینے انوینٹری میں web3 شامل کریں اور دوبارہ چلائیں — نیا باکس بن جاتا ہے، پرانے باکسز کی تصدیق ہو جاتی ہے۔ کسی ایسے باکس پر غیر صفر changed drift ہے جسے آپ نے ہاتھ نہیں لگایا، اور یہ بتاتا ہے کہ کسی نے ہاتھ سے وہ ترمیم کی ہے جو پلے بک میں ہونی چاہیے تھی۔
یہاں سے پیٹرن بڑھتا جاتا ہے۔ لکھنے کے قابل اگلی پلے بک اسی VPS پر WireGuard VPN لگاتی ہے اور ufw کے رول کو سخت کرتی ہے تاکہ SSH صرف ٹنل پر جواب دے؛ اس کے بعد، ایک پلے بک جو ہر ایپ سرور پر Docker اور Compose انسٹال کرے۔ جب site.yml تین اسکرینوں سے بڑھ جائے، اسے roles میں تقسیم کریں — لیکن اس سے پہلے نہیں۔
ناکامی کے طریقے، آپ کو جو پیغامات نظر آئیں گے
UNREACHABLE معنی Permission denied۔
web1 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: root@10.0.0.10: Permission denied (publickey).",
"unreachable": true
}SSH ٹرانسپورٹ کسی بھی ماڈیول کے چلنے سے پہلے ناکام ہو گیا: ansible_user غلط ہے، کلید اس ہوسٹ پر کاپی ہی نہیں ہوئی، یا غلط کلید پیش کی جا رہی ہے۔ اسے سادہ ssh root@10.0.0.10 سے دہرائیں، پھر ssh -v چلائیں تاکہ دیکھیں کون سی کلیدیں پیش کی گئیں۔ اگر پاس ورڈ SSH کام کرتا ہے لیکن Ansible نہیں، تو آپ نے ssh-copy-id چھوڑ دیا۔
sudo پاس ورڈ غائب ہے۔
web1 | FAILED! => {
"msg": "Missing sudo password"
}آپ نے become: true سیٹ کیا، غیر روٹ صارف کے طور پر منسلک ہوئے، اور اس صارف کو sudo کے لیے پاس ورڈ درکار ہے۔ یا تو کمانڈ لائن میں -K (--ask-become-pass) شامل کریں، یا صارف کو ایک NOPASSWD sudoers اندراج دیں — اور اسی وجہ سے پلے بک آپ کے اس صارف deploy پر منتقل ہونے سے پہلے اس کے لیے ایک اندراج انسٹال کرتا ہے۔
error: externally-managed-environment۔ آپ نے Ubuntu 24.04 پر سسٹم Python کے خلاف pip چلایا۔ مرحلہ 1 میں اس کا ذکر ہے: pipx، نہ کہ pip، اور نہ ہی --break-system-packages۔
mapping values are not allowed in this context۔
ERROR! Syntax Error while loading YAML.
mapping values are not allowed in this contextتقریباً ہمیشہ یہ انڈینٹیشن کی خرابی ہوتی ہے: کوئی کلید غلط گہرائی پر ہے، یا کولن کے بعد خالی جگہ غائب ہے۔ رپورٹ کی گئی لائن نمبر غلطی کے قریب بتاتا ہے، اس پر نہیں — اوپر والی لائن بھی چیک کریں۔ اس کا ہم جوڑ found character '\t' that cannot start any token اس کا مطلب ہے کہ کوئی ٹیب آ گیا ہے؛ YAML اسے منع کرتا ہے۔ ہر رن سے پہلے ansible-playbook site.yml --syntax-check کو ایک عادت بنائیں، اور YAML کے لیے اپنے ایڈیٹر کو دو اسپیس انڈینٹیشن پر سیٹ کریں۔
/usr/bin/python3: not found۔ معیاری Ubuntu 24.04 امیجز پر یہ نایاب ہے، کم سے کم یا نیٹ بوٹ امیجز پر عام ہے: ماڈیول ایگزیکیوشن اس لیے ناکام ہوتی ہے کیونکہ ٹارگٹ پر Python موجود نہیں ہے۔ اسے raw ماڈیول سے بوٹسٹریپ کریں، یہ وہ واحد ماڈیول ہے جسے دور دراز سسٹم پر کسی چیز کی ضرورت نہیں: ansible all -m raw -a "apt-get update && apt-get install -y python3" --become، پھر پلے بک دوبارہ چلائیں۔
FAQ
کیا مجھے Ansible کو ان سرورز پر انسٹال کرنے کی ضرورت ہے جنہیں یہ منظم کرتا ہے؟
نہیں۔ Ansible ایجنٹ سے پاک ہے۔ کنٹرول مشین SSH کے ذریعے چھوٹے Python ماڈیولز بھیجتی ہے، انہیں چلاتی ہے، اور پھر ہٹا دیتی ہے۔ ہدف پر صرف python3 اور SSH تک رسائی درکار ہے، اور یہ دونوں چیزیں اسٹاک Ubuntu امیجز میں پہلے سے موجود ہوتی ہیں۔ اس پوری گائیڈ میں انسٹالیشن صرف آپ کی کنٹرول مشین پر ہوتی ہے۔
Ansible "Permission denied (publickey)" کیوں کہتا ہے؟
UNREACHABLE! بلاک جس میں Permission denied (publickey) ہے، اس کا مطلب ہے کہ Ansible کے کام شروع ہونے سے پہلے ہی SSH توثیق ناکام ہو گئی۔ چیک کریں کہ انوینٹری میں ansible_user اس اکاؤنٹ سے ملتا ہے جو آپ نے واقعی سیٹ اپ کیا ہے، کہ آپ نے اس ہوسٹ تک ssh-copy-id چلایا ہے، اور کہ سادہ ssh user@host بغیر پاس ورڈ کے لاگ اِن ہو جاتا ہے۔ جو کچھ بھی سادہ ssh کمانڈ کو ٹھیک کرتا ہے وہ Ansible کو بھی ٹھیک کرتا ہے، کیونکہ دونوں کا ٹرانسپورٹ ایک ہی ہے۔
Ansible میں idempotent کا کیا مطلب ہے؟
ایک ٹاسک مطلوبہ حالت کا اعلان کرتا ہے — "یہ پیکیج موجود ہے"، "یہ لائن اس فائل میں ہے" — بجائے اس کے کہ کوئی عمل انجام دیا جائے۔ اگر حالت پہلے سے برقرار ہے، تو Ansible کچھ نہیں کرتا اور changed کے بجائے ok رپورٹ کرتا ہے۔ اسی لیے پلے بک کو دو بار چلانے پر دوسری بار changed=0 نظر آتا ہے، اور اسی لیے دوبارہ چلانا ایک محفوظ آڈٹ ہے نہ کہ خطرناک دوبارہ انسٹالیشن۔
Ubuntu 24.04 پر Ansible انسٹال کرنے کے لیے مجھے pip استعمال کرنا چاہیے یا pipx؟
pipx۔ Ubuntu 24.04 سسٹم Python کو بیرونی طور پر منظم کردہ قرار دیتا ہے، اس لیے pip install ansible ڈیزائن کے مطابق error: externally-managed-environment کے ساتھ ناکام ہو جاتا ہے۔ pipx install --include-deps ansible Ansible کو ایک الگ تھلگ virtualenv میں رکھتا ہے اور ansible، ansible-playbook، اور باقی سب کو آپ کے PATH پر صاف ستھرے انداز میں دستیاب کرتا ہے۔
ansible اور ansible-core پیکیجز میں کیا فرق ہے؟
ansible-core صرف انجن اور ansible.builtin ماڈیولز ہیں۔ ansible پیکیج core کے ساتھ منتخب کردہ کمیونٹی کلیکشنز بھی شامل کرتا ہے — بشمول ansible.posix (authorized_key ماڈیول) اور community.general (ufw ماڈیول)، جو دونوں اس گائیڈ میں استعمال ہوئے ہیں۔ مکمل پیکیج سے شروع کریں۔ صرف اس وقت core کی طرف رجوع کریں جب آپ کے پاس اس کی کوئی وجہ ہو۔