Anti-Pattern #
State adalah komponen Terraform yang paling mudah dirusak dan paling sulit diperbaiki. Kesalahan dalam pengelolaan state sering kali tidak terlihat dampaknya secara langsung, tapi menumpuk menjadi masalah besar ketika sudah terlambat — drift yang tidak terdeteksi, resource orphan yang membuang biaya, atau state corrupt yang membuat seluruh infrastruktur tidak bisa dikelola. Artikel ini mengompilasi anti-pattern yang paling sering ditemukan di lapangan.
Anti-Pattern 1: State di Git #
Ini adalah anti-pattern yang paling berbahaya dan masih sangat umum ditemukan, terutama di tim yang baru mulai menggunakan Terraform.
# ANTI-PATTERN: Commit terraform.tfstate ke Git
git add terraform.tfstate
git commit -m "update state"
git push
# Masalah yang ditimbulkan:
# 1. SECRET BOCOR
# State bisa mengandung password, API key, private key dalam plaintext.
# Siapapun dengan akses repo bisa membacanya.
# Bahkan setelah dihapus dari commit terbaru, secret masih ada di Git history.
# 2. MERGE CONFLICT YANG TIDAK BISA DISELESAIKAN
# State file adalah JSON yang di-generate otomatis.
# Merge conflict di state tidak bisa diselesaikan secara manual
# tanpa risiko merusak struktur JSON yang diharapkan Terraform.
# 3. TIDAK ADA LOCKING
# Git tidak menyediakan mekanisme locking untuk mencegah
# dua orang push state secara bersamaan.
# BENAR: Gunakan remote backend dan exclude state dari Git
echo "*.tfstate" >> .gitignore
echo "*.tfstate.backup" >> .gitignore
Anti-Pattern 2: Edit State File Secara Manual #
State file adalah file JSON, dan text editor bisa membukanya. Tapi mengeditnya secara manual adalah resep untuk state corrupt.
# ANTI-PATTERN: Edit terraform.tfstate dengan text editor
vim terraform.tfstate # ✗ Jangan pernah lakukan ini
# Risiko:
# - Typo yang merusak struktur JSON → state tidak bisa dibaca
# - Lupa update "serial" → Terraform menolak state karena dianggap stale
# - Referensi yang tidak konsisten antar resource
# BENAR: Gunakan subcommand terraform state untuk semua operasi
terraform state list # Lihat semua resource
terraform state show aws_instance.web # Lihat detail resource
terraform state rm aws_instance.web # Hapus dari state (tanpa destroy)
terraform state mv aws_instance.web aws_instance.web_server # Rename
terraform state pull > backup.tfstate # Backup state
terraform state push modified.tfstate # Push state (hati-hati)
Anti-Pattern 3: State Monolitik untuk Infrastruktur Besar #
Menyimpan seluruh infrastruktur — production, staging, networking, compute, database — dalam satu state file adalah pola yang tidak skalabel.
MASALAH STATE MONOLITIK:
Performance:
Plan harus query SEMUA resource ke provider API
→ Semakin banyak resource, semakin lambat plan
→ 200+ resource bisa butuh 5-10 menit hanya untuk plan
Blast Radius:
Satu apply yang gagal di tengah jalan bisa mempengaruhi
semua resource — networking, compute, database sekaligus
→ Risiko lebih tinggi, dampak lebih luas
Kolaborasi:
Hanya satu orang yang bisa apply pada satu waktu
(karena locking)
→ Bottleneck di tim yang aktif
Keamanan:
Semua orang butuh akses ke satu state
→ Tidak bisa membatasi akses per komponen
SOLUSI: Pecah berdasarkan layer atau komponen
state/networking/ → VPC, subnet, routing
state/compute/ → EC2, ASG, load balancer
state/database/ → RDS, ElastiCache
state/security/ → IAM, security groups
Anti-Pattern 4: Tidak Ada State Locking #
Menjalankan Terraform tanpa state locking di lingkungan tim adalah bom waktu.
# ANTI-PATTERN: Backend S3 tanpa DynamoDB untuk locking
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "production/terraform.tfstate"
region = "ap-southeast-1"
encrypt = true
# dynamodb_table tidak dikonfigurasi → TIDAK ADA LOCKING
}
}
# Konsekuensi:
# Developer A dan B apply bersamaan
# → Keduanya baca state lama
# → Keduanya tulis state baru yang berbeda
# → Salah satu menimpa yang lain → state tidak konsisten
# BENAR: Selalu konfigurasi locking
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "production/terraform.tfstate"
region = "ap-southeast-1"
encrypt = true
dynamodb_table = "terraform-state-lock" # ✓ Wajib ada
}
}
Anti-Pattern 5: Mengabaikan Resource Orphan #
Resource orphan adalah resource yang ada di cloud tapi tidak ada di state Terraform — biasanya karena dibuat di luar Terraform, atau karena state pernah dimodifikasi secara tidak tepat.
# Cara mendeteksi resource orphan:
# 1. List semua resource di state
terraform state list > state-resources.txt
# 2. List semua resource aktual di cloud (contoh untuk AWS)
aws ec2 describe-instances \
--query 'Reservations[].Instances[?State.Name==`running`].InstanceId' \
--output text > cloud-resources.txt
# 3. Bandingkan — resource di cloud tapi tidak di state = orphan
# Dampak resource orphan:
# - Membuang biaya karena tidak terdeteksi dan dibiarkan berjalan
# - Tidak ada governance — siapapun bisa membuat resource tanpa review
# - Drift yang tidak terlihat — state tidak mencerminkan realita
# SOLUSI: Import resource orphan ke Terraform
terraform import aws_instance.recovered_server i-0abcdef1234567890
Anti-Pattern 6: Sensitive Values dalam Output yang Tidak Dilindungi #
State menyimpan semua output values — termasuk yang sensitif — dalam plaintext jika tidak ditandai dengan benar.
# ANTI-PATTERN: Output sensitif tanpa tanda sensitive = true
output "database_password" {
value = aws_db_instance.main.password
# Password tersimpan plaintext di state dan tampil di terminal
}
# BENAR: Tandai output sensitif
output "database_password" {
value = aws_db_instance.main.password
sensitive = true
# Tersembunyi di output terminal
# Tapi tetap tersimpan di state — pastikan state file diamankan
}
Checklist State Management yang Sehat #
STATE MANAGEMENT CHECKLIST:
STORAGE:
□ State disimpan di remote backend (S3, GCS, Terraform Cloud)
□ Enkripsi at rest diaktifkan
□ Versioning diaktifkan di S3 bucket
LOCKING:
□ State locking dikonfigurasi (DynamoDB untuk S3)
□ CI/CD pipeline menggunakan concurrency control
KEAMANAN:
□ terraform.tfstate tidak ada di Git repository
□ *.tfstate ada di .gitignore
□ Akses ke state dibatasi dengan IAM policy
□ Output sensitif ditandai dengan sensitive = true
ORGANISASI:
□ State dipecah per environment (dev/staging/production)
□ State dipecah per komponen jika infrastruktur besar
□ Tidak ada resource orphan yang tidak terkelola
OPERASIONAL:
□ Backup state sebelum operasi berisiko
□ Tidak ada edit manual pada file state
□ Semua operasi state melalui terraform state subcommand
Ringkasan #
- State di Git adalah anti-pattern paling berbahaya — secret bocor, tidak ada locking, merge conflict yang tidak bisa diselesaikan.
- Jangan edit state secara manual — gunakan selalu
terraform statesubcommand untuk semua operasi.- State monolitik tidak skalabel — plan lambat, blast radius besar, kolaborasi terhambat. Pecah berdasarkan layer atau komponen.
- Locking bukan opsional — tanpa DynamoDB table di backend S3, race condition dan state corrupt hanya soal waktu.
- Resource orphan membuang biaya dan menciptakan drift yang tidak terdeteksi — audit secara berkala dan import yang ditemukan.
- Tandai output sensitif dengan
sensitive = true— meskipun tetap tersimpan di state, setidaknya tidak tampil di terminal.