Terraform Backend'ini Veri Kaybetmeden Geçirmek
Selamlar, bu yazımda Terraform'un en gergin operasyonlarından birine bakacağız: backend geçişi. State dosyası tek bir JSON gibi görünür ama Terraform için kâinatın merkezidir; o dosyayı kaybederseniz Terraform yönettiği her şeyi 'tanımıyorum' moduna alır. Resource'lar duruyor, ama sizin onları yönetebilme yetiniz buharlaşıyor. Lafı uzatmadan başlayalım.
Backend geçişi neden olur? Önce local ile başlamışsınızdır, ekip büyür, S3'e geçmek istersiniz. Sonra Terraform Cloud'un workspace yönetimini denemek istersiniz. Bazen de iki şirket birleşir, state'leri tek bucket'ta toplamak gerekir. Hepsi normal ihtiyaçlar; ama her biri yanlış adımda saatlerce uğraşacağınız bir kurtarma operasyonuna dönüşebilir.
Geçişten önce yapılması gerekenler
Tek bir kuralı asla atlamayın: yedek. Terraform'un kendi state push/pull mekanizması güvenli, ama dosyayı bir kez elden çıkarınca geri alamayabilirsiniz.
# 1. Ekipteki herkesi haberdar edin, CI/CD pipeline'larini durdurun
# 2. Mevcut state'i tarihli bir dosyaya cekin
terraform state pull > state-backup-$(date +%Y%m%d_%H%M%S).json
# 3. Yedegin tam oldugunu dogrulayin
jq '.resources | length' state-backup-*.json
terraform state list | wc -l
# 4. Yedegi repo disinda bir yere koyun
aws s3 cp state-backup-*.json s3://my-backups/terraform/
Bence bu adımı atlamak, geçişin başarısı umurumda değil, prensip olarak kabul edilemez. Yedek olmadan başlanan migration'ın bir adı vardır: kumar.
Local'den S3'e
En sık görülen senaryo bu. Önceden backend "local" bloğunuz var ya da hiç yok; yeni durumda S3'e yazıyorsunuz.
# backend.tf - YENI hali
terraform {
backend "s3" {
bucket = "myorg-terraform-state"
key = "prod/app/terraform.tfstate"
region = "eu-central-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
Sonra init:
terraform init
# Terraform soracak:
# Do you want to copy existing state to the new backend?
# Cevap: yes
terraform plan
# Cikti: No changes. -> ise yaradi
Plan boş çıktıktan sonra local dosyayı silin, bir saniye bile önce değil:
rm terraform.tfstate terraform.tfstate.backup
S3'ten Terraform Cloud'a
Burası iki backend tipi farklı olduğu için Terraform'un otomatik geçişi her zaman tetiklemediği bir yer. Manuel push'a hazırlıklı olun.
terraform {
cloud {
organization = "myorg"
workspaces { name = "prod-app" }
}
}
# Once mevcut state'i alalim
terraform state pull > current-state.json
# backend.tf'i guncelleyip init
terraform init
# Eger Terraform migrate teklif etmediyse manuel push:
terraform state push current-state.json
terraform plan
Cross-cloud: S3'ten GCS'e
İki farklı cloud arası geçişte, kontrolü Terraform'a bırakmak yerine elinize alın. init sırasında migrate'e 'no' deyin, ardından kendiniz push edin. Şahsi tercihim hep budur; bir adımı kendi gözümle görmek bana huzur veriyor.
terraform state pull > migration-state.json
# backend.tf'i GCS'e guncelle, sonra:
terraform init -reconfigure
# Migrate teklifine: no
terraform state push migration-state.json
terraform plan
İşler ters giderse
Panik yok, çünkü yedeğiniz var. Üç tipik senaryoya bakalım.
State hiçbir backend'de yok
git checkout backend.tf
terraform init -reconfigure
terraform state push state-backup-20260510_103000.json
terraform plan
State iki backend'de birden var
Aslında bu kısmen iyi haber - hiçbir şey kaybolmadı. Hangisinin güncel olduğunu serial numarasına bakarak anlayın:
terraform state pull | jq '.serial'
Yüksek olan kazanır. Diğerini elle silin.
Lock takılı kaldı
terraform force-unlock LOCK_ID
Ama önce o lock'u kimsenin gerçekten tutmadığından emin olun; başka bir CI job'ı çalışıyorsa state'i bozabilirsiniz.
Sık karşılaşılan tuzaklar
- Yedek almadan başlamak: En tehlikeli hata bu. Geçiş başarılı olsa bile yedek olmadan başarıyı doğrulayamazsınız, çünkü 'eskiden ne vardı' sorusunun cevabı kalmamış olur.
- Local dosyayı erken silmek:
terraform.tfstate'i remote backend doğrulanmadan silmek, geri dönüşü olmayan bir karardır. Önceplan, sonra silme. - Workspace'leri unutmak: Birden fazla workspace varsa her biri ayrı state taşır. Sadece
default'u taşıyıp diğerlerini unutursanız üç gün sonra fark edersiniz. - CI/CD credentials güncellemesini ertelemek: Geçiş bittikten sonra pipeline'lar hâlâ eski backend'e yazmaya çalışırsa hem state bozulur hem lock karışır. Backend değiştiği gün CI değişkenleri de değişmeli.
-migrate-stateile-reconfigurekarıştırmak: İlki state'i taşır, ikincisi sadece backend ayarlarını yeniden okur. Yanlış flag yanlış sonuç verir.
Doğrulama
Geçiş bittikten sonra şu beş şeyi sırayla kontrol edin:
terraform state list # State okunuyor mu?
terraform plan # Sifir degisiklik mi?
terraform state list | wc -l # Kaynak sayisi yedekle ayni mi?
jq '.resources | length' state-backup-*.json
# Tum ekip terraform init calistirdi mi?
Hepsi yeşilse rahat nefes alın. Eski backend'i bir hafta daha açık bırakın - panik anında geri dönüş kapısı olarak işinize yarar.
Kapanış
Terraform backend geçişi gözünüzde büyüttüğünüz kadar zor değil; disiplinli bir checklist'le yarım saatlik bir iş. Bence en kritik nokta yedek - state'i bir kez yazılı bir dosyaya almışsanız, gerisi en kötü senaryoda bile telafi edilebilir bir teknik problem. Umarım faydalı olur, bir sonraki yazıda görüşmek üzere.
