Reliability Friday 11: Terraform Drift ve "No changes" Neden Kanıt Değildir?
"No changes" çıktısı altyapının doğru olduğunu kanıtlamaz. Terraform drift neden görünmez kalır, üç komutla nasıl bulunur, hangi sonuç ne anlama gelir.









Kısa cevap: terraform plan "No changes." dediğinde Terraform yalnızca şunu söyler: seçili workspace, state ve provider kapsamında yönettiği alanlarda uygulanacak bir değişiklik görmüyor. Bu çıktı tüm altyapının doğru olduğunu, yönetilmeyen kaynak bulunmadığını ya da servisin sağlıklı çalıştığını kanıtlamaz. Production'daki firewall rule farklı, bir VM yanlış network'te, load balancer'da eksik backend olabilir ve plan yine temiz kalabilir. Bu hafta üç komutla Terraform'un görüş alanını ve o alanın dışında kalanı kontrol ediyoruz.
Don't Deploy on Friday. Verify on Friday.
Bu haftanın kontrolü
IaC ortamında tek bir source of truth yoktur, üç katman vardır: configuration (nasıl olmasını istediğimiz), state (hangi resource'u yönettiğimizi ve onun kimliğini gösteren kayıt) ve real infrastructure (provider üzerinde gerçekten çalışan sistem). Reliability, bu üç katmanın sürekli uzlaştırılmasıyla oluşur. Kontrol üç soruyla ilerler:
1. Doğru hedefte misiniz?
terraform workspace show
terraform state list
Workspace, backend, provider account/tenant ve region bilgisini doğrulayın.
2. State ile gerçek kaynak farklı mı?
terraform plan -refresh-only
Remote resource'ları değiştirmeden drift'i inceleyin;
planı apply etmeden önce farkın nedenini sınıflandırın.
3. Terraform neyi görmezden geliyor?
rg "ignore_changes|refresh=false" .
Ardından kritik resource inventory'sini provider'ın kendi
CLI/API çıktısıyla karşılaştırın.Drift neden görünmez kalır? Terraform'un görüş alanı üç şekilde sınırlanır: yanlış workspace, account, tenant veya region kontrol ediliyordur; resource state içinde değildir ya da attribute ignore_changes kapsamındadır; refresh kapatılmıştır veya provider ilgili davranışı modellemiyordur. Plan temiz olabilir, kapsam yine de eksik olabilir.
Beklenen çıktı
Üç komutun sonucunu birlikte okuyun:
- Refresh-only fark buldu, normal plan değişiklik önerdi: gerçek altyapı configuration'dan sapmış. Değişikliği geri alın ya da configuration'a taşıyın.
- Refresh-only fark buldu, normal plan değişiklik önermedi:
ignore_changes, computed attribute veya paylaşılan ownership olabilir. Bu alanın sahibini doğrulayın. - İki plan da temiz, provider çıktısı farklı: yanlış scope, unmanaged resource veya provider'ın modellemediği bir kör nokta olabilir.
Sağlıklı sonuç, üç komutun da sessiz kalması değil; her farkın bir sahibinin ve bir sınıfının olmasıdır.
Ne zaman aksiyon alınmalı
Fark bulduğunuzda ilk karar teknik değildir: hangi durum doğru, configuration mı, production mı? Önce buna karar verilmelidir. Yanlış refleks "state'i refresh edelim, düzelsin" demektir. terraform apply -refresh-only gerçek altyapıyı configuration'a döndürmez; sadece state'i, provider'ın bildirdiği mevcut duruma göre günceller. Incident sırasında yapılan değişikliği configuration'a taşımadan state'e kaydetmek kalıcı yönetim sağlamaz.
Drift'i yönetilebilir yapmak için:
- Drift detection'ı periyodik çalıştırın; remediation'ı otomatikleştirmeden önce değişikliği sınıflandırın.
- Her
ignore_changesiçin owner, gerekçe ve gözden geçirme tarihi tanımlayın. - Kritik invariant'ları Terraform dışından da doğrulayın: route, encryption, security rule, LB membership ve service readiness.
Başarı metriği drift'in hiç oluşmaması değil, ne kadar hızlı fark edilip güvenli şekilde uzlaştırıldığıdır.
Risk
"No changes" çıktısını kanıt olarak kabul etmek, görünmeyen değişikliği bir sonraki incident'e kadar gizler. İkinci risk, drift bulununca refleksle state'i güncellemektir: production'daki geçici bir müdahale böylece istenen durum hâline gelir ve sonraki apply'da kimse sorgulamaz. Üçüncü risk otomatik remediation'dır: sınıflandırılmamış bir farkı otomatik geri almak, incident sırasında bilerek yapılmış bir değişikliği de geri alabilir.
Otomatikleştirin
Haftalık elle kontrol başlangıçtır, varılacak yer değil. terraform plan -refresh-only -detailed-exitcode komutunu zamanlanmış bir pipeline'da çalıştırın ve çıkış kodu 2 olduğunda uyarı üretin; ignore_changes listesini sahipleriyle birlikte bir envanter olarak tutun; route, encryption, security rule, LB membership ve service readiness için Terraform dışında, provider API'sinden beslenen kontroller ekleyin. Bu boru hattının kurulumu DevOps ve platform mühendisliği ile CI/CD hizmetlerimizin kapsamındadır; altyapının günlük işletimi ise altyapı yönetimi hizmetimizin.
Eclit notu
Code is the source of intent. Production is the source of evidence. "No changes", production'ın doğru olduğunu değil; Terraform'un kendi kapsamı içinde yapacak bir değişiklik bulamadığını söyler. Sizin production ortamınızda Terraform'un görmediği alanları kim doğruluyor?
Serinin önceki yazısında firewall'ın bandwidth %30'dayken neden packet drop yaptığını incelemiştik; bu haftaki kontrol, o firewall rule'unun gerçekten configuration'daki rule olup olmadığını sorar. Terraform ve Ansible ile altyapı otomasyonunun temelleri için altyapıyı Terraform ve Ansible ile otomatikleştirme yazısına bakabilirsiniz.
Every Friday. One Production Check.