Ansible বনাম Terraform: কোনটি আপনার প্রয়োজন?
Terraform দিয়ে ইনফ্রাস্ট্রাকচার তৈরি এবং Ansible দিয়ে কনফিগারেশন করার সঠিক নিয়ম জানুন। কেন এই দুটি টুল একসাথে ব্যবহার করা উচিত এবং কখন শুধুমাত্র Ansible যথেষ্ট তা এখানে দেখুন।
Ansible এবং Terraform-এর মধ্যে পার্থক্য এক বাক্যে
Ansible এবং Terraform একই কাজ করে না, তাই এদের মধ্যে কোনো একটিকে বেছে নেওয়ার প্রশ্ন আসে না। Terraform ঘোষণা করে যে কী কী অবকাঠামো বিদ্যমান থাকবে: সার্ভার, ডিস্ক, নেটওয়ার্ক এবং DNS রেকর্ড। Ansible ঘোষণা করে যে একটি বিদ্যমান মেশিনের ভেতরে কী কী অবস্থা বজায় থাকবে: প্যাকেজ, ইউজার, কনফিগারেশন ফাইল এবং চলমান সার্ভিস। Terraform একটি VPS তৈরি করে, আর Ansible সেই VPS-কে একটি ওয়েব সার্ভারে রূপান্তর করে।
উভয়ই ডিক্লারেটিভ এবং উভয়কেই Infrastructure as Code (IaC) বলা হয়। এদের আসল পার্থক্য হলো তারা কী মনে রাখে। Terraform একটি state file লেখে যা আপনার কোডের প্রতিটি রিসোর্সকে তার তৈরি করা বাস্তব অবজেক্টের সাথে ম্যাপ করে, ফলে কোড থেকে পাঁচটি লাইন মুছে ফেললে সে বুঝতে পারে যে একটি সার্ভার ধ্বংস করতে হবে। Ansible প্রতিবার চালানোর মাঝে কিছুই মনে রাখে না। এটি SSH-এর মাধ্যমে সংযুক্ত হয়, মেশিনটি পরীক্ষা করে এবং শুধুমাত্র সেই অংশগুলো পরিবর্তন করে যা প্লেবুকের সাথে মিলছে না।
এই একটি পার্থক্যই এই গাইডের বাকি অংশ ব্যাখ্যা করে, যার মধ্যে রয়েছে কেন এই দুটি কাজকে একটি টুলে মেশালে সমস্যা হয়।
Terraform আসলে যা করে
Terraform একটি provider plugin-এর মাধ্যমে API-এর সাথে যোগাযোগ করে। আপনার provider-এর registry পেজে সেই resource type-গুলো সংজ্ঞায়িত থাকে যা আপনি লিখতে পারেন, তাই এক host-এর সার্ভার এবং অন্য host-এর সার্ভার ভিন্ন ভিন্ন resource নাম এবং ভিন্ন ভিন্ন argument বহন করে।
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 ব্লকটি অত্যন্ত গুরুত্বপূর্ণ, কারণ এর মাধ্যমেই ঠিকানাটি Terraform থেকে বেরিয়ে যায়।
terraform init
terraform fmt -check
terraform validate
terraform plan -out=tfplan
terraform apply tfplanterraform init provider-টিকে ডাউনলোড করে এবং একটি lock file তৈরি করে। terraform plan আপনার কোড এবং state file-এর মধ্যকার পার্থক্য প্রদর্শন করে, যা Plan: 1 to add, 0 to change, 0 to destroy.-এর মতো একটি লাইনের মাধ্যমে শেষ হয়। প্রতিবার এই লাইনটি পড়ুন। কিছু argument সরাসরি পরিবর্তন করা যায় না, এবং plan-এ সেই attribute-এর পাশে # forces replacement লেখা থাকে, যার পরে 1 to add, 0 to change, 1 to destroy থাকে। সেই plan apply করলে সার্ভারটি মুছে যায় এবং একটি নতুন খালি সার্ভার তৈরি হয়, এভাবেই মানুষ তাদের ডেটা হারিয়ে ফেলে যা তারা নিরাপদ ভেবেছিল।
সরাসরি terraform apply না চালিয়ে plan-টিকে একটি ফাইলে সেভ করে সেই ফাইলটি apply করা মানে হলো, আপনি যা পর্যালোচনা করেছেন ঠিক সেটিই কার্যকর হবে। এই দুটি কমান্ডের মধ্যবর্তী সময়ে অন্য কেউ হয়তো infrastructure পরিবর্তন করে থাকতে পারে।
terraform.tfstate হলো মেমোরি। এটি হারিয়ে ফেললে Terraform আর বুঝতে পারে না যে ওই সার্ভারগুলো আপনার, ফলে পরবর্তী apply-এর সময় এটি ডুপ্লিকেট তৈরি করার চেষ্টা করে। যখন একাধিক ব্যক্তি কমান্ডগুলো চালান, তখন এটিকে দ্রুত একটি remote backend-এ রাখুন, কারণ দুইজন ব্যক্তি একসাথে apply করলে এমনটি ঘটে:
Error: Error acquiring the state lockOpenTofu হলো Terraform-এর একটি fork, যার কমান্ড এবং ফাইল ফরম্যাট একই। জুলাই 2026 অনুযায়ী, আপনি যদি terraform-এর পরিবর্তে tofu টাইপ করেন, তবে এই গাইডের সবকিছুই কাজ করবে।
Ansible আসলে যা করে
Ansible-এর কোনো agent বা API-এর প্রয়োজন হয় না। এটি একটি SSH connection খোলে, একটি ছোট Python module target-এ কপি করে, সেটি চালায় এবং তারপর মুছে ফেলে। SSH এবং sudo password দিয়ে আপনি যা কিছু অ্যাক্সেস করতে পারেন, Ansible তা কনফিগার করতে পারে।
- 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: trueansible -i inventory.ini web -m ansible.builtin.ping
ansible-playbook -i inventory.ini site.yml --check --diff
ansible-playbook -i inventory.ini site.ymlplaybook ডিবাগ করা শুরু করার আগে ping module-টি SSH, Python এবং sudo-এর কার্যকারিতা যাচাই করে। একটি সফল ফলাফল হলো web1 | SUCCESS => {"ping": "pong"}। --check --diff রান হলো Ansible-এর পরিকল্পনার সবচেয়ে কাছাকাছি বিষয়: এটি কোনো পরিবর্তন না করেই কী কী পরিবর্তন হতে পারে তার রিপোর্ট দেয়। তবে যেসব task আগের task-এর ওপর নির্ভরশীল, check mode-এ সেগুলো ভুল রিপোর্ট দিতে পারে, কারণ আগের পরিবর্তনটি বাস্তবে ঘটেনি।
প্রতিটি রান ok=6 changed=2 unreachable=0 failed=0-এর মতো একটি recap দিয়ে শেষ হয়। একই playbook দুইবার চালান। দ্বিতীয় রানটিতে changed=0 রিপোর্ট করা উচিত। যে task প্রতিবারই changed রিপোর্ট করে তা idempotent নয়, এবং এটি সাধারণত একটি command বা shell task, যা আসলে একটি সঠিক module হওয়া উচিত ছিল। আপনি যদি নতুন হয়ে থাকেন, তবে একটি একক VPS-এ প্রথম Ansible playbook দিয়ে শুরু করুন এবং সেখান থেকে ধীরে ধীরে এগিয়ে যান।
যেখানে টুল দুটি একে অপরের পরিপূরক এবং যেখানে তারা সংঘর্ষে লিপ্ত হয়
Terraform নতুন সার্ভারে remote-exec provisioner ব্যবহার করে কমান্ড চালাতে পারে। HashiCorp-এর নিজস্ব ডকুমেন্টেশনে provisioner-কে শেষ অবলম্বন হিসেবে উল্লেখ করা হয়েছে। এর পেছনে যথেষ্ট কারণ রয়েছে।
একটি provisioner শুধুমাত্র রিসোর্স তৈরির সময় কার্যকর হয়। স্ক্রিপ্ট পরিবর্তন করলে বিদ্যমান সার্ভারে কোনো প্রভাব পড়ে না, কারণ Terraform-এর দৃষ্টিতে রিসোর্সটি ইতিমধ্যে কোডের সাথে সামঞ্জস্যপূর্ণ। Provisioner-এর ধাপগুলো কখনোই terraform plan-এ দেখা যায় না, তাই আপনার রিভিউতে এগুলোর কোনো চিহ্ন থাকে না। যদি স্ক্রিপ্টটি ব্যর্থ হয়, তবে Terraform রিসোর্সটিকে tainted হিসেবে চিহ্নিত করে এবং পরবর্তী apply কমান্ডে এমন একটি সার্ভার ধ্বংস ও পুনর্নির্মাণ করে যা সম্ভবত ঠিকঠাকই ছিল।
এই ব্যর্থতাটি ভুল সময়ে ঘটে। প্রোভাইডার সার্ভারটিকে তৈরি হিসেবে রিপোর্ট করে ঠিক সেই মুহূর্তে যখন API তা নিশ্চিত করে, অথচ অপারেটিং সিস্টেম তখনো বুট হচ্ছে এবং sshd তখনো লিসেনিং মোডে আসেনি।
Error: remote-exec provisioner error
timeout - last error: dial tcp 203.0.113.10:22: connect: connection refusedAnsible-এর ক্ষেত্রে বিপরীত প্রলোভন কাজ করে। ক্লাউড মডিউলগুলো সার্ভার তৈরি করতে পারে এবং অল্প সংখ্যক মেশিনের জন্য এটি কার্যকর। তবে এতে আপনি dependency graph এবং state file-এর সুবিধা হারাবেন। Ansible অনায়াসেই একটি রিসোর্স তৈরি করবে, কিন্তু আপনার playbook থেকে টাস্কটি মুছে ফেললে রিসোর্সটি চালু থাকবে এবং বিল হতে থাকবে, কারণ এটি যে আপনার তৈরি করা ছিল তা কোথাও রেকর্ড করা নেই।
এ থেকে যে নিয়মটি বেরিয়ে আসে তা হলো: API দ্বারা তৈরি এবং ধ্বংস করা যায় এমন অবজেক্টগুলোর মালিকানা Terraform-কে দিন, আর একটি বুট হওয়া অপারেটিং সিস্টেমের ভেতরের সবকিছুর দায়িত্ব Ansible-এর ওপর ছেড়ে দিন।
হ্যান্ডঅফ, সম্পন্ন
হ্যান্ডঅফ হলো একটি সীমানা, কোনো ইন্টিগ্রেশন নয়। Terraform তার কাজ শেষ করে, একটি ঠিকানা প্রকাশ করে এবং থেমে যায়। Ansible সেই ঠিকানা থেকে কাজ শুরু করে।
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.ymlterraform output -raw কোনো উদ্ধৃতি চিহ্ন বা JSON র্যাপার ছাড়াই একটি মান প্রিন্ট করে, যা শেল সাবস্টিটিউশনের ভেতরে আপনার প্রয়োজন। একাধিক সার্ভারের ক্ষেত্রে terraform output -json ব্যবহার করুন এবং তা থেকে ইনভেন্টরি তৈরি করুন, কারণ -raw শুধুমাত্র একটি স্ট্রিং, সংখ্যা বা বুলিয়ান নিয়ে কাজ করতে পারে।
এই দুটি টুলের মাঝে ping ধাপটি বজায় রাখা জরুরি। এটি "Terraform আমাকে ভুল ঠিকানা দিয়েছে" এবং "আমার প্লেবুকে বাগ আছে" - এই দুটি সমস্যার মধ্যে পার্থক্য তৈরি করে। নতুন সার্ভারে প্লেবুক সরাসরি চালানো হলে এই দুটি সমস্যাকে একই রকম মনে হতে পারে।
Terraform state-কে Ansible inventory হিসেবে পড়া
আপনি যদি কোনো inventory ফাইল লিখতে না চান, তবে cloud.terraform কালেকশন সরাসরি state ফাইল থেকে তথ্য পড়তে পারে।
ansible-galaxy collection install cloud.terraformআপনার playbook-এর পাশে terraform.yml লিখুন:
plugin: cloud.terraform.terraform_provider
project_path: /home/deploy/infraansible-inventory -i terraform.yml --graph
ansible-playbook -i terraform.yml site.ymlএটি ব্যবহার করার আগে দুটি বিষয় জেনে রাখা প্রয়োজন। প্লাগিনটি project_path-এর বিপরীতে terraform show চালায়, তাই সেই ডিরেক্টরি অবশ্যই আগে থেকে initialized থাকতে হবে, অন্যথায় প্লাগিনটি কাজ করবে না। এটি আপনার সার্ভার রিসোর্স থেকে নিজে থেকে কোনো host তৈরি করে না: এটি ansible_host এবং ansible_group রিসোর্সগুলো পড়ে, যা আপনি Ansible প্রোভাইডার ব্যবহার করে আপনার Terraform কোডে ঘোষণা করেছেন। আপনি সেগুলোকে যোগ না করা পর্যন্ত ansible-inventory --graph-এ কিছুই দেখা যাবে না।
একটি সাধারণ জেনারেট করা inventory ফাইল ডিবাগ করা সহজ এবং এটি যেকোনো প্রোভাইডারের সাথে কাজ করে। যখন inventory-তে মেশিনের সংখ্যা কয়েকটির বেশি হয়ে যায় এবং হাতে এডিট করতে গিয়ে টাইপো বা ভুল হওয়ার সম্ভাবনা তৈরি হয়, তখনই এই প্লাগিনটি কার্যকর হয়ে ওঠে। এটি সেই পর্যায়, যখন একটি কন্ট্রোল মেশিন থেকে একাধিক Linux সার্ভার পরিচালনা করা কেবল একটি অভ্যাসের বদলে একটি প্রকৃত কর্মপ্রক্রিয়া হয়ে দাঁড়ায়।
আপনার কি সত্যিই Terraform প্রয়োজন?
এটি যারা পড়ছেন তাদের বেশিরভাগেরই, অন্তত এই মুহূর্তে, Terraform-এর প্রয়োজন নেই। যখন পরিকাঠামো তৈরি এবং ধ্বংস করা একটি নিয়মিত কাজ হয়ে দাঁড়ায়, তখনই Terraform তার উপযোগিতা প্রমাণ করে। আপনি যদি কন্ট্রোল প্যানেলের মাধ্যমে একটি VPS অর্ডার করেন এবং সেটি দুই বছর ধরে ব্যবহার করার পরিকল্পনা করেন, তবে Terraform এমন একটি কাজের বর্ণনা দেয় যা মাত্র একবারই ঘটে এবং এটি এমন একটি state file তৈরি করে যা আপনার কোনোভাবেই হারানো উচিত নয়।
Terraform ব্যবহার করুন যখন আপনি ঘনঘন পরিবেশ (environment) পুনর্নির্মাণ করেন, যখন staging-কে production-এর সাথে হুবহু মিল রাখতে হয়, যখন একাধিক ব্যক্তি পরিকাঠামো পরিবর্তন করেন এবং কোনো কিছু মুছে ফেলার আগে আপনি একটি পর্যালোচনাযোগ্য পরিকল্পনা চান, অথবা যখন আপনার ব্যবস্থাপনার পরিধি সার্ভার ছাড়িয়ে DNS রেকর্ড, লোড ব্যালেন্সার এবং ফায়ারওয়াল রুল পর্যন্ত বিস্তৃত হয় যা কোনো প্রোভাইডার API-তে থাকে।
সার্ভারগুলো যখন দীর্ঘস্থায়ী এবং সংখ্যায় কম হয়, এবং যখন প্রতিদিনের প্রশ্ন থাকে "এই বক্সটি কি সঠিকভাবে কনফিগার করা আছে" না কি "এই বক্সটি কি আদৌ বিদ্যমান", তখন শুধুমাত্র Ansible ব্যবহার করাই শ্রেয়। একটি সিঙ্গেল playbook যা একটি নতুন সার্ভারকে সুরক্ষিত (harden) করে, তা নতুন VPS-এ প্রথম দশ মিনিট-এর মতোই কাজ করে, তবে এর সুবিধা হলো এটি পরবর্তী সার্ভারেও একইভাবে কাজ করে।
শেখার ক্রমটি এখান থেকেই নির্ধারিত হয়। আপনার মালিকানাধীন প্রথম সার্ভার থেকেই Ansible-এর সুফল পাওয়া যায়। আর 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 লিসেন করার আগেই API একটি অ্যাড্রেস প্রদান করেছে। একটি নির্দিষ্ট সময় ধরে sleep না করিয়ে বরং পোর্টটি ওপেন হওয়ার জন্য অপেক্ষা করুন। Ansible-এ ঠিক এই কাজের জন্য ansible.builtin.wait_for_connection রয়েছে, যা প্লে-বুকের প্রথম টাস্ক হিসেবে চালান। যখন একই প্লে-বুক একটি নতুন সার্ভারের পরিবর্তে একটি গ্রুপকে টার্গেট করবে, তখন আগে থেকেই সিদ্ধান্ত নিন কোনো হোস্ট আনরিচেবল থাকলে কী করতে হবে, কারণ Ansible সেই হোস্টটিকে বাকি রান থেকে বাদ দিয়ে দেয় এবং শুধুমাত্র রিক্যাপ লাইনেই আপনাকে তা জানায়।
হোস্ট কি (host key) পরিবর্তিত হয়েছে। আপনি সার্ভারটি ডিলিট করে পুনরায় তৈরি করেছেন, এবং নতুন সার্ভারটি একই অ্যাড্রেসে নতুন একটি কি (key) নিয়ে রেসপন্স করছে।
Host key verification failed.ssh-keygen -R 203.0.113.10 ব্যবহার করে পুরনো এন্ট্রিটি মুছে ফেলুন। Terraform যখন বারবার রিবিল্ড করে, তখন এটি প্রায়ই ঘটে। যে মেশিনে ডেটা থাকে, সেগুলোতে রিবিল্ডের সংখ্যা কম রাখাই ভালো।
Sudo ব্যর্থ হচ্ছে। fatal: [web1]: FAILED! => {"msg": "Missing sudo password"} মানে হলো ওই হোস্টে become: true-এর জন্য পাসওয়ার্ড প্রয়োজন। হয় ডেপ্লয় ইউজারকে পাসওয়ার্ডহীন sudo ব্যবহারের অনুমতি দিন, অথবা --ask-become-pass ফ্ল্যাগটি ব্যবহার করুন।
Terraform এমন কিছু ডিলিট করতে চাইছে যা আপনি পরিবর্তন করেননি। প্ল্যানে এমন পরিবর্তন দেখাচ্ছে যা আপনি লেখেননি, এর মানে হলো ইনফ্রাস্ট্রাকচার কোড থেকে সরে গেছে (drift)। সাধারণত কেউ প্রোভাইডারের ওয়েব প্যানেল থেকে কোনো সেটিং পরিবর্তন করলে এমন হয়। পার্থক্যটি দেখার জন্য terraform plan -refresh-only চালান, তারপর সিদ্ধান্ত নিন কোড ভুল নাকি লাইভ রিসোর্স। লাইন বাই লাইন ব্যাখ্যা করতে পারেন না এমন কোনো ডিস্ট্রাক্টিভ প্ল্যান কখনোই apply করবেন না।
Ansible প্রতিবারই 'changed' রিপোর্ট করছে। কোনো shell টাস্ক যদি creates বা when গার্ড ছাড়া থাকে, তবে তা প্রতিবারই রান করবে। এটি কেবল একটি কসমেটিক সমস্যা নয়, কারণ এর ফলে আপনি আর changed=0-কে সার্ভারটি আপনার কাঙ্ক্ষিত অবস্থায় আছে কি না তা বোঝার সংকেত হিসেবে ব্যবহার করতে পারবেন না।
FAQ
Terraform কি Ansible-এর বিকল্প হতে পারে?
সার্ভারের ভেতরের কনফিগারেশনের জন্য নয়। Terraform remote-exec provisioner ব্যবহার করে স্ক্রিপ্ট চালাতে পারে, কিন্তু সেগুলো শুধুমাত্র রিসোর্স তৈরির সময় কার্যকর হয়, কখনোই terraform plan-এ দেখা যায় না এবং ব্যর্থ হলে রিসোর্সটিকে taint করে দেয়, যার ফলে পরবর্তী apply-এর সময় সেটি ধ্বংস করে নতুন করে তৈরি করা হয়। nginx আগে থেকেই ইনস্টল করা আছে কি না তা পরীক্ষা করে কোনো ব্যবস্থা না নেওয়ার মতো কোনো মডিউল Terraform-এ নেই। তাই মেশিন তৈরির জন্য Terraform ব্যবহার করুন এবং এরপর Ansible-এর হাতে দায়িত্ব তুলে দিন।
Ansible কি Terraform-এর বিকল্প হতে পারে?
অল্প সংখ্যক দীর্ঘস্থায়ী সার্ভারের ক্ষেত্রে, হ্যাঁ। Ansible-এর ক্লাউড মডিউলগুলো সার্ভার তৈরি করতে পারে এবং আপনি যদি দুটি VPS ইনস্ট্যান্স নিয়ে সেগুলো ব্যবহার করতে থাকেন, তবে তা যথেষ্ট। আপনি যা হারাবেন তা হলো state file এবং dependency graph: playbook থেকে কোনো টাস্ক সরিয়ে ফেললে রিসোর্সটি চলতে থাকে এবং বিল বাড়তে থাকে, কারণ Ansible কখনোই রেকর্ড করে না যে এটি তার তৈরি করা। Terraform এক্ষেত্রে ধ্বংস করার পরিকল্পনা (destroy plan) দেখাত।
আমার কোনটি আগে শেখা উচিত?
আপনার যদি বর্তমানে সার্ভার থাকে, তবে Ansible। এটি প্রথম মেশিন থেকেই সুফল দেয়, SSH ছাড়া আর কিছুর প্রয়োজন হয় না এবং এই দক্ষতা আপনি হাতে তৈরি করা সার্ভারের ক্ষেত্রেও প্রয়োগ করতে পারেন। Terraform-এর সুফল পাওয়া যায় পরে, যখন আপনি বারবার এনভায়রনমেন্ট তৈরি করেন অথবা সার্ভারের বাইরেও DNS রেকর্ড বা ফায়ারওয়াল রুলের মতো প্রোভাইডার রিসোর্স ম্যানেজ করেন।
Terraform থেকে নতুন সার্ভারের IP কীভাবে Ansible-এ পাঠাব?
আপনার Terraform কোডে একটি output ঘোষণা করুন এবং apply করার পর সেটি পড়ুন। terraform output -raw web_ip শেল সাবস্টিটিউশনের জন্য সরাসরি মানটি প্রিন্ট করে এবং যখন একাধিক হোস্ট থাকে তখন terraform output -json একসাথে সব আউটপুট দেয়। এটি একটি ইনভেন্টরি ফাইলে লিখুন অথবা cloud.terraform কালেকশন ইনস্টল করে ansible-inventory -i terraform.yml --graph-কে প্রজেক্ট ডিরেক্টরির দিকে নির্দেশ করুন।
Terraform শেষ হওয়ার পরপরই আমার playbook কেন ব্যর্থ হয়?
প্রোভাইডার API-তে সার্ভার তৈরি হওয়ার সাথে সাথেই সেটিকে তৈরি হিসেবে রিপোর্ট করে, কিন্তু অপারেটিং সিস্টেম তখনো বুট হতে থাকে, তাই প্রথম কয়েক সেকেন্ড SSH সংযোগ প্রত্যাখ্যান করা হয়। এই ত্রুটিটি হলো UNREACHABLE! এবং এর সাথে Connection refused থাকে। কতক্ষণ অপেক্ষা করতে হবে তা অনুমান না করে ansible.builtin.wait_for_connection-কে play-এর প্রথম টাস্ক হিসেবে ব্যবহার করুন, কারণ ইমেজ এবং প্ল্যান অনুযায়ী বুট হওয়ার সময় ভিন্ন হতে পারে।