Idempotency #

Idempotency adalah properti di mana menjalankan operasi yang sama berkali-kali menghasilkan hasil yang sama seperti menjalankannya sekali. Di Terraform, ini berarti kamu bisa menjalankan terraform apply berulang kali tanpa khawatir akan membuat resource duplikat, mengubah sesuatu yang tidak perlu, atau merusak kondisi yang sudah benar. Ini bukan kebetulan — idempotency adalah hasil desain Terraform yang disengaja, dan memahaminya membantumu mengenali kapan konfigurasi atau penggunaan Terraform menyimpang dari prinsip ini.

Idempotency di Terraform #

Terraform menjamin idempotency melalui mekanisme state dan planning.

CARA IDEMPOTENCY BEKERJA:

Terraform apply (pertama kali):
  State: kosong
  Konfigurasi: 3 resource
  Plan: +3 create
  Hasil: 3 resource dibuat, state diupdate

Terraform apply (kedua kali, tanpa perubahan):
  State: 3 resource
  Konfigurasi: 3 resource (sama)
  Plan: "No changes. Your infrastructure matches the configuration."
  Hasil: tidak ada yang berubah

Terraform apply (ketiga, keempat, kelima...):
  Sama dengan kedua kali — tidak ada perubahan

Ini berbeda dengan script bash yang tidak idempoten, di mana menjalankan dua kali bisa membuat resource duplikat atau menghasilkan error.


Perbandingan dengan Pendekatan Non-Idempoten #

# ANTI-PATTERN: Script bash — tidak idempoten
#!/bin/bash

# Jalankan pertama kali: berhasil
aws ec2 create-security-group \
  --group-name "web-sg" \
  --description "Web security group"

# Jalankan kedua kali: ERROR
# An error occurred (InvalidGroup.Duplicate):
# The security group 'web-sg' already exists

# Butuh conditional logic ekstra untuk membuatnya idempoten:
if ! aws ec2 describe-security-groups --group-names "web-sg" 2>/dev/null; then
  aws ec2 create-security-group --group-name "web-sg" ...
fi
# Dan ini masih tidak menangani race condition, update, dll.
# BENAR: Terraform — idempoten secara built-in
resource "aws_security_group" "web" {
  name        = "web-sg"
  description = "Web security group"
}
# Jalankan 100 kali → hasilnya selalu sama
# Terraform tahu apakah security group sudah ada
# dan hanya bertindak jika ada perbedaan

Mekanisme yang Membuat Terraform Idempoten #

Ada tiga komponen yang bekerja bersama untuk menjamin idempotency.

1. STATE — "Apa yang sudah ada"
   Terraform membaca state sebelum melakukan apapun.
   Jika resource sudah ada di state dengan konfigurasi yang sama,
   tidak ada operasi yang dilakukan.

2. PLAN — "Apa yang perlu berubah"
   Terraform membandingkan konfigurasi dengan state.
   Hanya perbedaan yang dieksekusi — bukan seluruh konfigurasi.

3. PROVIDER — "Apakah kondisi aktual sudah sesuai"
   Sebelum plan, Terraform me-refresh state dari kondisi aktual.
   Jika kondisi aktual sudah sesuai konfigurasi, tidak ada perubahan.

Kasus yang Bisa Merusak Idempotency #

Meskipun Terraform dirancang untuk idempoten, ada beberapa pola yang bisa merusaknya.

# KASUS 1: timestamp() atau uuid() dalam konfigurasi
# ANTI-PATTERN: Setiap apply menghasilkan nilai berbeda
resource "aws_s3_bucket_object" "config" {
  bucket  = aws_s3_bucket.main.id
  key     = "config.json"
  content = jsonencode({
    generated_at = timestamp()  # ✗ Berbeda setiap apply!
    # Ini menyebabkan resource diupdate setiap kali apply dijalankan
  })
}

# BENAR: Gunakan nilai yang stabil
resource "aws_s3_bucket_object" "config" {
  bucket  = aws_s3_bucket.main.id
  key     = "config.json"
  content = jsonencode({
    environment = var.environment
    version     = var.app_version
    # Nilai ini hanya berubah jika variable-nya berubah
  })
}
# KASUS 2: Provisioner yang tidak idempoten
resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = "t3.micro"

  # ANTI-PATTERN: Provisioner ini dijalankan setiap kali
  # resource dianggap "baru" oleh Terraform
  provisioner "remote-exec" {
    inline = [
      "echo 'Server $(hostname) started at $(date)' >> /var/log/deploy.log"
      # timestamp di sini akan berbeda setiap apply
    ]
  }
}

# BENAR: Gunakan user_data untuk konfigurasi initial
# atau Ansible untuk konfigurasi yang benar-benar idempoten
resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = "t3.micro"
  user_data     = file("scripts/setup.sh")  # Dijalankan hanya sekali saat launch
}
# KASUS 3: depends_on yang tidak perlu bisa memicu apply berulang
# (lihat artikel Execution Plan untuk pembahasan lebih detail)

# KASUS 4: Resource yang dikelola sebagian oleh Terraform
# sebagian oleh tool lain — bisa saling konflik

Memverifikasi Idempotency Konfigurasimu #

Ada cara sederhana untuk memverifikasi bahwa konfigurasimu benar-benar idempoten.

# Tes idempotency manual:

# 1. Apply pertama kali
terraform apply -auto-approve

# 2. Apply kedua kali tanpa mengubah apapun
terraform apply -auto-approve

# 3. Cek output
# Jika konfigurasi idempoten, outputnya:
# Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

# Jika ada perubahan di apply kedua, ada yang tidak idempoten.
# Cari penyebabnya: timestamp, random value, atau resource yang
# dimodifikasi di luar Terraform.

Idempotency dan Immutable Infrastructure #

Idempotency bukan berarti resource tidak pernah berubah — ia berarti hasil dari menjalankan konfigurasi yang sama selalu konsisten. Ini sejalan dengan prinsip immutable infrastructure.

MUTABLE INFRASTRUCTURE (tradisional):
  Server dibuat sekali, lalu dikonfigurasi ulang berulang kali
  di tempat yang sama. Seiring waktu, kondisi server menjadi
  sulit diprediksi ("configuration drift").

IMMUTABLE INFRASTRUCTURE (modern):
  Saat konfigurasi berubah, resource lama dihapus dan
  resource baru dibuat dari awal dengan konfigurasi baru.
  Kondisi selalu bisa diprediksi karena selalu fresh.

TERRAFORM MENDUKUNG KEDUANYA:
  - Update in-place (~): mutable, tapi terkontrol
  - Destroy and recreate (-/+): immutable approach
  - Pilihan tergantung pada jenis resource dan kebutuhan

Ringkasan #

  • Idempotency Terraform bersifat built-in melalui tiga mekanisme: state, plan, dan refresh dari kondisi aktual.
  • “No changes” di apply kedua adalah tanda bahwa konfigurasimu idempoten — ini adalah kondisi yang diinginkan.
  • Hindari timestamp(), uuid(), atau random value dalam konfigurasi resource — ini merusak idempotency karena nilainya berubah setiap apply.
  • Provisioner tidak idempoten secara natural — pertimbangkan user_data atau Ansible sebagai alternatif.
  • Tes idempotency dengan menjalankan apply dua kali berturut-turut dan memastikan apply kedua tidak melakukan perubahan apapun.
  • Idempotency adalah fondasi kepercayaan terhadap konfigurasi Terraform — jika apply kedua masih menghasilkan perubahan, ada sesuatu yang perlu diperbaiki.

← Sebelumnya: Drift Detection   Berikutnya: Apa itu Resource? →

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