SSD Nodes Learn 🎉 VPS $5.50/ماہ سے
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-07

Ansible یا Terraform: آپ کو کون سا چاہیے؟

Terraform VPS بناتا ہے، Ansible اسے configure کرتا ہے۔ state file، provisioners کے مسائل، handoff commands اور صرف Ansible استعمال کرنے کا درست وقت جانیں۔

ایک جملے میں Ansible بمقابلہ Terraform

Ansible بمقابلہ Terraform ایسے دو tools کے درمیان انتخاب نہیں ہے جو ایک ہی کام کرتے ہوں۔ Terraform اعلان کرتا ہے کہ کون سا infrastructure موجود ہونا چاہیے: servers، disks، networks اور DNS records۔ Ansible اعلان کرتا ہے کہ پہلے سے موجود machine کے اندر کیا حالت درست ہونی چاہیے: packages، users، config files اور running services۔ Terraform VPS بناتا ہے۔ Ansible اس VPS کو web server میں تبدیل کرتا ہے۔

دونوں declarative ہیں، اور دونوں کو infrastructure as code (IaC) کہا جاتا ہے۔ اصل فرق یہ ہے کہ یہ tools کیا یاد رکھتے ہیں۔ Terraform ایک state file لکھتا ہے جو آپ کے code میں موجود ہر resource کو اس کے ذریعے API سے بنائے گئے حقیقی object سے map کرتی ہے۔ اس لیے Terraform سمجھ سکتا ہے کہ پانچ lines حذف کرنے کا مطلب ایک server کو destroy کرنا ہے۔ Ansible runs کے درمیان کچھ یاد نہیں رکھتا۔ یہ SSH کے ذریعے connect ہوتا ہے، machine کا جائزہ لیتا ہے، اور صرف وہی چیز تبدیل کرتا ہے جو playbook کے مطابق پہلے سے درست نہیں ہوتی۔

یہ ایک فرق اس guide کی باقی وضاحت کو سمجھا دیتا ہے، بشمول یہ کہ دونوں کاموں کو ایک ہی tool میں ملانا کیوں مسائل پیدا کرتا ہے۔

Terraform اصل میں کیا کرتا ہے

Terraform ایک provider plugin کے ذریعے API سے رابطہ کرتا ہے۔ آپ کے provider کا registry صفحہ ان resource types کی وضاحت کرتا ہے جنہیں آپ لکھ سکتے ہیں، اس لیے ایک host پر موجود server اور دوسرے host پر موجود server مختلف resource names اور مختلف arguments رکھتے ہیں۔

resource "cloud_server" "web" {
  name  = "web1"
  image = "ubuntu-24.04"
  type  = "small"
}

output "web_ip" {
  value = cloud_server.web.ipv4_address
}

cloud_server کو اپنے provider کی دستاویزات میں بیان کردہ resource type سے تبدیل کریں۔ output block اس guide کے لیے اہم ہے، کیونکہ اسی کے ذریعے address Terraform سے باہر جاتا ہے۔

terraform init
terraform fmt -check
terraform validate
terraform plan -out=tfplan
terraform apply tfplan

terraform init provider download کرتا ہے اور lock file لکھتا ہے۔ terraform plan آپ کے code اور state file کے درمیان فرق دکھاتا ہے، اور آخر میں Plan: 1 to add, 0 to change, 0 to destroy. جیسی line پر ختم ہوتا ہے۔ ہر بار اس line کو پڑھیں۔ کچھ arguments کو موجودہ resource میں تبدیل نہیں کیا جا سکتا۔ plan اس بات کو attribute کے ساتھ # forces replacement لکھ کر ظاہر کرتا ہے، جس کے بعد 1 to add, 0 to change, 1 to destroy آتا ہے۔ اس plan کو apply کرنے سے server delete ہو جاتا ہے اور نیا خالی server بن جاتا ہے۔ اسی طرح وہ data ضائع ہو جاتا ہے جسے لوگ محفوظ سمجھ رہے ہوتے ہیں۔

plan کو file میں save کرکے وہ file apply کرنا، براہ راست terraform apply چلانے کے بجائے، اس بات کو یقینی بناتا ہے کہ جس plan کا آپ نے جائزہ لیا تھا، وہی چلایا جائے۔ دونوں commands کے درمیان کوئی دوسرا شخص infrastructure تبدیل کر سکتا ہے۔

terraform.tfstate یادداشت ہے۔ اگر یہ ضائع ہو جائے تو Terraform کو معلوم نہیں رہتا کہ وہ servers آپ کے ہیں، اس لیے اگلا apply duplicate servers بنانے کی کوشش کرتا ہے۔ جیسے ہی ایک سے زیادہ افراد commands چلانے لگیں، اسے remote backend میں رکھیں، کیونکہ بیک وقت دو افراد کے apply کرنے سے یہ نتیجہ پیدا ہوتا ہے:

Error: Error acquiring the state lock

OpenTofu، Terraform کا fork ہے جس میں وہی commands اور وہی file format استعمال ہوتا ہے۔ July 2026 تک، اس guide میں موجود ہر چیز اس وقت بھی کام کرتی ہے جب آپ terraform کے بجائے tofu لکھیں۔

Ansible اصل میں کیا کرتا ہے

Ansible کو کسی agent یا API کی ضرورت نہیں ہوتی۔ یہ SSH connection کھولتا ہے، ایک چھوٹا Python module ہدف سسٹم پر copy کرتا ہے، اسے چلاتا ہے، اور پھر اسے delete کر دیتا ہے۔ جس سسٹم تک آپ SSH اور sudo password کے ذریعے پہنچ سکتے ہیں، Ansible اسے configure کر سکتا ہے۔

- name: Base web server
  hosts: web
  become: true
  tasks:
    - name: Install nginx
      ansible.builtin.apt:
        name: nginx
        state: present
        update_cache: true

    - name: Ensure nginx is running at boot
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: true
ansible -i inventory.ini web -m ansible.builtin.ping
ansible-playbook -i inventory.ini site.yml --check --diff
ansible-playbook -i inventory.ini site.yml

ping module playbook کی debugging شروع کرنے سے پہلے SSH، Python اور sudo کی تصدیق کرتا ہے۔ صحت مند نتیجہ web1 | SUCCESS => {"ping": "pong"} ہوتا ہے۔ --check --diff run، Ansible میں plan کے قریب ترین چیز ہے۔ یہ بتاتا ہے کہ کیا تبدیل ہوگا، مگر حقیقت میں کچھ تبدیل نہیں کرتا۔ تاہم، جو tasks پہلے والے tasks پر منحصر ہوں، وہ check mode میں غلط نتیجہ دے سکتے ہیں، کیونکہ پہلے والی تبدیلی حقیقت میں نہیں ہوئی ہوتی۔

ہر run کا اختتام ok=6 changed=2 unreachable=0 failed=0 جیسے recap پر ہوتا ہے۔ اسی playbook کو دو مرتبہ چلائیں۔ دوسرے run میں changed=0 رپورٹ ہونا چاہیے۔ جو task ہر run میں changed رپورٹ کرے، وہ idempotent نہیں ہے۔ عموماً یہ command یا shell task ہوتا ہے، جس کی جگہ حقیقی module استعمال ہونا چاہیے تھا۔ اگر یہ آپ کے لیے نیا موضوع ہے تو ایک VPS پر پہلے Ansible playbook سے شروع کریں اور پھر اسی بنیاد پر اسے وسعت دیں۔

جہاں دونوں ٹولز کا دائرۂ کار ملتا ہے، اور جہاں وہ ایک دوسرے سے متصادم ہوتے ہیں

Terraform نئے سرور پر `remote-exec` provisioner کے ذریعے commands چلا سکتا ہے۔ HashiCorp کی اپنی documentation provisioners کو آخری چارہ کار قرار دیتی ہے۔ اس کی اچھی وجوہات ہیں۔

Provisioner صرف resource بناتے وقت چلتا ہے۔ Script میں ترمیم کریں تو موجودہ سرور پر کچھ نہیں ہوتا، کیونکہ Terraform کے نقطۂ نظر سے resource پہلے ہی code سے مطابقت رکھتا ہے۔ Provisioner کے مراحل کبھی `terraform plan` میں ظاہر نہیں ہوتے، اس لیے review میں ان کا کوئی نشان نہیں ملتا۔ اگر script ناکام ہو جائے تو Terraform resource کو tainted قرار دیتا ہے، اور اگلا apply ایسے سرور کو destroy کرکے دوبارہ بناتا ہے جو غالباً درست حالت میں تھا۔

Failure کا وقت بھی نامناسب ہوتا ہے۔ Provider اسی لمحے سرور کو created بتا دیتا ہے جب API یہ اطلاع دیتی ہے، جبکہ operating system ابھی boot ہو رہا ہوتا ہے اور `sshd` ابھی listening نہیں کر رہا ہوتا۔

Error: remote-exec provisioner error
timeout - last error: dial tcp 203.0.113.10:22: connect: connection refused

Ansible کے ساتھ اس کے برعکس مسئلہ پیدا ہوتا ہے۔ Cloud modules سرور بنا سکتے ہیں، اور چند machines کے لیے یہ طریقہ کام کرتا ہے۔ لیکن اس میں dependency graph اور state file کا فائدہ ختم ہو جاتا ہے۔ Ansible کسی resource کو آسانی سے بنا دے گا، لیکن playbook سے task حذف کرنے پر resource چلتا رہتا ہے اور اس کے charges بھی جاری رہتے ہیں، کیونکہ کوئی record یہ نہیں رکھتا کہ وہ resource کبھی آپ کی ملکیت تھا۔

اس سے یہ اصول سامنے آتا ہے: API کے ذریعے بنائے اور ختم کیے جانے والے objects کی ownership Terraform کو دیں، اور boot ہو چکے operating system کے اندر موجود ہر چیز کی ownership Ansible کو دیں۔

ہینڈ آف، عملی شکل میں

ہینڈ آف integration نہیں بلکہ ایک حد ہے۔ Terraform اپنا کام مکمل کرتا ہے، ایک address شائع کرتا ہے، اور رک جاتا ہے۔ Ansible اسی address سے شروع ہوتا ہے۔

terraform apply -auto-approve
terraform output -raw web_ip
printf '[web]\n%s ansible_user=root\n' "$(terraform output -raw web_ip)" > inventory.ini
ansible -i inventory.ini web -m ansible.builtin.ping
ansible-playbook -i inventory.ini site.yml

terraform output -raw ایک value کو quotes اور JSON wrapper کے بغیر print کرتا ہے۔ shell substitution کے اندر یہی مطلوب ہوتا ہے۔ متعدد servers کے لیے terraform output -json استعمال کریں اور اسی سے inventory بنائیں، کیونکہ -raw صرف ایک string، number یا boolean کو handle کرتا ہے۔

دونوں tools کے درمیان ping کا step برقرار رکھنا مفید ہے۔ اس سے "Terraform نے مجھے غلط address دیا" اور "میرے playbook میں bug ہے" کے درمیان فرق واضح رہتا ہے۔ اگر playbook نئے box کو پہلی بار touch کرنے والی چیز ہو تو یہ دونوں مسائل ایک جیسے دکھائی دیتے ہیں۔

Terraform state کو Ansible inventory کے طور پر پڑھنا

اگر آپ inventory file بالکل نہیں لکھنا چاہتے تو cloud.terraform collection براہ راست state پڑھتی ہے۔

ansible-galaxy collection install cloud.terraform

اپنی playbook کے ساتھ terraform.yml لکھیں:

plugin: cloud.terraform.terraform_provider
project_path: /home/deploy/infra
ansible-inventory -i terraform.yml --graph
ansible-playbook -i terraform.yml site.yml

اس پر انحصار کرنے سے پہلے دو باتیں جاننا ضروری ہے۔ Plugin project_path کے خلاف terraform show چلاتا ہے، اس لیے اس directory کو پہلے سے initialized ہونا چاہیے، ورنہ plugin fail ہو جاتا ہے۔ یہ plugin آپ کے server resources سے hosts خود نہیں بناتا۔ یہ صرف ansible_host اور ansible_group resources پڑھتا ہے، جنہیں آپ Terraform code میں Ansible provider استعمال کرتے ہوئے declare کرتے ہیں۔ جب تک آپ انہیں شامل نہ کریں، ansible-inventory --graph میں کچھ ظاہر نہیں ہوگا۔

سادہ generated inventory file کو debug کرنا آسان ہے اور یہ کسی بھی provider کے ساتھ کام کرتی ہے۔ جب inventory چند machines سے بڑھ جائے اور ہاتھ سے editing میں typos ہونے لگیں تو plugin مفید ثابت ہوتا ہے۔ یہی وہ مرحلہ ہے جب ایک control machine سے متعدد Linux servers کا انتظام محض عادت کے بجائے ایک باقاعدہ workflow بن جاتا ہے۔

کیا آپ کو واقعی Terraform کی ضرورت ہے؟

اسے پڑھنے والے زیادہ تر لوگوں کو فی الحال اس کی ضرورت نہیں ہے۔ Terraform اس وقت اپنی لاگت پوری کرتا ہے جب infrastructure بنانا اور ختم کرنا خود ایک بار بار دہرایا جانے والا کام ہو۔ اگر آپ نے control panel کے ذریعے ایک VPS منگوایا ہے اور اسے دو سال تک رکھنے کا ارادہ ہے، تو Terraform ایسی چیز کو بیان کرتا ہے جو صرف ایک بار ہوتی ہے، اور ساتھ ایک state file شامل کرتا ہے جسے آپ ضائع نہیں کر سکتے۔

Terraform اس وقت استعمال کریں جب آپ environments کو بار بار دوبارہ بناتے ہوں، جب staging کا production سے عین مطابق مطابقت رکھنا ضروری ہو، جب متعدد لوگ infrastructure تبدیل کرتے ہوں اور آپ چاہتے ہوں کہ کچھ بھی delete ہونے سے پہلے review کے قابل plan موجود ہو، یا جب زیر انتظام چیزیں servers سے آگے بڑھ کر DNS records، load balancers اور firewall rules تک شامل ہو جائیں جو کسی provider API میں موجود ہوں۔

صرف Ansible استعمال کرتے رہیں جب servers طویل عرصے تک قائم رہتے ہوں اور تعداد میں کم ہوں، اور روزمرہ کا سوال یہ ہو کہ "کیا یہ box درست طور پر configured ہے"، نہ کہ "کیا یہ box موجود ہے"۔ ایک ہی playbook جو نئے server کو harden کرتی ہے، نئے VPS پر پہلے دس منٹ جتنا کام انجام دیتی ہے، اور اس کا فائدہ یہ ہے کہ اگلے server پر بھی اسی طریقے سے چلتی ہے۔

سیکھنے کی ترتیب بھی اسی سے واضح ہوتی ہے۔ Ansible آپ کے پہلے server پر ہی فائدہ دینا شروع کر دیتا ہے۔ Terraform اس وقت فائدہ دیتا ہے جب آپ تیسرا environment دوبارہ بناتے ہیں۔

ہینڈ آف میں کیا خراب ہوتا ہے

سرور تیار نہیں ہے۔ Terraform کامیاب ہو جاتا ہے، لیکن Ansible فوراً ناکام ہو جاتا ہے۔

fatal: [web1]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 203.0.113.10 port 22: Connection refused", "unreachable": true}

API نے address اس وقت واپس کیا جب sshd ابھی listening نہیں کر رہا تھا۔ مقررہ sleep شامل کرنے کے بجائے port کا انتظار کریں۔ Ansible میں اسی مقصد کے لیے ansible.builtin.wait_for_connection موجود ہے؛ اسے play کے پہلے task کے طور پر چلائیں۔

Host key تبدیل ہو گئی ہے۔ آپ نے سرور ختم کر کے دوبارہ بنایا، اور نیا سرور اسی address پر نئی key کے ساتھ جواب دے رہا ہے۔

Host key verification failed.

ssh-keygen -R 203.0.113.10 کے ذریعے پرانی entry حذف کریں۔ Terraform کے ذریعے rebuild ہونے کے بعد یہ صورت حال بار بار پیش آتی ہے۔ اسی لیے data رکھنے والی مشینوں پر rebuilds کم رکھنا بہتر ہے۔

Sudo ناکام ہو جاتا ہے۔ fatal: [web1]: FAILED! => {"msg": "Missing sudo password"} کا مطلب ہے کہ become: true کو اس host پر password درکار ہے۔ یا تو deploy user کے لیے passwordless sudo configure کریں، یا --ask-become-pass فراہم کریں۔

Terraform ایسی چیز destroy کرنا چاہتا ہے جسے آپ نے تبدیل نہیں کیا۔ Plan میں ایسی تبدیلیاں دکھائی دیتی ہیں جو آپ نے code میں نہیں لکھی ہوتیں۔ اس کا مطلب ہے کہ حقیقی infrastructure code سے مختلف ہو چکا ہے۔ عموماً ایسا اس وقت ہوتا ہے جب کسی نے provider کے web panel میں setting تبدیل کی ہو۔ صرف یہ فرق دیکھنے کے لیے terraform plan -refresh-only چلائیں، پھر فیصلہ کریں کہ code غلط ہے یا live resource۔ ایسی destructive plan کبھی apply نہ کریں جس کی ہر سطر کی وضاحت آپ نہ کر سکیں۔

Ansible ہر run میں changed رپورٹ کرتا ہے۔ creates یا when guard کے بغیر shell task ہر بار بلاشرط چلتا ہے۔ یہ صرف ظاہری مسئلہ نہیں، کیونکہ اس صورت میں آپ changed=0 کو اس signal کے طور پر استعمال نہیں کر سکتے کہ سرور مطلوبہ state میں ہے۔

FAQ

کیا Terraform، Ansible کی جگہ لے سکتا ہے؟

سرور کے اندر configuration کے لیے نہیں۔ Terraform، remote-exec provisioner کے ذریعے scripts چلا سکتا ہے، لیکن یہ scripts صرف resource بناتے وقت چلتی ہیں، terraform plan میں کبھی ظاہر نہیں ہوتیں، اور ناکام ہونے پر resource کو tainted کر دیتی ہیں۔ اس کے نتیجے میں اگلے apply کے دوران اسے destroy کرکے دوبارہ بنانے کا عمل schedule ہو جاتا ہے۔ Terraform میں ایسے module کا کوئی متبادل نہیں جو یہ جانچے کہ nginx پہلے سے installed ہے یا نہیں، اور installed ہونے کی صورت میں کوئی کارروائی نہ کرے۔ مشین بنانے کے لیے Terraform استعمال کریں، پھر configuration کا کام Ansible کے حوالے کر دیں۔

کیا Ansible، Terraform کی جگہ لے سکتا ہے؟

کم تعداد میں طویل مدت تک چلنے والے servers کے لیے ہاں۔ Ansible میں cloud modules موجود ہیں جو servers بناتے ہیں۔ اگر آپ دو VPS instances order کرکے انہیں برقرار رکھتے ہیں تو یہ کافی ہو سکتا ہے۔ لیکن آپ state file اور dependency graph سے محروم ہو جاتے ہیں۔ Playbook سے کوئی task ہٹانے پر resource چلتا رہتا ہے اور billing بھی جاری رہتی ہے، کیونکہ Ansible نے یہ record نہیں کیا ہوتا کہ resource اسی نے بنایا تھا۔ Terraform ایسی صورت میں destroy کا منصوبہ بناتا۔

مجھے پہلے کون سا سیکھنا چاہیے؟

اگر اس وقت آپ servers manage کرتے ہیں تو Ansible سیکھیں۔ اس کا فائدہ پہلے machine پر ہی مل جاتا ہے، اسے صرف SSH درکار ہوتا ہے، اور یہ skill اس server پر بھی کام آتی ہے جسے آپ نے دستی طور پر order کیا ہو۔ Terraform کا فائدہ بعد میں ملتا ہے، جب آپ environments بار بار rebuild کریں یا servers کے علاوہ provider resources بھی manage کریں، مثلاً DNS records اور firewall rules۔

میں نئے server کا IP، Terraform سے Ansible میں کیسے منتقل کروں؟

اپنے Terraform code میں output declare کریں، پھر apply کے بعد اسے پڑھیں۔ terraform output -raw web_ip shell substitution کے لیے صرف value print کرتا ہے، جبکہ متعدد hosts ہونے پر terraform output -json تمام outputs ایک ساتھ فراہم کرتا ہے۔ اس value کو inventory file میں لکھیں، یا cloud.terraform collection install کرکے ansible-inventory -i terraform.yml --graph کو project directory کی طرف point کریں۔

Terraform مکمل ہونے کے فوراً بعد میرا playbook کیوں ناکام ہو جاتا ہے؟

Provider server کو اسی وقت created report کرتا ہے جب اس کی API ایسا بتاتی ہے، جبکہ operating system ابھی boot ہو رہا ہوتا ہے۔ اسی لیے پہلے چند seconds میں SSH refused ہو جاتا ہے۔ Error UNREACHABLE! کے ساتھ Connection refused ہے۔ اندازے سے sleep duration مقرر کرنے کے بجائے ansible.builtin.wait_for_connection کو play کا پہلا task بنائیں، کیونکہ boot time image اور plan کے مطابق مختلف ہوتا ہے۔