SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-08-29

Ansible vs Terraform: Mana yang Anda Butuhkan?

Terraform membuat VPS, sedangkan Ansible mengonfigurasinya. Pahami perbedaannya, handoff command, risiko provisioner, dan kapan cukup memakai Ansible.

Ansible vs Terraform dalam satu kalimat

Ansible vs Terraform bukan pilihan antara dua alat yang melakukan pekerjaan yang sama. Terraform mendeklarasikan infrastruktur yang tersedia: server, disk, jaringan, dan catatan DNS. Ansible mendeklarasikan kondisi yang harus dipenuhi di dalam mesin yang sudah tersedia: paket, pengguna, file konfigurasi, dan service yang berjalan. Terraform membuat VPS. Ansible mengubah VPS tersebut menjadi web server.

Keduanya bersifat deklaratif dan disebut infrastructure as code (IaC). Perbedaan sebenarnya terletak pada hal yang diingat oleh masing-masing alat. Terraform menulis file state yang memetakan setiap resource dalam kode Anda ke objek nyata yang dibuat melalui API. Dengan demikian, Terraform dapat mengetahui bahwa penghapusan lima baris berarti satu server harus dihancurkan. Ansible tidak menyimpan apa pun di antara eksekusi. Ansible terhubung melalui SSH, memeriksa mesin, lalu hanya mengubah hal yang belum sesuai dengan playbook.

Satu perbedaan ini menjelaskan bagian lain dalam panduan ini, termasuk alasan mencampur kedua pekerjaan tersebut ke dalam satu alat dapat menimbulkan masalah.

Apa yang sebenarnya dilakukan Terraform

Terraform berkomunikasi dengan API melalui plugin provider. Halaman registry provider Anda menentukan jenis resource yang dapat ditulis. Karena itu, server pada satu host dan server pada host lain memiliki nama resource dan argumen yang berbeda.

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

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

Ganti cloud_server dengan jenis resource yang didokumentasikan oleh provider Anda. Blok output adalah bagian penting dalam panduan ini karena blok tersebut menentukan cara alamat IP keluar dari Terraform.

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

terraform init mengunduh provider dan menulis lock file. terraform plan menampilkan perbedaan antara kode dan state file Anda, lalu diakhiri dengan baris seperti Plan: 1 to add, 0 to change, 0 to destroy. Baca baris tersebut setiap kali. Beberapa argumen tidak dapat diubah secara langsung. Plan menandainya dengan # forces replacement di sebelah atribut, lalu menampilkan 1 to add, 0 to change, 1 to destroy. Saat plan tersebut diterapkan, server dihapus dan server kosong yang baru dibuat. Inilah penyebab orang kehilangan data yang mereka kira aman.

Menyimpan plan ke file lalu menerapkan file tersebut, bukan menjalankan terraform apply secara langsung, memastikan bahwa konfigurasi yang Anda tinjau adalah konfigurasi yang dijalankan. Di antara kedua perintah tersebut, orang lain mungkin telah mengubah infrastruktur.

terraform.tfstate adalah memorinya. Jika file tersebut hilang, Terraform tidak lagi mengetahui bahwa server-server tersebut adalah milik Anda. Akibatnya, apply berikutnya mencoba membuat duplikat. Simpan file tersebut dalam remote backend segera setelah lebih dari satu orang menjalankan perintah, karena dua orang yang menjalankan apply secara bersamaan menghasilkan kondisi berikut:

Error: Error acquiring the state lock

OpenTofu adalah fork dari Terraform dengan perintah dan format file yang sama. Per Juli 2026, semua hal dalam panduan ini berfungsi jika Anda mengetik tofu sebagai ganti terraform.

Apa yang sebenarnya dilakukan Ansible

Ansible tidak memerlukan agent atau API. Ansible membuka koneksi SSH, menyalin modul Python kecil ke target, menjalankannya, lalu menghapusnya. Apa pun yang dapat Anda akses melalui SSH dan kata sandi sudo dapat dikonfigurasi 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 memverifikasi SSH, Python, dan sudo sebelum Anda mulai men-debug playbook. Hasil yang sehat adalah web1 | SUCCESS => {"ping": "pong"}. Opsi --check --diff adalah hal yang paling mendekati rencana dalam Ansible: opsi ini melaporkan perubahan yang akan dilakukan tanpa menerapkannya. Namun, task yang bergantung pada task sebelumnya dapat melaporkan hasil yang keliru dalam check mode karena perubahan sebelumnya tidak pernah benar-benar diterapkan.

Setiap eksekusi berakhir dengan ringkasan seperti ok=6 changed=2 unreachable=0 failed=0. Jalankan playbook yang sama dua kali. Eksekusi kedua seharusnya melaporkan changed=0. Task yang melaporkan changed pada setiap eksekusi tidak idempotent. Biasanya, task tersebut berupa task command atau shell yang seharusnya menggunakan modul nyata. Jika ini masih baru bagi Anda, mulai dengan playbook Ansible pertama pada satu VPS dan kembangkan dari sana.

Di mana kedua alat ini saling tumpang tindih dan di mana keduanya berkonflik

Terraform dapat menjalankan perintah pada server baru dengan provisioner remote-exec. Dokumentasi HashiCorp sendiri menyebut provisioner sebagai pilihan terakhir. Ada alasan yang jelas untuk itu.

Provisioner hanya berjalan saat resource dibuat. Jika skrip diedit, tidak ada perubahan pada server yang sudah ada karena dari sudut pandang Terraform, resource tersebut sudah sesuai dengan kode. Langkah provisioner tidak pernah muncul dalam terraform plan, sehingga hasil peninjauan tidak menunjukkan keberadaannya. Jika skrip gagal, Terraform menandai resource sebagai tainted. Pada penerapan berikutnya, Terraform akan menghancurkan dan membangun ulang server yang sebenarnya mungkin masih berfungsi baik.

Kegagalan juga terjadi pada waktu yang tidak tepat. Provider melaporkan server telah dibuat segera setelah API menyatakan demikian, padahal sistem operasi masih melakukan boot dan sshd belum listening.

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

Ansible memiliki risiko sebaliknya. Modul cloud dapat membuat server, dan pendekatan itu dapat digunakan untuk beberapa mesin. Namun, Anda kehilangan dependency graph dan state file. Ansible akan membuat resource tanpa masalah, tetapi jika task tersebut dihapus dari playbook, resource tetap berjalan dan biaya tetap dikenakan karena tidak ada catatan bahwa resource tersebut pernah dikelola oleh Ansible.

Aturan yang dapat diambil dari sini: biarkan Terraform mengelola objek yang dibuat dan dihancurkan oleh API, lalu biarkan Ansible mengelola semua hal di dalam sistem operasi yang sudah melakukan boot.

Serah terima yang berhasil

Serah terima adalah batas antartahap, bukan integrasi. Terraform selesai, menerbitkan alamat, lalu berhenti. Ansible dimulai dari 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 kutip dan tanpa pembungkus JSON. Format ini sesuai untuk digunakan dalam substitusi shell. Untuk beberapa server, gunakan terraform output -json dan buat inventory dari hasilnya, karena -raw hanya menangani satu string, angka, atau boolean.

Langkah ping di antara kedua alat tersebut tetap penting. Langkah ini membedakan masalah "Terraform memberikan alamat yang salah" dari masalah "playbook saya memiliki bug". Kedua masalah tersebut terlihat sama jika playbook adalah hal pertama yang berinteraksi dengan server baru.

Membaca state Terraform sebagai inventori Ansible

Jika Anda tidak ingin menulis file inventori sama sekali, koleksi cloud.terraform membaca state secara langsung.

ansible-galaxy collection install cloud.terraform

Tulis terraform.yml di samping 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

Ada dua hal yang perlu diketahui sebelum mengandalkannya. Plugin menjalankan terraform show terhadap project_path, sehingga direktori tersebut harus sudah diinisialisasi. Jika belum, plugin gagal. Plugin juga tidak membuat host dari resource server Anda: plugin membaca resource ansible_host dan ansible_group, yang Anda deklarasikan dalam kode Terraform menggunakan Ansible provider. Tidak ada yang muncul di ansible-inventory --graph sampai Anda menambahkannya.

File inventori yang dibuat secara biasa lebih mudah di-debug dan berfungsi dengan provider apa pun. Plugin ini mulai bermanfaat setelah inventori berkembang hingga mencakup lebih dari beberapa mesin dan pengeditan manual mulai menimbulkan kesalahan ketik. Pada tahap yang sama, mengelola beberapa server Linux dari satu mesin kontrol menjadi alur kerja nyata, bukan sekadar kebiasaan.

Apakah Anda benar-benar memerlukan Terraform?

Sebagian besar pembaca tidak memerlukannya, setidaknya belum. Terraform sepadan dengan biayanya ketika pembuatan dan penghapusan infrastructure itu sendiri merupakan tugas yang berulang. Jika Anda memesan satu VPS melalui control panel dan berencana menggunakannya selama dua tahun, Terraform hanya mendeskripsikan sesuatu yang terjadi satu kali serta menambahkan state file yang tidak boleh hilang.

Gunakan Terraform ketika Anda sering membangun ulang environment, ketika staging harus sama persis dengan production, ketika beberapa orang mengubah infrastructure dan Anda menginginkan plan yang dapat ditinjau sebelum sesuatu dihapus, atau ketika hal yang Anda kelola mencakup lebih dari sekadar server, seperti DNS record, load balancer, dan firewall rule yang berada dalam provider API.

Gunakan Ansible saja ketika server berumur panjang dan jumlahnya sedikit, serta ketika pertanyaan sehari-hari adalah "apakah server ini telah dikonfigurasi dengan benar", bukan "apakah server ini ada". Satu playbook yang memperkuat keamanan server baru mencakup hal yang sama seperti sepuluh menit pertama pada VPS baru, dengan kelebihan bahwa playbook tersebut berjalan dengan cara yang sama pada server berikutnya.

Urutan pembelajaran mengikuti hal tersebut. Ansible memberikan manfaat sejak server pertama yang Anda miliki. Terraform memberikan manfaat pada environment ketiga yang Anda bangun ulang.

Gangguan saat serah terima

Server belum siap. Terraform berhasil, tetapi Ansible langsung gagal.

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 mulai listening. Tunggu port tersebut, bukan menambahkan jeda tetap. Ansible menyediakan ansible.builtin.wait_for_connection untuk keperluan ini. Jalankan sebagai task pertama dalam play. Setelah playbook yang sama menargetkan sebuah group, bukan satu server baru, tentukan sejak awal apa yang harus terjadi jika satu host tetap tidak dapat dijangkau, karena Ansible mengeluarkan host tersebut dari sisa proses dan baris recap adalah satu-satunya tempat Ansible memberi tahu Anda.

Host key berubah. Anda menghancurkan dan membuat ulang server, lalu server baru merespons pada alamat yang sama dengan key baru.

Host key verification failed.

Hapus entri lama dengan ssh-keygen -R 203.0.113.10. Hal ini sering terjadi ketika Terraform menangani pembuatan ulang server. Karena itu, sebaiknya pembuatan ulang jarang dilakukan pada mesin yang menyimpan data.

Sudo gagal. fatal: [web1]: FAILED! => {"msg": "Missing sudo password"} berarti become: true memerlukan password pada host tersebut. Konfigurasikan sudo tanpa password untuk deploy user, atau teruskan --ask-become-pass.

Terraform ingin menghancurkan sesuatu yang tidak Anda ubah. Plan menampilkan perubahan yang tidak pernah Anda tulis. Ini berarti infrastruktur nyata telah menyimpang dari kode, biasanya karena seseorang mengubah pengaturan di panel web provider. Jalankan terraform plan -refresh-only untuk melihat perbedaan tersebut saja, lalu tentukan apakah kode atau resource aktif yang salah. Jangan pernah menerapkan plan destruktif yang tidak dapat Anda jelaskan baris demi baris.

Ansible melaporkan changed pada setiap proses. Task shell tanpa guard creates atau when berjalan tanpa syarat. Ini bukan sekadar masalah tampilan, karena Anda tidak lagi dapat menggunakan changed=0 sebagai tanda bahwa server berada dalam kondisi yang diminta.

FAQ

Dapatkah Terraform menggantikan Ansible?

Tidak untuk konfigurasi di dalam server. Terraform dapat menjalankan skrip dengan provisioner remote-exec, tetapi skrip tersebut hanya dijalankan saat resource dibuat, tidak pernah muncul di terraform plan, dan membuat resource berstatus tainted jika gagal. Kondisi ini menjadwalkan penghapusan dan pembuatan ulang pada eksekusi apply berikutnya. Terraform tidak memiliki padanan modul yang memeriksa apakah nginx sudah terpasang dan tidak melakukan apa pun jika memang sudah terpasang. Gunakan Terraform untuk membuat mesin, lalu serahkan pengelolaannya ke Ansible.

Dapatkah Ansible menggantikan Terraform?

Untuk sejumlah kecil server yang digunakan dalam jangka panjang, ya. Ansible memiliki modul cloud untuk membuat server. Jika Anda memesan dua instance VPS dan mempertahankannya, kemampuan tersebut sudah memadai. Namun, Anda kehilangan state file dan dependency graph. Jika Anda menghapus suatu task dari playbook, resource tetap berjalan dan tetap menimbulkan biaya karena Ansible tidak pernah mencatat bahwa resource tersebut dibuat olehnya. Terraform akan merencanakan penghapusan resource tersebut.

Mana yang sebaiknya saya pelajari terlebih dahulu?

Ansible, jika saat ini Anda mengelola server. Manfaatnya langsung terasa pada mesin pertama, hanya memerlukan SSH, dan keterampilannya dapat diterapkan pada server yang Anda pesan secara manual. Terraform memberikan manfaat setelahnya, ketika Anda berulang kali membuat ulang environment atau mengelola resource milik provider selain server, seperti DNS record dan firewall rule.

Bagaimana cara meneruskan IP server baru dari Terraform ke Ansible?

Deklarasikan output dalam kode Terraform Anda, lalu baca nilainya setelah apply. terraform output -raw web_ip mencetak nilai mentah untuk substitusi shell, sedangkan terraform output -json memberikan semua output sekaligus jika terdapat beberapa host. Tulis nilai tersebut ke dalam inventory file, atau instal collection cloud.terraform dan arahkan ansible-inventory -i terraform.yml --graph ke direktori project.

Mengapa playbook saya gagal tepat setelah Terraform selesai?

Provider melaporkan server sebagai telah dibuat segera setelah API-nya memberikan konfirmasi, sementara sistem operasi masih melakukan booting. Akibatnya, SSH ditolak selama beberapa detik pertama. Error tersebut adalah UNREACHABLE! dengan Connection refused. Jadikan ansible.builtin.wait_for_connection sebagai task pertama dalam play, bukan menebak durasi sleep, karena waktu boot berbeda-beda bergantung pada image dan plan.