Membuat satu VPS lewat web console memang hanya lima menit, tetapi mengulangnya lima puluh kali dengan klik yang sama adalah resep bencana: satu salah pilih region atau satu SSH key yang lupa diunggah, dan armada server kita tidak lagi seragam. Infrastructure as Code (IaC) mengganti klik itu dengan berkas definisi yang bisa disimpan di Git, direview, dan dijalankan ulang berkali-kali dengan hasil identik. Chapter ini membahas pola berpikirnya — deklaratif, terencana, terukur — dengan Terraform sebagai contoh utama. Terraform tidak terpasang di container latihan, jadi kita tulis berkas definisi main.tf sungguhan lalu mensimulasikan siklus plan dengan grep, jq, dan diff yang sudah kita kuasai.
Server Snowflake dan Resep yang Hilang #
Server yang dikonfigurasi lewat klik manual berakhir sebagai snowflake server: unik, indah, dan tidak bisa diciptakan ulang. Prosedurnya hidup di kepala admin atau di utas chat, jadi ketika mesin itu mati, tidak ada cara memastikan penggantinya identik — penyedia cloud menyebut masalah ini dengan pertanyaan yang menusuk: bisakah Anda membangun ulang seluruh infrastruktur dari nol tanpa membuka web console? Jawabannya harus “ya, dalam hitungan menit”, dan jawaban itu hanya mungkin bila setiap sumber daya terdefinisi sebagai teks.
Definisi sebagai teks membawa tiga hak yang tidak dimiliki klik. Pertama, versi: setiap perubahan infrastruktur tercatat sebagai commit Git dengan penulis dan alasannya. Kedua, review: rekan sekerja bisa membaca diff sebelum perubahan menyentuh produksi. Ketiga, rollback: kesalahan dikembalikan dengan git revert lalu menjalankan ulang definisi — pola kerja yang sama dengan membatalkan commit di Chapter Bash Basics
saat kita menulis skrip.
Deklaratif, Bukan Imperatif #
Skrip shell yang kita tulis sepanjang Course ini bersifat imperatif: kita menuliskan langkah demi langkah, dan urutannya menjadi tanggung jawab kita. IaC memilih arah sebaliknya — deklaratif: kita menuliskan hasil akhir yang diinginkan, dan mesin yang menentukan langkahnya. Bandingkan dua kalimat ini: “buat direktori, salin berkas, nyalakan service” versus “service ini harus berjalan dengan konfigurasi ini”. Kalimat kedua bisa diperiksa kapan saja tanpa menduplikasi pekerjaan, karena yang dibandingkan adalah keadaan, bukan sejarah perintah.
Alur kerjanya selalu tiga langkah: tulis definisi, jalankan plan untuk melihat apa yang akan berubah, lalu apply untuk melaksanakannya. Terraform mempopulerkan alur ini dengan berkas HCL; Pulumi menawarkan pola yang sama dengan definisi dalam bahasa umum seperti Python atau TypeScript. Pilihan toolnya selera — pola berpikirnya yang penting.
Membedah main.tf Terraform #
Berikut main.tf yang mendefinisikan satu droplet di penyedia fiktif — aman disalin karena hanya berkas latihan:
cat > main.tf << 'EOF'
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
}
}
}
provider "digitalocean" {
token = var.do_token
}
resource "digitalocean_droplet" "web" {
image = "debian-13-x64"
name = "web-jakarta"
region = "sgp1"
size = "s-1vcpu-1gb"
}
EOF
cat main.tfOutput yang Dihasilkan:
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
}
}
}
provider "digitalocean" {
token = var.do_token
}
resource "digitalocean_droplet" "web" {
image = "debian-13-x64"
name = "web-jakarta"
region = "sgp1"
size = "s-1vcpu-1gb"
}Mari kita bedah blok demi bloknya:
terraform { required_providers { ... } }: mendeklarasikan plugin penyedia yang dibutuhkan beserta sumbernya di registry — Terraform mengunduh plugin ini sebelum bekerja.provider "digitalocean" { token = var.do_token }: konfigurasi koneksi ke API penyedia. Token diambil dari variabelvar.do_token, bukan ditulis mentah — nilainya diberikan lewat environment variable saat eksekusi.resource "digitalocean_droplet" "web": satu resource dengan tipedigitalocean_dropletdan nama logisweb— nama logis dipakai Terraform untuk melacak resource ini di state, terpisah darinamemesinnya.- Empat atribut (
image,name,region,size): keadaan akhir yang kita inginkan — persis kolom-kolom form pembuatan instance dari Chapter Linux Cloud Servers , kini berbentuk teks yang bisa direview.
State, Drift, dan Simulasi plan #
Bagaimana Terraform tahu apa yang harus diubah? Ia menyimpan state: berkas JSON yang mencatat seluruh resource yang pernah dibuatnya, lengkap dengan atributnya. Saat dijalankan, Terraform membaca definisi terbaru, membandingkannya dengan state, lalu menampilkan rencana perubahan — inilah terraform plan. Perbedaan antara dunia nyata dan state disebut drift, biasanya akibat ada admin yang diam-diam mengubah server lewat web console.
Kita bisa mensimulasikan logika plan itu dengan tiga tool terminal. Definisi dan state di bawah sengaja dibuat berselisih di atribut size — seolah droplet di-resize manual dari console:
cat > main.tf << 'EOF'
resource "digitalocean_droplet" "web" {
image = "debian-13-x64"
name = "web-jakarta"
region = "sgp1"
size = "s-1vcpu-1gb"
}
EOF
cat > terraform.tfstate << 'EOF'
{
"version": 4,
"resource": {
"digitalocean_droplet": {
"web": {
"image": "debian-13-x64",
"name": "web-jakarta",
"region": "sgp1",
"size": "s-2vcpu-2gb"
}
}
}
}
EOF
grep -oE '(image|name|region|size)[ ]+=[ ]+"[^"]+"' main.tf | tr -d ' "' | sort > diinginkan.txt
jq -r '.resource.digitalocean_droplet.web | to_entries[] | "\(.key)=\(.value)"' terraform.tfstate | sort > tercatat.txt
echo "-- diinginkan (main.tf):"
cat diinginkan.txt
echo "-- tercatat (state):"
cat tercatat.txt
if diff diinginkan.txt tercatat.txt; then
echo "Plan: 0 to add, 0 to change, 0 to destroy."
else
echo "Plan: ada perbedaan — terraform akan mengembalikan size sesuai definisi."
fiOutput yang Dihasilkan:
-- diinginkan (main.tf):
image=debian-13-x64
name=web-jakarta
region=sgp1
size=s-1vcpu-1gb
-- tercatat (state):
image=debian-13-x64
name=web-jakarta
region=sgp1
size=s-2vcpu-2gb
4c4
< size=s-1vcpu-1gb
---
> size=s-2vcpu-2gb
Plan: ada perbedaan — terraform akan mengembalikan size sesuai definisi.Mari kita bedah langkah demi langkahnya:
- Dua
cat > ... << 'EOF': menulis ulang definisi dan state di awal blok — setiap blok latihan mandiri, jadi bisa dijalankan ulang sendiri. grep -oE '(image|name|region|size)[ ]+=[ ]+"..."': menyaring empat atribut darimain.tflalutr -d ' "'membuang spasi dan tanda kutip sehingga formatnya seragam:size=s-1vcpu-1gb.jq ... to_entries[]: membalik objek JSONwebmenjadi pasangankunci=nilai—to_entriesmengubah tiap field menjadi entri tersendiri, pola dari Chapter jq dan JSON Processing .diffdalamif:diffmengembalikan exit code 0 hanya bila isinya sama, jadi percabangan ini persis logika plan — “tidak ada perubahan” atau “ada yang harus dikoreksi”.
Terraform sungguhan menampilkan hasil perbandingan itu dalam ringkasan yang ringkas. Berikut contoh tampilan plan untuk drift di atas:
# digitalocean_droplet.web will be updated in-place
~ resource "digitalocean_droplet" "web" {
image = "debian-13-x64"
name = "web-jakarta"
region = "sgp1"
~ size = "s-2vcpu-2gb" -> "s-1vcpu-1gb"
}
Plan: 0 to add, 1 to change, 0 to destroy.Kapan IaC, Kapan Configuration Management #
IaC dan configuration management menyelesaikan masalah di waktu yang berbeda — satu saat infrastruktur lahir, satu saat ia hidup:
| Aspek | Infrastructure as Code | Configuration Management |
|---|---|---|
| Objek kelola | resource yang belum ada: VM, volume, jaringan | mesin yang sudah ada: paket, berkas, service |
| Pertanyaan kunci | “saya butuh tiga server web” | “semua server web memakai nginx terbaru” |
| Seberapa sering dijalankan | saat infrastruktur berubah | rutin, aman diulang kapan saja |
| Contoh tool | Terraform, Pulumi | Ansible, Puppet, Chef, Salt |
Dalam praktik keduanya berdampingan: Terraform melahirkan server kosong, configuration management yang mendidikkannya. Peralihan itu juga alur bab demi bab section ini — cloud-init menyiapkan boot pertama, Terraform menciptakan mesinnya, dan bab berikutnya mengisi ke dalam mesin itu. Chapter Configuration Management membedah konsep intinya: state akhir, idempotensi, dan konvergensi.
Referensi lanjut: Pro Git untuk model versioning yang menjadi fondasi seluruh praktik IaC.