SSD Nodes Learn Hosting plans →
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-08-29

Ansible की Terraform: तुम्हाला नेमके कोणते हवे?

Terraform VPS तयार करते, तर Ansible त्याचे कॉन्फिगरेशन करते. दोन्हींची खरी विभागणी, provisioners का अडचण ठरतात, handoff commands आणि फक्त Ansible कधी पुरेसे आहे ते जाणून घ्या.

एका वाक्यात Ansible विरुद्ध Terraform

Ansible विरुद्ध Terraform ही समान काम करणाऱ्या दोन साधनांपैकी एक निवडण्याची बाब नाही. 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) म्हटले जाते. त्यांच्यातील वास्तविक फरक म्हणजे ते काय लक्षात ठेवतात. Terraform एक state file लिहिते. या file मध्ये तुमच्या code मधील प्रत्येक resource आणि API द्वारे तयार केलेला वास्तविक object यांचा संबंध नोंदवलेला असतो. त्यामुळे तुमच्या code मधील 5 lines हटवल्याचा अर्थ एक server नष्ट करायचा आहे हे Terraform ओळखू शकते. Ansible runs दरम्यान काहीही लक्षात ठेवत नाही. ते SSH द्वारे connect होते, machine ची तपासणी करते आणि playbook शी आधीपासून जुळत नसलेल्या गोष्टीच बदलते.

या एका फरकामुळे या मार्गदर्शकातील पुढील सर्व बाबी स्पष्ट होतात. दोन वेगवेगळी कामे एकाच tool मध्ये मिसळल्यास समस्या का निर्माण होतात, हेही यामुळे स्पष्ट होते.

Terraform प्रत्यक्षात काय करते

Terraform provider plugin मार्फत API शी संवाद साधते. तुमच्या provider च्या registry page वर तुम्ही लिहू शकणाऱ्या 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 या मार्गदर्शकासाठी महत्त्वाचा आहे, कारण त्याच्यामार्फत 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. सारखी ओळ येते. ती ओळ प्रत्येक वेळी वाचा. काही arguments विद्यमान resource मध्ये बदलता येत नाहीत. अशा वेळी plan attribute च्या बाजूला # forces replacement दाखवते आणि त्यानंतर 1 to add, 0 to change, 1 to destroy असते. तो plan लागू केल्यास server delete होतो आणि नवीन रिकामा server तयार होतो. सुरक्षित असल्याचे समजलेला data अशा प्रकारे गमावला जाऊ शकतो.

नुसते terraform apply चालवण्याऐवजी plan file मध्ये save करून ती file apply करा. त्यामुळे तुम्ही review केलेलीच configuration प्रत्यक्षात लागू होते. या दोन commands च्या दरम्यान दुसऱ्या व्यक्तीने infrastructure मध्ये बदल केलेला असू शकतो.

terraform.tfstate ही memory आहे. ती गमावल्यास Terraform ला ते servers तुमचे आहेत हे कळत नाही. त्यामुळे पुढील apply duplicates तयार करण्याचा प्रयत्न करते. एकापेक्षा अधिक व्यक्ती commands चालवत असतील, तर ती remote backend मध्ये शक्य तितक्या लवकर ठेवा. कारण दोन व्यक्तींनी एकाच वेळी apply केल्यास असे घडते:

Error: Error acquiring the state lock

OpenTofu हा Terraform चा fork आहे. त्यात तेच commands आणि तेच file format वापरले जातात. July 2026 पर्यंत, terraform ऐवजी tofu लिहिल्यास या मार्गदर्शकातील सर्वकाही कार्य करते.

Ansible प्रत्यक्षात काय करते

Ansible ला agent किंवा API ची आवश्यकता नसते. ते SSH कनेक्शन उघडते, target वर एक लहान Python module कॉपी करते, ते चालवते आणि नंतर हटवते. SSH आणि sudo password वापरून ज्या system पर्यंत पोहोचता येते, ते 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

Playbook चे debugging सुरू करण्यापूर्वी ping module SSH, Python आणि sudo कार्यरत आहेत हे पडताळते. योग्य परिणाम web1 | SUCCESS => {"ping": "pong"} असा असतो. --check --diff run हा Ansible मधील plan शी सर्वाधिक जवळचा पर्याय आहे. तो कोणते बदल होतील हे दाखवतो, पण प्रत्यक्ष बदल करत नाही. मात्र आधीच्या task वर अवलंबून असलेले task check mode मध्ये चुकीचा परिणाम दाखवू शकतात, कारण आधीचा बदल प्रत्यक्षात झालेला नसतो.

प्रत्येक run चा शेवट ok=6 changed=2 unreachable=0 failed=0 सारख्या recap ने होतो. तोच playbook दोनदा चालवा. दुसऱ्या run मध्ये changed=0 असा परिणाम दिसला पाहिजे. प्रत्येक run मध्ये changed असा परिणाम देणारे task idempotent नसतात. सहसा ते command किंवा shell task असतात; त्यांच्या ऐवजी वास्तविक module वापरायला हवा. हा विषय नवीन असल्यास एका VPS वरचा पहिला Ansible playbook पासून सुरुवात करा आणि त्यावर पुढे विस्तार करा.

ही दोन्ही साधने कुठे एकमेकांना पूरक ठरतात आणि कुठे संघर्ष करतात

Terraform नवीन सर्व्हरवर remote-exec provisioner वापरून commands चालवू शकते. HashiCorp च्या स्वतःच्या documentation मध्ये provisioners हा शेवटचा पर्याय असल्याचे नमूद केले आहे. त्यामागे योग्य कारणे आहेत.

Provisioner फक्त resource तयार केला जाताना चालतो. Script संपादित केल्यानंतर विद्यमान सर्व्हरवर काहीही होत नाही, कारण Terraform च्या दृष्टीने resource आधीच code शी जुळत असतो. Provisioner मधील steps terraform plan मध्ये कधीही दिसत नाहीत. त्यामुळे तुमच्या review मध्ये त्यांचा कोणताही मागमूस राहत नाही. Script अयशस्वी झाल्यास Terraform resource ला tainted म्हणून चिन्हांकित करते. त्यानंतरच्या apply मध्ये आधी योग्य असलेला सर्व्हर नष्ट करून पुन्हा तयार केला जाऊ शकतो.

अपयशाची वेळही अयोग्य असते. API ने सर्व्हर तयार झाल्याचे सांगताच provider सर्व्हर तयार झाल्याची नोंद करतो. त्या वेळी 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 सर्व्हर तयार करू शकतात आणि काही मोजक्या मशीनसाठी ही पद्धत चालते. मात्र dependency graph आणि state file उपलब्ध राहत नाहीत. Ansible resource तयार करते; परंतु playbook मधून task काढून टाकल्यानंतरही resource चालू राहतो आणि त्याचे billing सुरू राहते. कारण तो resource कधी तुमच्या व्यवस्थापनाखाली होता, याची नोंद कुठेही केलेली नसते.

यातून पुढील नियम स्पष्ट होतो: API द्वारे तयार आणि नष्ट होणाऱ्या objects ची मालकी Terraform कडे द्या. Boot झालेल्या operating system च्या आतील सर्व गोष्टींची मालकी 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 कोणतेही quotes किंवा JSON wrapper न वापरता एक value छापतो. Shell substitution मध्ये वापरण्यासाठी हेच आवश्यक असते. अनेक servers साठी terraform output -json वापरा आणि त्यावरून inventory तयार करा, कारण -raw केवळ एक string, number किंवा boolean हाताळतो.

दोन्ही tools मधील ping step ठेवणे उपयुक्त ठरते. त्यामुळे "Terraform ने मला चुकीचा address दिला" आणि "माझ्या playbook मध्ये bug आहे" या दोन समस्या वेगळ्या करता येतात. नवीन box ला प्रथमच हाताळणारी गोष्ट playbook असेल, तर या दोन्ही समस्या अगदी सारख्या दिसतात.

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 अयशस्वी होते. हे plugin तुमच्या server resources वरून hosts आपोआप तयार करत नाही. ते ansible_host आणि ansible_group resources वाचते. हे 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 ची गरज नसते. पायाभूत सुविधा तयार करणे आणि नष्ट करणे हेच वारंवार करावे लागणारे काम असेल, तेव्हा Terraform चा खर्च योग्य ठरतो. तुम्ही control panel द्वारे एक VPS घेतला आणि तो दोन वर्षे ठेवणार असाल, तर Terraform एकदाच होणारी प्रक्रिया वर्णन करते आणि तुम्हाला जपून ठेवावी लागणारी state file तयार करते.

तुम्ही environments वारंवार पुन्हा तयार करत असाल, staging environment production शी अचूक जुळणे आवश्यक असेल, अनेक लोक infrastructure मध्ये बदल करत असतील आणि काहीही delete करण्यापूर्वी review करता येणारा plan हवा असेल, किंवा तुम्ही manage करत असलेल्या गोष्टी servers च्या पलीकडे DNS records, load balancers आणि provider API मध्ये असलेल्या firewall rules पर्यंत जात असतील, तेव्हा Terraform वापरा.

Servers दीर्घकाळ चालणारे आणि कमी संख्येचे असतील, आणि रोजचा प्रश्न "हा box योग्य प्रकारे configured आहे का" असा असेल, "हा box अस्तित्वात आहे का" असा नसेल, तर फक्त Ansible वापरत रहा. नवीन server harden करणारे एक playbook नवीन VPS वरील पहिल्या दहा मिनिटांइतकेच काम करते आणि पुढील server वरही ते त्याच पद्धतीने चालवता येते.

त्यावरून शिकण्याचा क्रम ठरतो. तुमच्या मालकीच्या पहिल्या server पासून Ansible चा फायदा मिळतो. तुम्ही पुन्हा तयार करत असलेल्या तिसऱ्या environment पासून Terraform चा फायदा मिळतो.

हँडऑफमध्ये काय बिघडते

सर्व्हर तयार नाही. 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}

sshd listening सुरू करण्यापूर्वी API ने address परत केला. Fixed sleep जोडण्याऐवजी port उपलब्ध होईपर्यंत प्रतीक्षा करा. यासाठी Ansible मध्ये ansible.builtin.wait_for_connection आहे. ते play मधील पहिले task म्हणून चालवा. तोच playbook एका नवीन box ऐवजी group ला target करू लागल्यावर, एखादा host unreachable राहिल्यास काय करायचे हे आधीच ठरवा. Ansible त्या host ला उर्वरित run मधून काढून टाकते आणि याची माहिती recap line मध्येच देते.

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"} याचा अर्थ त्या host वर become: true ला password आवश्यक आहे. Deploy user साठी passwordless sudo configure करा किंवा --ask-become-pass पास करा.

तुम्ही बदललेले नसतानाही Terraform एखादी गोष्ट नष्ट करू इच्छिते. Plan मध्ये तुम्ही कधीही लिहिलेले नसलेले बदल दिसतात. याचा अर्थ वास्तविक infrastructure code पेक्षा वेगळे झाले आहे. हे सहसा provider च्या web panel मध्ये कोणीतरी setting बदलल्यामुळे होते. हा फरक स्वतंत्रपणे पाहण्यासाठी terraform plan -refresh-only चालवा. त्यानंतर code चुकीचा आहे की live resource, हे ठरवा. प्रत्येक ओळ स्पष्टपणे समजावून सांगता येत नसेल, तर destructive plan कधीही apply करू नका.

प्रत्येक run मध्ये Ansible changed दाखवते. creates किंवा when guard नसलेले shell task अटीशिवाय चालते. ही केवळ cosmetic समस्या नाही. यामुळे सर्व्हर अपेक्षित स्थितीत आहे हे दर्शवणारा संकेत म्हणून changed=0 वापरता येत नाही.

FAQ

Terraform Ansible ची जागा घेऊ शकते का?

सर्व्हरच्या आत configuration करण्यासाठी नाही. Terraform remote-exec provisioner द्वारे scripts चालवू शकते; परंतु ते resource तयार करतानाच चालतात, terraform plan मध्ये कधीही दिसत नाहीत आणि ते अयशस्वी झाल्यास resource tainted होते. त्यामुळे पुढील apply वेळी destroy आणि rebuild नियोजित होते. nginx आधीपासून install आहे का हे तपासून, असल्यास काहीही न करणाऱ्या module चा Terraform मध्ये समतुल्य पर्याय नाही. मशीन तयार करण्यासाठी Terraform वापरा आणि त्यानंतर नियंत्रण Ansible कडे द्या.

Ansible Terraform ची जागा घेऊ शकते का?

कमी संख्येने दीर्घकाळ चालणारे सर्व्हर असल्यास, होय. Ansible मध्ये सर्व्हर तयार करणारे cloud modules आहेत. तुम्ही दोन VPS instances ऑर्डर करून ते कायम ठेवत असाल, तर ते पुरेसे आहे. मात्र state file आणि dependency graph उपलब्ध राहत नाहीत. Playbook मधून एखादे task काढले, तरी resource चालू राहतो आणि त्यासाठी billing सुरू राहते, कारण Ansible ने तो resource तयार केल्याची नोंद केलेली नसते. Terraform destroy चे नियोजन केले असते.

मी प्रथम कोणते शिकावे?

तुमच्याकडे सध्या सर्व्हर असल्यास Ansible शिका. पहिल्या मशीनवरच त्याचा फायदा मिळतो. त्यासाठी SSH व्यतिरिक्त काहीही आवश्यक नाही. तसेच हाताने ऑर्डर केलेल्या सर्व्हरवरही हे कौशल्य लागू होते. वातावरणे वारंवार पुन्हा तयार करायची असतील किंवा सर्व्हरव्यतिरिक्त DNS records आणि firewall rules यांसारखी provider resources व्यवस्थापित करायची असतील, तेव्हा Terraform चा फायदा मिळतो.

Terraform मधून नवीन सर्व्हरचा IP Ansible कडे कसा द्यावा?

Terraform code मध्ये output घोषित करा आणि apply नंतर ते वाचा. Shell substitution साठी terraform output -raw web_ip फक्त मूल्य print करते. अनेक hosts असल्यास terraform output -json सर्व outputs एकाच वेळी देते. ते inventory file मध्ये लिहा. किंवा cloud.terraform collection install करून ansible-inventory -i terraform.yml --graph ला project directory कडे निर्देशित करा.

Terraform पूर्ण झाल्यानंतर माझे playbook लगेच का अयशस्वी होते?

Provider च्या API ने सर्व्हर तयार झाल्याचे कळवताच provider त्याला created म्हणून नोंदवतो. त्या वेळी operating system अद्याप boot होत असते. त्यामुळे पहिल्या काही सेकंदांत SSH connection नाकारले जाते. Connection refused सह UNREACHABLE! ही त्रुटी येते. अंदाजाने sleep duration ठरवण्याऐवजी ansible.builtin.wait_for_connection हे play मधील पहिले task करा. कारण boot time image आणि plan नुसार बदलतो.