Destroy
#
terraform destroy adalah perintah yang paling perlu kehati-hatian di seluruh Terraform. Ia menghapus semua resource yang dikelola Terraform secara permanen — tidak ada undo, tidak ada recycle bin. Memahami kapan destroy tepat digunakan, bagaimana cara melindungi resource yang tidak boleh dihapus, dan alternatif selain full destroy adalah keterampilan penting untuk siapapun yang mengelola infrastruktur di production.
flowchart TD
A["terraform destroy"] --> B["1. Baca state saat ini\nApa saja yang dikelola Terraform?"]
B --> C["2. Generate 'reverse plan'\nSemua resource ditandai untuk dihapus"]
C --> D["3. Tampilkan rencana penghapusan\nMinta konfirmasi 'yes'"]
D --> E["4. Hapus resource dalam\nurutan terbalik dependency"]
E --> F["5. State dikosongkan\nSemua resource terhapus"]
E --> G["aws_instance.web\ndihapus dulu (paling bergantung)"]
G --> H["aws_security_group\ndihapus dulu"]
H --> I["aws_subnet.public\ndihapus dulu"]
I --> J["aws_vpc.main\ndihapus terakhir (pondasi)"]
style A fill:#ffebee,stroke:#c62828
style F fill:#ffebee,stroke:#c62828
style G fill:#fff3e0,stroke:#e65100
style J fill:#e3f2fd,stroke:#1565c0| Langkah | Apa yang Dilakukan | Output | Catatan Penting |
|---|
| 1. Baca state | Identifikasi semua managed resource | Daftar resource | Hanya resource di state yang akan dihapus |
| 2. Reverse plan | Kebalikan dari apply — semua ditandai destroy | Rencana penghapusan | Sama seperti plan -destroy |
| 3. Konfirmasi | User ketik yes | — | Dilewati jika -auto-approve |
| 4. Hapus berurutan | Resource paling bergantung dihapus dulu | Resource dihapus | Urutan otomatis dari dependency graph |
| 5. Kosongkan state | State file dikosongkan | State kosong | Tidak ada data tersisa |
Urutan penghapusan adalah kebalikan dari urutan pembuatan — resource yang paling “dalam” (paling banyak bergantung pada resource lain) dihapus dulu, baru resource yang jadi pondasinya.
flowchart LR
subgraph "Urutan Apply (kiri ke kanan)"
A1["VPC"] --> A2["Subnet"] --> A3["SG"] --> A4["Instance"]
end
subgraph "Urutan Destroy (kanan ke kiri)"
D4["Instance"] --> D3["SG"] --> D2["Subnet"] --> D1["VPC"]
end
style A1 fill:#e3f2fd,stroke:#1565c0
style A4 fill:#e8f5e9,stroke:#2e7d32
style D4 fill:#ffebee,stroke:#c62828
style D1 fill:#ffebee,stroke:#c62828Menjalankan Destroy
#
flowchart TD
A["Butuh destroy?"] --> B{"Cakupannya?"}
B -->|"Semua resource"| C{"Ada data\nproduction?"}
C -->|"Ya"| D["❌ JANGAN\nGunakan alternatif"]
C -->|"Tidak"| E["terraform destroy"]
B -->|"Beberapa resource\nsaja"| F["Hapus blok resource\ndari .tf, lalu apply"]
B -->|"Module tertentu"| G["terraform destroy\n-target=module.x"]
B -->|"Satu resource"| H["terraform destroy\n-target=resource.x"]
D --> D1["Alternatif:\nhapus blok dari .tf\natau state rm"]
style D fill:#ffebee,stroke:#c62828
style E fill:#fff3e0,stroke:#e65100
style F fill:#e8f5e9,stroke:#2e7d32
style G fill:#e3f2fd,stroke:#1565c0
style H fill:#e3f2fd,stroke:#1565c0# Destroy semua resource (minta konfirmasi)
terraform destroy
# Output konfirmasi:
# Plan: 0 to add, 0 to change, 5 to destroy.
#
# Do you really want to destroy all resources?
# Terraform will destroy all your managed infrastructure, as shown above.
# There is no undo. Only 'yes' will be accepted to confirm.
#
# Enter a value: yes
# Destroy tanpa konfirmasi (untuk CI/CD atau automation)
terraform destroy -auto-approve
# Cara lain yang ekuivalen — lebih eksplisit tentang intent
terraform apply -destroy
# Destroy hanya resource tertentu
terraform destroy -target=aws_instance.web
terraform destroy -target=module.staging
| Perintah | Cakupan | Konfirmasi | Gunakan Untuk |
|---|
terraform destroy | Semua resource | Ketik yes | Teardown environment |
terraform destroy -auto-approve | Semua resource | Tidak | CI/CD teardown |
terraform destroy -target=x | Resource tertentu | Ketik yes | Hapus sebagian |
terraform apply -destroy | Semua resource | Ketik yes | Sama seperti destroy |
Hapus blok dari .tf + apply | Resource tertentu | Ketik yes | Paling terkontrol |
Melindungi Resource dari Destroy
#
Ada beberapa mekanisme untuk melindungi resource yang tidak boleh dihapus secara tidak sengaja.
flowchart TD
A["Melindungi resource\ndari destroy"] --> B["prevent_destroy = true"]
A --> C["ignore_changes"]
A --> D["terraform state rm"]
A --> E["Deletion Protection\ndi provider"]
B --> B1["Terraform ERROR sebelum\nmenghapus resource\nPaling aman untuk DB"]
C --> C1["Abaikan perubahan atribut\nyang bisa trigger replace\nBukan langsung ke destroy"]
D --> D1["Lepas resource dari\nTerraform tanpa hapus\ndari cloud"]
E --> E1["Fitur provider seperti\nRDS deletion_protection\nAWS-level protection"]
style B1 fill:#e8f5e9,stroke:#2e7d32
style C1 fill:#e3f2fd,stroke:#1565c0
style D1 fill:#fff3e0,stroke:#e65100
style E1 fill:#e8f5e9,stroke:#2e7d32| Mekanisme | Level | Apa yang Dilakukan | Kekurangan |
|---|
prevent_destroy = true | Terraform | Error saat ada rencana destroy | Harus dihapus manual jika memang mau destroy |
ignore_changes | Terraform | Abaikan perubahan atribut | Bukan perlindungan destroy langsung |
terraform state rm | Terraform | Lepas dari management | Resource orphaned, tidak dikelola siapapun |
deletion_protection | Provider/Cloud | Cegah penghapusan di level API | Terbatas di resource tertentu |
Mekanisme 1: prevent_destroy
#
# lifecycle prevent_destroy
# Terraform akan ERROR jika ada yang mencoba menghapus resource ini
resource "aws_rds_instance" "production_db" {
identifier = "production-database"
engine = "postgres"
instance_class = "db.t3.medium"
allocated_storage = 100
lifecycle {
prevent_destroy = true
# Error saat destroy:
# Error: Instance cannot be destroyed
# Resource aws_rds_instance.production_db has lifecycle.prevent_destroy
# set to true.
}
}
Mekanisme 2: ignore_changes
#
# ignore_changes untuk atribut yang dikelola di luar Terraform
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = var.instance_type
lifecycle {
ignore_changes = [
# Abaikan perubahan pada atribut ini — tidak akan trigger destroy/recreate
ami,
user_data,
]
}
}
Mekanisme 3: Unmanage Resource
#
# Hapus resource dari state tanpa menghapusnya dari cloud
# Resource tetap ada di AWS, tapi Terraform tidak lagi mengelolanya
terraform state rm aws_instance.web
# Sekarang terraform destroy tidak akan menyentuh resource ini
Mekanisme 4: Provider-level Protection
#
# Deletion protection di level provider (bukan Terraform)
resource "aws_rds_instance" "db" {
identifier = "production-db"
engine = "postgres"
instance_class = "db.t3.medium"
deletion_protection = true # AWS-level: tidak bisa dihapus dari Console/API
}
# S3 bucket: versioning + MFA delete
resource "aws_s3_bucket" "critical" {
bucket = "critical-data-bucket"
# Versioning memastikan data lama tetap tersimpan
# bahkan jika object dihapus
}
Kapan Destroy Tepat Digunakan
#
flowchart TD
A["Situasi"] --> B{"Tipe environment?"}
B -->|"Development /\nFeature branch"| C["✅ Destroy aman\nResource sementara"]
B -->|"Staging /\nTesting"| D["✅ Destroy aman\nBisa recreate"]
B -->|"Production"| E["❌ HINDARI destroy\nGunakan alternatif"]
C --> C1["terraform destroy\natau -auto-approve di CI/CD"]
D --> D1["terraform destroy\ndengan konfirmasi"]
E --> E1["Hapus blok dari .tf\nlalu apply\nAtau state rm"]| Skenario | Gunakan Destroy? | Alternatif |
|---|
| Environment sementara (dev, feature branch) | ✅ Ya | — |
| Resource demo atau eksperimen | ✅ Ya | — |
| Teardown environment yang sudah tidak diperlukan | ✅ Ya | — |
| Migrasi ke konfigurasi baru dari awal | ✅ Ya (hati-hati) | Backup state dulu |
| Hapus sebagian resource | ❌ Tidak | Hapus blok dari .tf, lalu apply |
| Database production tanpa backup | ❌ JANGAN | Backup dulu, baru pertimbangkan |
| Tidak yakin apa yang akan terhapus | ❌ JANGAN | Jalankan plan -destroy dulu |
Jangan pernah menjalankan terraform destroy pada production tanpa backup yang sudah diverifikasi. Selalu jalankan terraform plan -destroy dan baca outputnya dengan cermat sebelum mengkonfirmasi.
Alternatif Selain Full Destroy
#
Destroy penuh seringkali bukan satu-satunya pilihan. Ada pendekatan yang lebih aman dan lebih terkontrol.
flowchart TD
A["Mau menghapus\nresource?"] --> B{"Resource apa\nyang mau dihapus?"}
B -->|"Hanya beberapa\nresource"| C["Hapus blok resource\ndari .tf, lalu apply"]
B -->|"Satu module"| D["terraform destroy\n-target=module.x"]
B -->|"Lepas dari\nTerraform"| E["terraform state rm\nResource tetap di cloud"]
B -->|"Semua resource"| F{"Ada data\nproduction?"}
F -->|"Ya"| G["❌ Jangan destroy\nGunakan alternatif lain"]
F -->|"Tidak"| H["terraform destroy"]
style C fill:#e8f5e9,stroke:#2e7d32
style D fill:#e3f2fd,stroke:#1565c0
style E fill:#fff3e0,stroke:#e65100
style G fill:#ffebee,stroke:#c62828
style H fill:#ffebee,stroke:#c62828Alternatif 1: Hapus Blok Resource dari Konfigurasi
#
# Sebelum:
resource "aws_instance" "staging" {
ami = var.ami_id
instance_type = "t3.micro"
}
# Sesudah (hapus blok ini dari .tf):
# (tidak ada lagi)
# Lalu jalankan: terraform apply
# Terraform mendeteksi resource tidak lagi ada di konfigurasi
# dan menghapusnya dari cloud — hanya resource ini, bukan yang lain
Alternatif 2: Target Destroy
#
# Destroy hanya module atau resource spesifik
terraform destroy -target=module.staging
terraform destroy -target=aws_instance.old_server
Alternatif 3: Unmanage Resource
#
# Lepas resource dari Terraform tanpa menghapusnya dari cloud
terraform state rm aws_s3_bucket.old_bucket
# Resource tetap ada di AWS, Terraform tidak lagi mengelolanya
# Berguna untuk transisi ownership ke tim lain atau tool lain
| Alternatif | Perintah | Resource Lain | Data Aman? | Cocok Untuk |
|---|
| Hapus blok + apply | Edit .tf + apply | Tidak terpengaruh | ✅ Ya | Hapus resource spesifik |
| Target destroy | destroy -target=x | Tidak terpengaruh | ✅ Ya | Hapus module/resource tertentu |
| Unmanage | state rm | Tidak terpengaruh | ✅ Ya | Transisi ownership |
| Full destroy | destroy | Semua terhapus | ❌ Tidak | Teardown environment |
Destroy di CI/CD Pipeline
#
Untuk lingkungan yang di-destroy secara otomatis (misalnya: ephemeral environment per PR), ada pola yang aman.
flowchart TD
A["PR merged /\nEnvironment selesai"] --> B["1. Generate destroy plan\nterraform plan -destroy\n-out=destroy-plan"]
B --> C["2. Review plan\nManual atau automated check"]
C --> D["3. Approval diterima"]
D --> E["4. terraform apply destroy-plan\nEksekusi destroy dari saved plan"]
E --> F["5. Hapus file destroy-plan"]
F --> G["✅ Environment bersih\nAudit trail tersimpan"]
style A fill:#e3f2fd,stroke:#1565c0
style E fill:#ffebee,stroke:#c62828
style G fill:#e8f5e9,stroke:#2e7d32# Pola destroy yang aman di CI/CD:
# 1. Generate destroy plan dulu
terraform plan -destroy -out=destroy-plan
# 2. Review plan (manual atau automated check)
terraform show destroy-plan
# 3. Apply destroy plan jika sudah diverifikasi
terraform apply destroy-plan
# Kenapa tidak langsung -auto-approve?
# Destroy plan yang disimpan memberikan audit trail
# dan mencegah surprise dari kondisi yang berubah
# antara inisiasi destroy dan eksekusinya.
| Pola CI/CD | Perintah | Audit Trail | Risiko |
|---|
| Langsung destroy | destroy -auto-approve | ❌ Tidak ada | Tinggi |
| Saved destroy plan | plan -destroy -out=x + apply x | ✅ Ada | Rendah |
Ringkasan
#
- Destroy tidak bisa di-undo — selalu jalankan
terraform plan -destroy dan baca outputnya sebelum mengkonfirmasi. - Urutan penghapusan otomatis — Terraform menghapus resource dalam urutan terbalik dari dependency, tidak perlu ditentukan manual.
prevent_destroy = true untuk resource kritis seperti production database — Terraform akan error sebelum sempat menghapusnya.- Provider-level protection (
deletion_protection, versioning, MFA delete) memberikan perlindungan tambahan di luar Terraform. - Hapus blok resource dari .tf lalu apply untuk menghapus resource tertentu saja — lebih terkontrol dari destroy penuh.
terraform state rm untuk unmanage resource tanpa menghapusnya dari cloud — berguna untuk transisi ownership.- Di CI/CD, gunakan saved destroy plan (
plan -destroy -out=x) agar ada audit trail yang jelas dari apa yang akan dihapus. - Jangan pernah destroy production tanpa backup yang sudah diverifikasi — selalu ada alternatif yang lebih aman.
← Sebelumnya: Apply
Berikutnya: Execution Plan →