· kaynak dev.to (home feed)
Terraform'daki null varsayılan, 14 veritabanında RDS silme korumasını sessizce devre dışı bıraktı
Bir wrapper modülün RDS ayarı için null geçmesi, Terraform'ın platform modülünün varsayılanını hiç uygulamaması anlamına geliyordu; böylece silme koruması varsayılan olarak false'a döndü — ve bir destroy işlemi QA veritabanını sildi.

Ne oldu
Ağustos ayında, kişisel bir sandbox'ta çalıştığını düşünen bir mühendis, aslında paylaşılan QA ortamı olan ortamda terraform destroy komutunu çalıştırdı ve QA veritabanı silinen kaynaklar arasındaydı. Sergey Shinder'ın dev.to'da yayımladığı postmortem'e göre başta kimse endişelenmedi: kurumun veritabanı modülü deletion_protection değerini ayarlıyor ve AWS, bu bayrak etkinleştirilmiş bir RDS instance'ı silmeyi reddetmesi gerekiyordu. Instance yine de kayboldu.
Bir null varsayılanları nasıl ezdi
Platform ekibi, bayrak için değişkeni varsayılan olarak true olan veritabanı modülünün sahibi. Ekiplerin çoğu bu modülü doğrudan çağırmıyor; isimlendirme ve etiketleme kurallarını ekleyen ve aynı ayarı null varsayılanıyla yeniden ortaya çıkaran bir wrapper kullanıyorlar; yanında da bir ekip hiçbir şey söylemediğinde platform modülünün kendi varsayılanının uygulanması gerektiğini belirten bir yorum var.
Shinder'ın açıkladığı gibi, Terraform değeri bu şekilde yorumlamıyor. Değişkenler aksi beyan edilmedikçe nullable'dır ve nullable bir değişkene null geçmek bir atlama değil açık bir atamadır; dolayısıyla modülün kendi varsayılanına hiç bakılmaz. Null daha sonra aws_db_instance kaynağına ulaştı; orada null sağlamak argümanı tamamen atlamakla eşdeğerdir. Bu, kararı AWS provider'ına bıraktı ve provider'ın silme koruması için varsayılanı false'tur.
Etki alanı
Wrapper üzerinden sağlanan her veritabanı bu nedenle korumasız oluşturulmuştu. Her plan, deletion_protection = false satınını gösteriyordu; ekiplerin güvendiği bir modülde yaklaşık altmış satırdan yalnızca biri. Kurum sonunda AWS Config yönetilen kuralı rds-instance-deletion-protection-enabled'ı etkinleştirdiğinde, yirmi iki instance'ın on dördü işaretlendi; hepsi wrapper'ın ilk sürümünden beri onunla oluşturulmuştu. QA, geceye ait bir anlık kopyadan yeniden inşa edildi ve bir öğleden sonraya ait test verisi de onunla birlikte gitti.
Düzeltme
Shinder sonrasında yapılan birkaç değişikliği listeliyor:
Platform modülündeki her değişken artık nullable = false beyan ediyor; böylece gelen bir null, modülün varsayılanıyla değiştiriliyor ve wrapper'ın yazarının baştan istediği sonuç ortaya çıkıyor.
Wrapper artık kendi varsayılanlarını ayarlamıyor ve değerleri yalnızca bir ekip açıkça sağladığında iletiyor.
AWS Config kuralı, gerilemeleri yakalamak için her hesapta etkin kalıyor.
Veritabanı kaynağı, çözümlenen değer true olmadığı sürece planı başarısız kılan bir precondition içeriyor.
Neden önemli
Buradaki arıza tek seferlik bir hata değil, yapısal bir sorun. Terraform'da null, ayarlanmamış anlamına gelir ve ayarlanmamış bir değer zincirdeki bir sonraki tüketiciye düşer — bu durumda dahili bir standarttan habersiz bir provider'a. İç varsayılanın miras alınmasını belirtmek için null varsayılanları kullanan wrapper modüller yaygın bir desendir ve ortaya çıkan arıza sessizdir: planlar başarılı olur, kaynaklar oluşturulur ve bir destroy işlemi çalışmaması gerektiği bir anda çalışana kadar hiçbir şey ortaya çıkmaz.
Düzeltmeler bu ekibin ötesine de genelleniyor. nullable = false beyan etmek, modül varsayılanlarının geçiş sırasında korunmasını sağlar. Silme koruması gibi korkuluk ayarları precondition'larla zorlanabilir; böylece yanlış bir değer sessizce taşınmak yerine planı durdurur. AWS Config kuralları gibi harici denetimler, modül yazarları değişken semantiğini yanlış anlasa bile yanlış yapılandırmayı yakalar. Ve olay, workspace seçiminin bir destroy komutunun etki alanının kodun kendisi kadar bir parçası olduğunun da bir hatırlatıcısı.
- #terraform
- #aws
- #rds
- #infrastructure-as-code
- #postmortem