Ansible vs Terraform: Mana Satu Anda Perlu Pilih?
Ketahui perbezaan utama antara Terraform untuk penyediaan infrastruktur dan Ansible untuk konfigurasi pelayan. Fahami cara kedua-dua alat ini berfungsi bersama.
Ansible berbanding Terraform dalam satu ayat
Ansible berbanding Terraform bukanlah pilihan antara dua alat yang melakukan tugas yang sama. Terraform mengisytiharkan infrastruktur yang wujud: pelayan, cakera, rangkaian, rekod DNS. Ansible mengisytiharkan keadaan sebenar di dalam mesin yang sudah sedia ada: pakej, pengguna, fail konfigurasi, servis yang berjalan. Terraform mencipta VPS. Ansible menukarkan VPS tersebut menjadi pelayan web.
Kedua-duanya bersifat deklaratif, dan kedua-duanya dipanggil sebagai infrastruktur sebagai kod (IaC). Perbezaan sebenar ialah perkara yang diingati oleh kedua-duanya. Terraform menulis fail keadaan (state file) yang memetakan setiap sumber dalam kod anda kepada objek sebenar yang diciptanya melalui API, supaya ia boleh menentukan bahawa memadam lima baris kod bermakna satu pelayan perlu dimusnahkan. Ansible tidak mengingati apa-apa antara setiap pelaksanaan. Ia bersambung melalui SSH, memeriksa mesin tersebut, dan hanya mengubah perkara yang belum sepadan dengan playbook.
Satu perbezaan itu menjelaskan keseluruhan panduan ini, termasuk sebab mengapa menggabungkan kedua-dua tugas ke dalam satu alat akan mendatangkan masalah.
What Terraform actually does
Terraform talks to an API through a provider plugin. Your provider's registry page defines the resource types you may write, so a server on one host and a server on another are different resource names with different arguments.
resource "cloud_server" "web" {
name = "web1"
image = "ubuntu-24.04"
type = "small"
}
output "web_ip" {
value = cloud_server.web.ipv4_address
}Replace cloud_server with the resource type your provider documents. The output block is the important part for this guide, because it is how the address leaves Terraform.
terraform init
terraform fmt -check
terraform validate
terraform plan -out=tfplan
terraform apply tfplanterraform init downloads the provider and writes a lock file. terraform plan prints the difference between your code and the state file, ending in a line like Plan: 1 to add, 0 to change, 0 to destroy. Read that line every time. Some arguments cannot be changed in place, and the plan says so with # forces replacement next to the attribute, followed by 1 to add, 0 to change, 1 to destroy. Applying that plan deletes the server and builds a new empty one, which is how people lose data they thought was safe.
Saving the plan to a file and applying the file, rather than running a bare terraform apply, means the thing you reviewed is the thing that runs. Between the two commands, someone else may have changed the infrastructure.
terraform.tfstate is the memory. Lose it and Terraform no longer knows those servers are yours, so the next apply tries to create duplicates. Keep it in a remote backend as soon as more than one person runs the commands, because two people applying at once produces this:
Error: Error acquiring the state lockOpenTofu is a fork of Terraform with the same commands and the same file format. As of July 2026, everything in this guide works if you type tofu instead of terraform.
Apakah fungsi sebenar Ansible
Ansible tidak memerlukan ejen mahupun API. Ia membuka sambungan SSH, menyalin modul Python kecil ke sasaran, menjalankannya, kemudian memadamkannya. Apa sahaja yang boleh dicapai melalui SSH dan kata laluan sudo, boleh dikonfigurasikan oleh 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.ymlModul ping menguji SSH, Python dan sudo sebelum anda mula menyahpepijat playbook. Hasil yang sihat ialah web1 | SUCCESS => {"ping": "pong"}. Larian --check --diff adalah perkara paling hampir dengan pelan dalam Ansible: ia melaporkan perkara yang akan berubah tanpa melakukan sebarang perubahan, walaupun tugasan yang bergantung pada tugasan terdahulu mungkin melaporkan maklumat yang salah dalam mod semakan, kerana perubahan terdahulu tidak pernah berlaku.
Setiap larian berakhir dengan ringkasan seperti ok=6 changed=2 unreachable=0 failed=0. Jalankan playbook yang sama sebanyak dua kali. Larian kedua sepatutnya melaporkan changed=0. Tugasan yang melaporkan perubahan pada setiap larian adalah tidak idempoten, dan ia biasanya merupakan tugasan command atau shell yang sepatutnya menggunakan modul sebenar. Jika ini adalah perkara baharu bagi anda, mulakan dengan playbook Ansible pertama pada satu VPS dan kembangkan dari situ.
Di mana kedua-dua alat bertindih, dan di mana ia bercanggah
Terraform boleh menjalankan arahan pada pelayan baharu dengan provisioner remote-exec. Dokumentasi HashiCorp sendiri menyifatkan provisioner sebagai langkah terakhir. Terdapat sebab yang kukuh untuk perkara ini.
Provisioner hanya berjalan apabila sumber dicipta. Ubah suai skrip dan tiada apa-apa yang berlaku pada pelayan sedia ada, kerana dari sudut pandangan Terraform, sumber tersebut sudah sepadan dengan kod. Langkah provisioner tidak pernah muncul dalam terraform plan, jadi semakan anda tidak menunjukkan sebarang tanda mengenainya. Jika skrip gagal, Terraform menandakan sumber tersebut sebagai tainted, dan apply seterusnya akan memusnahkan serta membina semula pelayan yang mungkin berada dalam keadaan baik.
Kegagalan ini juga berlaku pada masa yang tidak sesuai. Provider melaporkan pelayan sebagai telah dicipta sebaik sahaja API mengesahkannya, sedangkan sistem pengendalian masih dalam proses but dan sshd belum lagi mendengar (listening).
Error: remote-exec provisioner error
timeout - last error: dial tcp 203.0.113.10:22: connect: connection refusedAnsible mempunyai godaan yang bertentangan. Modul awan boleh mencipta pelayan, dan untuk sebilangan kecil mesin, ia berfungsi. Apa yang anda korbankan ialah graf dependensi dan fail state. Ansible akan dengan senang hati mencipta sumber, tetapi jika anda memadamkan tugas tersebut daripada playbook anda, sumber itu akan terus berjalan dan terus dibilkan, kerana tiada rekod yang menyatakan ia pernah menjadi milik anda.
Peraturan yang terhasil daripada ini: biarkan Terraform mengurus objek yang dicipta dan dimusnahkan oleh API, dan biarkan Ansible mengurus segala-galanya di dalam sistem pengendalian yang telah but.
Handoff yang berjaya
Handoff merupakan sempadan, bukannya integrasi. Terraform selesai, menerbitkan alamat, dan berhenti. Ansible bermula daripada alamat tersebut.
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 mencetak satu nilai tanpa tanda petik dan tanpa pembungkus JSON, iaitu apa yang anda perlukan di dalam penggantian shell. Untuk beberapa pelayan, gunakan terraform output -json dan bina inventori daripadanya, memandangkan -raw hanya mengendalikan satu rentetan, nombor atau boolean sahaja.
Langkah ping antara kedua-dua alatan ini wajar dikekalkan. Ia memisahkan masalah "Terraform memberikan alamat yang salah" daripada "playbook saya mempunyai pepijat", dan kedua-dua masalah ini kelihatan serupa apabila playbook adalah perkara pertama yang menyentuh kotak baharu tersebut.
Membaca state Terraform sebagai inventori Ansible
Jika anda lebih gemar untuk tidak menulis fail inventori langsung, koleksi cloud.terraform membaca state tersebut secara terus.
ansible-galaxy collection install cloud.terraformTulis terraform.yml bersebelahan dengan playbook anda:
plugin: cloud.terraform.terraform_provider
project_path: /home/deploy/infraansible-inventory -i terraform.yml --graph
ansible-playbook -i terraform.yml site.ymlTerdapat dua perkara yang perlu diketahui sebelum anda bergantung kepadanya. Pemalam ini menjalankan terraform show terhadap project_path, jadi direktori tersebut mestilah sudah dimulakan (initialized) atau pemalam akan gagal. Ia juga tidak mencipta hos daripada sumber pelayan anda: ia membaca sumber ansible_host dan ansible_group, yang anda isytiharkan dalam kod Terraform anda menggunakan penyedia Ansible. Tiada apa-apa yang akan muncul dalam ansible-inventory --graph sehingga anda menambahkannya.
Fail inventori yang dijana secara biasa lebih mudah untuk dinyahpepijat dan berfungsi dengan mana-mana penyedia. Pemalam ini memberikan hasil yang berbaloi sebaik sahaja inventori telah berkembang melebihi beberapa buah mesin dan penyuntingan manual mula menghasilkan ralat taip, iaitu titik yang sama di mana menguruskan beberapa pelayan Linux daripada satu mesin kawalan menjadi aliran kerja sebenar dan bukannya sekadar tabiat.
Adakah anda benar-benar memerlukan Terraform?
Kebanyakan pembaca tidak memerlukannya, sekurang-kurangnya buat masa ini. Terraform memberikan nilai pulangan apabila tugas mencipta dan memadam infrastruktur dilakukan berulang kali. Jika anda memesan satu VPS melalui panel kawalan dan berhasrat untuk mengekalkannya selama dua tahun, Terraform hanya menerangkan sesuatu yang berlaku sekali sahaja, serta menambah fail state yang tidak boleh hilang.
Gunakan Terraform apabila anda kerap membina semula persekitaran, apabila staging perlu sepadan dengan production sepenuhnya, apabila beberapa orang mengubah infrastruktur dan anda mahukan pelan yang boleh disemak sebelum sebarang pemadaman dilakukan, atau apabila pengurusan anda melangkaui pelayan kepada DNS record, load balancer dan peraturan firewall yang berada dalam API penyedia.
Kekal dengan Ansible sahaja apabila pelayan bersifat kekal dan jumlahnya sedikit, serta apabila soalan harian ialah "adakah kotak ini dikonfigurasikan dengan betul" dan bukannya "adakah kotak ini wujud". Satu playbook tunggal yang mengeraskan pelayan baharu meliputi skop yang sama seperti sepuluh minit pertama pada VPS baharu, dengan kelebihan bahawa ia berjalan dengan cara yang sama pada pelayan seterusnya.
Urutan pembelajaran mengikut prinsip tersebut. Ansible memberikan hasil pada pelayan pertama yang anda miliki. Terraform memberikan hasil pada persekitaran ketiga yang anda bina semula.
Perkara yang tergendala semasa serahan tugas
Pelayan belum bersedia. Terraform berjaya dilaksanakan, namun Ansible gagal serta-merta.
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 mengembalikan alamat sebelum sshd sedia mendengar. Tunggu port tersebut dibuka dan bukannya menambah tempoh sleep yang tetap. Ansible mempunyai ansible.builtin.wait_for_connection khusus untuk tujuan ini; jalankan ia sebagai tugasan pertama dalam play anda. Apabila playbook yang sama menyasarkan satu kumpulan dan bukan sekadar satu pelayan baharu, tentukan lebih awal apa yang perlu berlaku apabila satu hos tidak dapat dicapai, kerana Ansible akan menggugurkan hos tersebut daripada baki pelaksanaan dan hanya memaklumkan perkara itu pada baris rumusan (recap).
Kunci hos telah berubah. Anda memusnahkan dan mencipta semula pelayan, dan pelayan baharu menjawab pada alamat yang sama dengan kunci yang berbeza.
Host key verification failed.Alih keluar entri lama dengan ssh-keygen -R 203.0.113.10. Perkara ini kerap berlaku apabila Terraform melakukan pembinaan semula, yang merupakan sebab utama untuk mengehadkan pembinaan semula pada mesin yang menyimpan data.
Sudo gagal. fatal: [web1]: FAILED! => {"msg": "Missing sudo password"} bermaksud become: true memerlukan kata laluan pada hos tersebut. Sama ada konfigurasikan sudo tanpa kata laluan untuk pengguna deploy, atau berikan --ask-become-pass.
Terraform ingin memusnahkan sesuatu yang tidak anda ubah. Pelan menunjukkan perubahan yang tidak pernah anda tulis; ini bermakna infrastruktur sebenar telah terpesong daripada kod, biasanya kerana seseorang menukar tetapan dalam panel web penyedia. Jalankan terraform plan -refresh-only untuk melihat perbezaan tersebut secara khusus, kemudian tentukan sama ada kod atau sumber sebenar yang salah. Jangan sekali-kali melaksanakan pelan yang bersifat merosakkan jika anda tidak dapat menjelaskan setiap barisnya.
Ansible melaporkan perubahan pada setiap pelaksanaan. Tugasan shell tanpa kawalan creates atau when akan dijalankan tanpa syarat. Ini bukan sekadar masalah kosmetik, kerana ia bermakna anda tidak lagi boleh menggunakan changed=0 sebagai isyarat bahawa pelayan berada dalam keadaan yang anda tetapkan.
FAQ
Bolehkah Terraform menggantikan Ansible?
Tidak untuk konfigurasi di dalam pelayan. Terraform boleh memanggil skrip dengan provisioner remote-exec, tetapi skrip tersebut hanya berjalan semasa penciptaan sumber, tidak pernah muncul dalam terraform plan, dan akan menjejaskan (taint) sumber tersebut jika ia gagal. Ini akan menjadualkan proses musnah dan bina semula pada arahan apply seterusnya. Terraform tidak mempunyai modul yang setara untuk menyemak sama ada nginx sudah dipasang dan tidak melakukan apa-apa jika ia sudah tersedia. Gunakan Terraform untuk mencipta mesin, kemudian serahkan tugas seterusnya kepada Ansible.
Bolehkah Ansible menggantikan Terraform?
Untuk sebilangan kecil pelayan yang kekal lama, ya. Ansible mempunyai modul awan yang boleh mencipta pelayan, dan jika anda menempah dua instans VPS dan mengekalkannya, itu sudah memadai. Apa yang anda hilang ialah fail state dan graf dependency: jika anda membuang satu task daripada playbook, sumber tersebut akan terus berjalan dan terus dicaj, kerana Ansible tidak pernah merekodkan bahawa ia yang menciptanya. Terraform sebaliknya akan merancang proses musnah (destroy).
Yang mana satu patut saya pelajari dahulu?
Ansible, jika anda sudah memiliki pelayan sekarang. Ia memberikan hasil pada mesin pertama, tidak memerlukan apa-apa selain SSH, dan kemahiran tersebut boleh digunakan pada pelayan yang anda tempah secara manual. Terraform memberikan hasil kemudian, apabila anda membina semula persekitaran secara berulang atau mengurus sumber penyedia selain pelayan, seperti rekod DNS dan peraturan firewall.
Bagaimanakah cara untuk menghantar IP pelayan baharu daripada Terraform ke Ansible?
Isytiharkan output dalam kod Terraform anda, kemudian baca nilainya selepas proses apply selesai. terraform output -raw web_ip mencetak nilai mentah untuk substitusi shell, dan terraform output -json memberikan semua output sekaligus apabila terdapat beberapa hos. Tulis nilai tersebut ke dalam fail inventori, atau pasang koleksi cloud.terraform dan halakan ansible-inventory -i terraform.yml --graph ke direktori projek tersebut.
Mengapa playbook saya gagal sejurus selepas Terraform selesai?
Penyedia melaporkan pelayan sebagai telah dicipta sebaik sahaja API mereka mengesahkannya, sedangkan sistem operasi mungkin masih dalam proses but, menyebabkan sambungan SSH ditolak untuk beberapa saat pertama. Ralat yang berlaku ialah UNREACHABLE! dengan Connection refused. Jadikan ansible.builtin.wait_for_connection sebagai task pertama dalam play anda daripada meneka tempoh masa tunggu (sleep), kerana masa but berbeza mengikut imej dan pelan yang digunakan.