Declarative #

Kata “deklaratif” sering disebut saat membahas Terraform, tapi apa artinya secara konkret? Bukan sekadar istilah marketing — pendekatan deklaratif adalah fondasi dari cara Terraform bekerja dan cara kamu harus berpikir saat menuliskan konfigurasi. Memahaminya dengan benar akan mengubah cara kamu mendekati masalah infrastruktur.

Inti Pendekatan Deklaratif #

Dalam pendekatan deklaratif, kamu mendefinisikan kondisi akhir yang kamu inginkan — bukan langkah-langkah untuk mencapainya. Terraform yang bertanggung jawab menghitung delta antara kondisi saat ini dan kondisi yang kamu inginkan, lalu menentukan sendiri apa yang perlu dilakukan.

# Kamu menulis ini:
resource "aws_instance" "web" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.micro"
  
  tags = {
    Name = "web-server"
  }
}

# Terraform yang memutuskan:
# - Instance ini belum ada → buat baru
# - Instance sudah ada dengan spec ini → tidak ada yang perlu dilakukan
# - Instance ada tapi instance_type berbeda → ubah instance_type
# - Instance ada tapi sudah tidak ada di konfigurasi → hapus

# Kamu tidak perlu menulis kondisional ini secara manual.

Terraform Menghitung Delta #

Setiap kali kamu menjalankan terraform plan, Terraform melakukan tiga hal: membaca konfigurasi yang kamu tulis, membaca state yang tersimpan, dan membandingkan keduanya untuk menghasilkan execution plan.

CARA TERRAFORM MENGHITUNG PERUBAHAN:

Konfigurasi (.tf files)         State (terraform.tfstate)
      │                                │
      └──────────────┬─────────────────┘
                     │
                     ▼
              Terraform Plan
              (menghitung delta)
                     │
        ┌────────────┼────────────┐
        │            │            │
        ▼            ▼            ▼
     Create        Update       Destroy
   (ada di .tf,  (ada di .tf   (ada di state,
    tidak ada     dan state,    tidak ada
    di state)     tapi beda)    di .tf)

Ini yang membuat Terraform idempoten secara natural — jika kamu menjalankan terraform apply dua kali tanpa mengubah konfigurasi apapun, operasi kedua tidak akan melakukan perubahan apapun karena tidak ada delta.


Dependency Graph Otomatis #

Keuntungan besar pendekatan deklaratif adalah Terraform bisa menghitung dependency graph secara otomatis. Kamu tidak perlu menentukan “buat VPC dulu, baru subnet, baru instance” — Terraform menyimpulkannya dari referensi antar resource.

# Kamu tidak perlu menentukan urutan — Terraform menyimpulkannya sendiri

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}

resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.main.id  # ← referensi ke VPC
  cidr_block = "10.0.1.0/24"
  # Terraform tahu: subnet bergantung pada VPC
  # → VPC harus dibuat dulu
}

resource "aws_instance" "web" {
  ami       = "ami-0abcdef1234567890"
  subnet_id = aws_subnet.public.id  # ← referensi ke subnet
  # Terraform tahu: instance bergantung pada subnet
  # → subnet harus ada sebelum instance dibuat
}

# Urutan eksekusi yang Terraform tentukan otomatis:
# 1. aws_vpc.main
# 2. aws_subnet.public
# 3. aws_instance.web

Resource yang tidak saling bergantung bisa dibuat secara paralel, yang membuat Terraform lebih efisien dari script sequential.


Implikasi untuk Cara Menulis Konfigurasi #

Karena Terraform bekerja secara deklaratif, ada beberapa pola pikir yang perlu kamu sesuaikan.

# ANTI-PATTERN: Berpikir imperatif saat menulis Terraform
# (mencoba mengontrol urutan yang sebenarnya tidak perlu)

resource "null_resource" "wait_for_vpc" {
  depends_on = [aws_vpc.main]
  
  provisioner "local-exec" {
    command = "sleep 10"  # Menunggu VPC "siap"
  }
}

resource "aws_subnet" "public" {
  depends_on = [null_resource.wait_for_vpc]  # Tidak perlu ini
  vpc_id     = aws_vpc.main.id
  cidr_block = "10.0.1.0/24"
}

# BENAR: Percayakan ke Terraform
# Referensi langsung sudah cukup untuk menentukan dependency

resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.main.id  # Ini sudah menyatakan dependency
  cidr_block = "10.0.1.0/24"
}

Deklaratif Bukan Berarti Tanpa Kontrol #

Pendekatan deklaratif tidak berarti kamu kehilangan kontrol. Ada mekanisme untuk situasi di mana kamu butuh kontrol lebih eksplisit.

# depends_on untuk dependency eksplisit yang tidak bisa disimpulkan
# dari referensi (misalnya: dependency pada side effect)

resource "aws_iam_role_policy_attachment" "worker" {
  role       = aws_iam_role.worker.name
  policy_arn = aws_iam_policy.worker.arn
}

resource "aws_eks_node_group" "workers" {
  # Node group butuh role sudah ter-attach ke policy
  # Dependency ini tidak terlihat dari referensi resource,
  # jadi perlu depends_on eksplisit
  depends_on = [aws_iam_role_policy_attachment.worker]
  
  cluster_name    = aws_eks_cluster.main.name
  node_role_arn   = aws_iam_role.worker.arn
  subnet_ids      = aws_subnet.private[*].id
}

Ringkasan #

  • Deklaratif = definisikan kondisi akhir — kamu menyatakan apa yang diinginkan, Terraform menentukan bagaimana mencapainya.
  • Terraform menghitung delta antara konfigurasi dan state saat ini — ini yang membuatnya idempoten secara natural.
  • Dependency graph dihitung otomatis dari referensi antar resource — tidak perlu menentukan urutan eksekusi secara manual.
  • Resource independen dieksekusi paralel — Terraform lebih efisien dari script sequential karena bisa membuat banyak resource sekaligus.
  • depends_on untuk edge case — gunakan hanya ketika dependency tidak bisa disimpulkan dari referensi langsung.
  • Jangan berpikir imperatif saat menulis HCL — percayakan kalkulasi urutan dan kondisi kepada Terraform.

← Sebelumnya: Kapan Digunakan?   Berikutnya: Provider →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact