SSD Nodes Learn 🎉 VPS dari $5.50/bln
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-07

Ansible vs Terraform: Mana Satu Anda Perlu Pilih?

Ketahui perbezaan utama antara Terraform yang mengurus infrastruktur dan Ansible untuk konfigurasi pelayan. Dapatkan panduan praktikal tentang cara menggabungkan kedua-duanya.

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 sedang berjalan. Terraform mencipta VPS. Ansible menukar VPS tersebut menjadi pelayan web.

Kedua-duanya bersifat deklaratif, dan kedua-duanya dipanggil sebagai infrastructure as code (IaC). Perbezaan sebenar terletak pada perkara yang diingati oleh setiap alat. Terraform menulis fail state yang memetakan setiap sumber dalam kod anda kepada objek sebenar yang dicipta 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 menyambung melalui SSH, memeriksa mesin, dan hanya mengubah perkara yang belum sepadan dengan playbook.

Satu perbezaan itu menjelaskan seluruh panduan ini, termasuk sebab mengapa menggabungkan kedua-dua tugas ke dalam satu alat akan membawa kepada masalah.

Apa yang Terraform sebenarnya lakukan

Terraform berhubung dengan API melalui pemalam penyedia (provider plugin). Halaman pendaftaran penyedia anda menentukan jenis sumber yang boleh anda tulis, jadi pelayan pada satu hos dan pelayan pada hos lain adalah nama sumber yang berbeza dengan argumen yang berbeza.

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

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

Gantikan cloud_server dengan jenis sumber yang didokumenkan oleh penyedia anda. Blok output adalah bahagian penting untuk panduan ini, kerana ia merupakan cara alamat tersebut keluar daripada Terraform.

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

terraform init memuat turun penyedia dan menulis fail kunci (lock file). terraform plan mencetak perbezaan antara kod anda dan fail keadaan (state file), yang berakhir dengan baris seperti Plan: 1 to add, 0 to change, 0 to destroy.. Baca baris itu setiap kali. Sesetengah argumen tidak boleh ditukar secara terus (in-place), dan pelan tersebut menyatakan perkara itu dengan # forces replacement di sebelah atribut, diikuti oleh 1 to add, 0 to change, 1 to destroy. Melaksanakan pelan tersebut akan memadamkan pelayan dan membina pelayan kosong yang baharu, yang merupakan cara pengguna kehilangan data yang mereka sangka selamat.

Menyimpan pelan ke dalam fail dan melaksanakan fail tersebut, berbanding menjalankan terraform apply secara terus, bermakna perkara yang anda semak adalah perkara yang akan dijalankan. Di antara kedua-dua arahan tersebut, orang lain mungkin telah mengubah infrastruktur.

terraform.tfstate ialah memorinya. Jika ia hilang, Terraform tidak lagi mengetahui bahawa pelayan tersebut adalah milik anda, jadi pelaksanaan (apply) seterusnya akan cuba mencipta pendua. Simpannya dalam backend jauh (remote backend) sebaik sahaja lebih daripada seorang menjalankan arahan tersebut, kerana dua orang yang melakukan pelaksanaan serentak akan menghasilkan ini:

Error: Error acquiring the state lock

OpenTofu ialah fork bagi Terraform dengan arahan yang sama dan format fail yang sama. Sehingga Julai 2026, segala-galanya dalam panduan ini berfungsi jika anda menaip tofu sebagai ganti 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: 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

Modul ping mengesahkan SSH, Python dan sudo sebelum anda mula menyahpepijat playbook. Hasil yang sihat adalah web1 | SUCCESS => {"ping": "pong"}. Larian --check --diff merupakan fungsi Ansible yang paling hampir dengan pelan: 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 benar-benar 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 ini 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 sebenarnya dalam keadaan baik.

Kegagalan ini juga berlaku pada masa yang tidak sesuai. Provider melaporkan pelayan 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 refused

Ansible 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 dikenakan bayaran, 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.

Penyerahan tugas, berjaya

Penyerahan tugas merupakan satu sempadan, bukan 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.yml

terraform output -raw mencetak satu nilai tanpa tanda petikan dan tanpa pembungkus JSON, iaitu format 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.

Langkah ping antara kedua-dua alat 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 menjadi 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.terraform

Tulis terraform.yml di sebelah playbook anda:

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

Terdapat dua perkara yang perlu diketahui sebelum anda bergantung kepadanya. Pemalam ini menjalankan terraform show terhadap project_path, jadi direktori tersebut mestilah sudah diinisialisasi 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 adalah 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 belum lagi. Terraform memberikan nilai pulangan apabila proses mencipta dan memusnahkan infrastruktur menjadi tugas berulang. 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 apa yang anda uruskan melangkaui pelayan kepada DNS record, load balancer dan peraturan firewall yang berada dalam API penyedia.

Kekal menggunakan Ansible sahaja apabila pelayan mempunyai jangka hayat yang panjang 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 pulangan pada pelayan pertama yang anda miliki. Terraform memberikan pulangan pada persekitaran ketiga yang anda bina semula.

Perkara yang tergendala semasa serahan tugas

Pelayan belum bersedia. Terraform berjaya dilaksanakan, tetapi 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 jeda (sleep) tetap. Ansible mempunyai ansible.builtin.wait_for_connection khusus untuk tujuan ini, jalankan sebagai tugasan pertama dalam play anda.

Host key telah berubah. Anda memusnahkan dan mencipta semula pelayan, dan pelayan baharu menjawab pada alamat yang sama dengan kunci (key) yang berbeza.

Host key verification failed.

Buang 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 (plan) menunjukkan perubahan yang tidak pernah anda tulis, yang bermaksud infrastruktur sebenar telah terpesong daripada kod, biasanya kerana seseorang mengubah tetapan dalam panel web penyedia. Jalankan terraform plan -refresh-only untuk melihat perbezaan tersebut secara berasingan, kemudian tentukan sama ada kod atau sumber sebenar yang salah. Jangan sekali-kali melaksanakan pelan yang bersifat memusnahkan jika anda tidak dapat menjelaskan setiap barisnya.

Ansible melaporkan perubahan pada setiap pelaksanaan. Tugasan shell tanpa pengawal creates atau when akan dijalankan tanpa syarat. Ini bukan sekadar masalah kosmetik, kerana ia bermaksud 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 menanda sumber sebagai rosak (taint) jika gagal. Ini akan menjadualkan proses pemusnahan dan pembinaan 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 hanya menempah dua instans VPS dan mengekalkannya, itu sudah memadai. Apa yang anda hilang ialah fail state dan graf dependensi: jika anda membuang tugasan daripada playbook, sumber tersebut akan terus berjalan dan terus dikenakan bayaran, kerana Ansible tidak pernah merekodkan bahawa ia yang menciptakannya. Terraform sebaliknya akan merancang proses pemusnahan.

Yang mana satu patut saya pelajari dahulu?

Ansible, jika anda sudah memiliki pelayan sekarang. Ia memberikan pulangan hasil pada mesin pertama, tidak memerlukan apa-apa selain SSH, dan kemahiran tersebut boleh digunakan pada pelayan yang anda tempah secara manual. Terraform memberikan pulangan hasil kemudian, apabila anda membina semula persekitaran secara berulang kali 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 output dalam kod Terraform anda, kemudian baca nilai tersebut selepas proses apply selesai. terraform output -raw web_ip mencetak nilai mentah untuk penggantian shell, dan terraform output -json memberikan anda semua output serentak 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.

Mengapa playbook saya gagal sejurus selepas Terraform selesai?

Penyedia melaporkan pelayan sebagai telah dicipta sebaik sahaja API mengesahkannya, sedangkan sistem operasi masih dalam proses but, jadi sambungan SSH ditolak untuk beberapa saat pertama. Ralat yang berlaku ialah UNREACHABLE! dengan Connection refused. Jadikan ansible.builtin.wait_for_connection sebagai tugasan pertama dalam play anda daripada meneka tempoh masa tunggu (sleep), kerana masa but berbeza mengikut imej dan pelan yang digunakan.