
Azure App Service ile Zero-Config Dağıtım
İçindekiler
Lokalde testleri geçen kodun production’da patlamaması sadece kod kalitesine değil; altyapı, config ve deployment süreçlerine de bağlı. İşletim sistemi yamaları, SSL sertifikaları veya IIS/Nginx konfigürasyonlarıyla uğraşmak, geliştirme eforunu sömüren ve projeyi canlıya alma süresini uzatan ciddi bir operasyonel yük.
Günün sonunda asıl derdimiz altyapı yönetmek değil, kodu yazıp sistemi sağlıklı bir şekilde canlıya çıkarmak. Azure App Service gibi PaaS çözümleri bu yüzden var. Altyapı yönetimini tamamen Azure’a devredip operasyonel ayrıntılarla uğraşmayı bırakıyoruz.
Neden Sunucu Yönetmek İstemiyoruz?
IaaS ve PaaS arasındaki temel fark kontrol ve sorumluluk paylaşımıdır. Bir sanal makine kiraladığımızda elimize geçen tek şey donanım ve yalın bir işletim sistemidir. Güvenlik güncellemeleri, firewall kuralları, web sunucusu ayarları ve runtime bağımlılıklarını yönetmek tamamen bizim işimizdir. Kontrol bizdedir ama bakım maliyeti ve hata yapma riski de sırtımızdadır.
Azure App Service bu yükü tamamen ortadan kaldırır. Arka plandaki donanım, işletim sistemi ve web sunucusu yönetimi Azure’da kalır. Herhangi bir container mimarisiyle uğraşmadan, standart bir .NET 10 API projesini doğrudan buluta deploy edip anında yayına alabiliriz.
Bütün bu altyapı soyutlamasının portal tarafındaki karşılığını “Basics” sekmesine bakınca direkt görebiliyoruz. Sisteme sadece uygulamanın çalışacağı hedef runtime’ı ve region’ı veriyoruz. Sunucu tipi, Windows sürümü veya IIS ayarları gibi detaylarla uğraşmıyoruz.
Altyapıdan kurtulduk diye kodu sunucuya manuel atacak değiliz. “Deployment” sekmesinden GitHub’ı bağlayıp deploy sürecini ilk adımdan otomatize ediyoruz. Projeyi yayına almak, sadece repoya kod push’lamaktan ibaret hale geliyor. Alt kısımdaki eski tip ‘Basic authentication’ ayarını da kapatarak, deployment kanalını brute-force riskine karşı baştan kilitliyoruz.
Canlı Ortamda Config Yönetimi
Bir uygulamayı canlıya alırken en sık yapılan hata, veritabanı şifreleri veya API anahtarları gibi hassas verileri doğrudan projenin içindeki config dosyalarında bırakmaktır. Kural çok net: Kod ve config birbirinden tamamen ayrılmalıdır. Bu key’leri repoya commit’lediğimiz an, koda erişimi olan herkes production ortamının da anahtarlarına sahip olur.
Bu key’lerin kodun içinde değil, doğrudan uygulamanın koştuğu environment’ta tutulması gerekir. Azure App Service, environment variable yönetimini portal üzerinden temiz bir şekilde halletmemizi sağlıyor.
.NET’in config yapısı Azure tarafında ekstra kod gerektirmeden doğrudan çalışıyor. Portaldan eklediğimiz ExternalServices__ApiKey değişkenindeki çift alt tire (__), proje ayağa kalktığında .NET tarafından otomatik olarak iki nokta (:) hiyerarşisine map ediliyor.
Bu key’i ana appsettings.json dosyasına eklemeye bile gerek yok. Lokalde geliştirme yaparken zaten appsettings.Development.json veya User Secrets üzerinden yürüyoruz. Projeyi Azure’a deploy ettiğimiz an, portaldaki environment variable doğrudan devreye giriyor.
Kod tarafında yapı hiç değişmiyor, alıştığımız standart yöntemle değeri okumaya devam ediyoruz:
// Program.cs veya ilgili servisvar apiKey = builder.Configuration.GetValue<string>("ExternalServices:ApiKey");// Çıktı: LIVE_PROD_KEY_999Repoyu public yapsak dahi canlı ortam şifrelerini sızdırma riskimiz kalmıyor. Connection string’ler ve kritik key’ler sadece Azure üzerinde, yani olması gerektiği yerde duruyor.
PaaS Mimarisi ve Altyapı Kısıtları
Azure App Service gibi PaaS çözümleri sunucu yönetimini bizden alıp işimizi hızlandırsa da, arka plandaki multi-tenant yapının getirdiği bazı mimari kısıtlar var. Free veya Shared gibi alt paketler SLA sunmadığı için bunları sadece test ve POC süreçlerinde kullanıp geçiyoruz. Prod ortamı için üst katmanlara çıksak bile, mimariyi çizerken hesaba katmamız gereken katı kurallar değişmiyor.
Burada en çok takıldığımız yer outbound IP mevzusu. App Service üzerinde koşan bir API’nin dışarı çıkarken kullandığı sabit bir IP adresi yok. Third-party bir servise request attığında, bu istek Azure’un o region için ayırdığı dinamik IP havuzundan çıkıyor. Karşı taraf güvenlik için IP whitelist talep ettiğinde tek bir IP veremiyorsun; tüm data center’ın outbound havuzunu iletmen gerekiyor. İlla sabit bir IP dayatması varsa, mimariye NAT Gateway gibi ekstra bileşenler ekleyip maliyeti şişirmek zorunda kalıyorsun.
İşletim sistemi tarafında da izolasyon katı. Sunucuda root yetkimiz olmadığı için makineye girip özel bir C++ DLL’i, driver veya kernel modülü kurma şansımız yok. Uygulamanın ihtiyaç duyduğu tüm dependency’ler doğrudan projeyle birlikte gelmeli veya container kullanıyorsak imajın içine gömülmeli.
Bu durum bir mimari eksiklik değil, PaaS’ın standart çalışma mantığı. Sunucuya tam erişimimizin olmadığını ve IP’lerin dinamik değiştiğini en baştan hesaba katarak ilerlemek, prod ortamında patlayacak entegrasyon sorunlarını daha kodu yazmadan çözüyor.