Drift Detection #

Drift adalah kondisi di mana infrastruktur aktual yang berjalan di cloud berbeda dari apa yang didefinisikan dalam konfigurasi Terraform. Ini terjadi lebih sering dari yang kamu kira — seseorang mengedit security group langsung di console untuk debugging, sebuah auto-scaling event mengubah jumlah instance, atau layanan cloud secara otomatis memodifikasi atribut tertentu. Drift yang tidak dideteksi dan dikelola bisa menjadi sumber bug yang sulit dilacak dan security hole yang tidak disadari.

Apa itu Drift #

Drift terjadi ketika ada ketidaksesuaian antara tiga hal: konfigurasi Terraform yang kamu tulis, state yang Terraform simpan, dan kondisi aktual di cloud.

TIGA SUMBER KEBENARAN DI TERRAFORM:

Konfigurasi (.tf)     State (.tfstate)     Realita (cloud)
      │                     │                    │
      └──────── idealnya ───┴──── selalu sama ───┘

KONDISI DRIFT:

Konfigurasi (.tf)     State (.tfstate)     Realita (cloud)
  port 443 only    →   port 443 only    ≠   port 443 + 22 + 8080
                                            (seseorang buka port
                                             tambahan di console)

Ada dua jenis drift yang perlu dibedakan: drift antara state dan realita (paling umum), dan drift antara konfigurasi dan state (terjadi jika ada yang edit state secara manual).


Mendeteksi Drift #

Cara paling langsung untuk mendeteksi drift adalah dengan menjalankan terraform plan — Terraform akan refresh state dari kondisi aktual dan menampilkan perbedaan yang ada.

# Cara 1: terraform plan (melakukan refresh sebelum plan)
terraform plan
# Jika ada drift, plan akan menampilkan perubahan
# meskipun kamu tidak mengubah konfigurasi apapun

# Cara 2: terraform refresh (update state dari kondisi aktual)
terraform refresh
# Memperbarui state file dengan kondisi aktual di cloud
# tanpa mengubah infrastruktur

# Cara 3: terraform plan -refresh-only
# Hanya menampilkan perbedaan antara state dan realita
# tanpa menghitung perubahan dari konfigurasi
terraform plan -refresh-only

# Output jika ada drift:
# ~ aws_security_group.web will be updated in-place
#   ~ ingress = [
#       + {
#           + from_port   = 22
#           + protocol    = "tcp"
#           + to_port     = 22
#           + cidr_blocks = ["0.0.0.0/0"]
#         },
#     ]
#
# Note: Objects have changed outside of Terraform

Penyebab Drift yang Paling Umum #

PENYEBAB DRIFT:

1. PERUBAHAN MANUAL DI CONSOLE
   Paling umum. Developer atau ops mengubah konfigurasi
   langsung di AWS/GCP console untuk debugging atau emergency.
   Sering tidak dikembalikan ke kondisi semula.

2. PERUBAHAN OLEH LAYANAN CLOUD ITU SENDIRI
   Beberapa atribut resource bisa berubah secara otomatis
   oleh cloud provider — misalnya: AWS secara otomatis
   merotasi sertifikat, Auto Scaling mengubah jumlah instance,
   atau managed service mengupdate versi minor secara otomatis.

3. TERRAFORM apply YANG PARSIAL
   Apply yang gagal di tengah jalan bisa meninggalkan resource
   dalam kondisi yang berbeda dari yang dikonfigurasi.

4. PERUBAHAN DI LUAR TERRAFORM oleh TOOL LAIN
   Ansible, CLI script, atau tool lain yang dijalankan
   di sumber resource yang sama dengan Terraform.

5. STATE YANG TIDAK SINKRON
   State yang lama atau corrupt bisa menyebabkan Terraform
   tidak tahu kondisi resource yang sebenarnya.

Merespons Drift #

Saat drift terdeteksi, ada dua pilihan: kembalikan infrastruktur ke kondisi yang dikonfigurasi, atau update konfigurasi untuk mencerminkan perubahan yang ada.

# OPSI 1: Kembalikan ke kondisi konfigurasi (terraform menang)
# Jalankan apply — Terraform akan mengubah infrastruktur
# agar sesuai dengan konfigurasi .tf
terraform apply
# Berguna jika perubahan manual adalah kesalahan dan harus dibatalkan

# OPSI 2: Terima perubahan yang ada (realita menang)
# Update state agar mencerminkan kondisi aktual
terraform apply -refresh-only
# State diupdate, konfigurasi .tf tidak berubah
# Langkah berikutnya: update konfigurasi .tf agar sesuai
# dengan kondisi aktual, lalu commit ke version control
# Contoh: Drift terdeteksi — port 22 dibuka di luar Terraform
# Setelah diskusi tim, diputuskan port 22 memang diperlukan
# tapi harus dikelola oleh Terraform

# Update konfigurasi .tf:
resource "aws_security_group" "web" {
  name = "web-sg"

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # Tambahkan aturan yang sebelumnya dibuka manual:
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.office_cidr]  # Batasi ke IP kantor, bukan 0.0.0.0/0
  }
}
# Commit konfigurasi ini, lalu apply

Mencegah Drift #

Strategi terbaik adalah mencegah drift sebelum terjadi.

STRATEGI PENCEGAHAN DRIFT:

1. LARANG PERUBAHAN MANUAL DI CONSOLE
   Buat kebijakan tim: semua perubahan infrastruktur
   harus melalui Terraform. Gunakan IAM policy untuk
   membatasi akses console di production jika memungkinkan.

2. AUTOMATED DRIFT DETECTION
   Jadwalkan terraform plan -refresh-only secara rutin
   (misal: setiap malam) dan kirim alert jika ada drift.

3. GUNAKAN ignore_changes UNTUK ATRIBUT YANG MEMANG BERUBAH SENDIRI
   Jika atribut tertentu sering berubah di luar Terraform
   dan itu memang expected, gunakan ignore_changes.

4. DOKUMENTASIKAN EMERGENCY PROCEDURES
   Saat ada insiden, tim butuh panduan yang jelas:
   "Boleh edit manual di console saat emergency, TAPI
   wajib buat Terraform PR dalam 24 jam."
# Contoh ignore_changes untuk atribut yang berubah secara otomatis
resource "aws_autoscaling_group" "web" {
  name             = "web-asg"
  min_size         = 2
  max_size         = 10
  desired_capacity = 2

  lifecycle {
    # desired_capacity bisa berubah oleh auto scaling policy
    # atau manual scaling — abaikan perubahan ini di Terraform
    ignore_changes = [desired_capacity]
  }
}

Automated Drift Detection di CI/CD #

# Contoh: GitHub Actions untuk drift detection terjadwal
# .github/workflows/drift-detection.yml

name: Terraform Drift Detection

on:
  schedule:
    - cron: '0 8 * * 1-5'  # Setiap hari kerja jam 8 pagi

jobs:
  drift-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        
      - name: Terraform Init
        run: terraform init
        
      - name: Check for Drift
        id: plan
        run: |
          terraform plan -refresh-only -detailed-exitcode
          # Exit code 0: tidak ada perubahan
          # Exit code 1: error
          # Exit code 2: ada perubahan (drift terdeteksi)          
        continue-on-error: true
        
      - name: Alert jika ada drift
        if: steps.plan.outputs.exitcode == '2'
        run: |
          echo "Drift detected! Check Terraform plan output."
          # Kirim notifikasi ke Slack, PagerDuty, dll.          

Ringkasan #

  • Drift adalah kondisi normal yang akan selalu terjadi di tim yang aktif — yang penting adalah mendeteksi dan meresponsnya dengan cepat.
  • terraform plan -refresh-only adalah cara paling aman untuk mendeteksi drift tanpa risiko mengubah infrastruktur.
  • Dua pilihan saat drift terdeteksi: apply untuk kembalikan ke konfigurasi, atau update konfigurasi untuk mencerminkan realita — pilih sesuai intent.
  • ignore_changes untuk atribut yang memang dikelola di luar Terraform — mencegah false-positive drift detection.
  • Automated drift detection yang dijadwalkan memastikan tim mengetahui drift sebelum menjadi masalah production.
  • Kebijakan tim yang jelas tentang perubahan manual adalah pertahanan pertama — bukan tool, tapi kebiasaan.

← Sebelumnya: Execution Plan   Berikutnya: Idempotency →

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