Cloud'da Maliyet Yönetimi: Fiyatlandırma Modelleri, Budget Alarmları, Tag'le Maliyet Dağıtımı ve Sık Yapılan Para Kaybettiren Hatalar
Bulut faturasını kontrol etmenin yolu, neye para ödediğini kalem kalem bilmek, budget'ı ilk gün kurmak ve her kaynağı tag'lemektir. Bookstore'un aylık maliyetini Retail Prices API'den gerçek liste fiyatlarıyla hesaplıyor, reservation ve savings plan'ı, budget'ın neden harcamayı durdurmadığını, FOCUS export'unu, FinOps döngüsünü ve durdurulan App Service'in neden para yazmaya devam ettiğini anlatıyoruz.
Sürüm notu: Bu yazıdaki örnekler .NET 10 (SDK 10.0.404), Azure CLI 2.92.0 ve ShellCheck 0.11.0 ile denenmiştir. Maliyet tahmini aracı, oturum açmadan kullanılabilen Azure Retail Prices API'ye karşı gerçekten çalıştırıldı; budget ve temizlik script'leri Azure'a gitmeyen sahte bir az komutuyla denendi. Azure'da budget ya da kaynak oluşturulmadı. Fiyatlar 14 Kasım 2026 tarihli liste fiyatlarıdır ve değişir.
Önce Tahmin Et
Sitedeki serilerin ortak örnek uygulaması Bookstore'un (bir online kitapçı) dev ortamında API, B1 (Basic tier'ın en küçük boyutu) boyutunda bir App Service planında çalışıyor. Ekip tasarruf için her akşam az webapp stop ile uygulamayı durduruyor, sabah başlatıyor. Planın aylık faturası ne kadar düşer? İkinci soru, production tahmininden: ayda 300 GB internet trafiği mi daha pahalı, 30 GB log mu? İkisinin cevabı da çoğu ekibi şaşırtıyor.
Neye Para Ödüyorsun?
Bulut faturası tek bir sayı değil, birkaç farklı ölçünün toplamı. Compute saat ya da saniye üzerinden ödenir: App Service planının instance saati, Container Apps'in vCPU-saniyesi, SQL'in vCore-saati. Storage, saklanan GB başına aylık ödenir. İşlemler (blob okuma ve yazma, Functions çalıştırması, Cosmos DB'nin (Azure'un NoSQL veritabanı) request unit'i) adet başına ödenir. Egress, yani Azure'dan internete çıkan trafik, GB başına ödenir; içeri giren trafik ücretsiz. Log ve telemetri, workspace'e yazılan GB başına ödenir. Bir de kullanılsın kullanılmasın her saat yazan sabit kalemler var: private endpoint, NAT (adres çevirisi yapan) gateway, public IP adresi.
Bu ayrım önemli, çünkü tasarrufun yolu kaleme göre değişir. Compute'u küçültür ya da kapatırsın, storage'ı daha ucuz tier'a taşırsın, egress'i CDN (içeriği kullanıcıya yakın sunuculardan dağıtan ağ) ile azaltırsın, log'u filtrelersin, sabit kalemleri ise ancak silerek azaltırsın.
Fiyatlandırma Modelleri ve AWS Karşılıkları
Varsayılan model pay-as-you-go: taahhüt yok, kullandığın kadar liste fiyatı. Sürekli çalışan iş yükleri için iki taahhüt modeli var. Reservation, belirli bir kaynak tipini (VM boyutu, SQL vCore'u) bir ya da üç yıl için önceden alır. Savings plan ise saatlik bir harcama taahhüdüdür: Learn'e göre bir ya da üç yıl için saatte belirli bir tutar harcamayı taahhüt edersin, o saatte kullanılmayan taahhüt kaybolur, üstündeki kullanım pay-as-you-go'dan faturalanır. Compute savings plan VM'leri, App Service'i, Functions Premium'u ve Container Apps'i kapsıyor; artık veritabanları için ayrı bir savings plan türü de var. Learn'deki bir değişikliğe dikkat: 1 Şubat 2027 ve sonrasında alınan reservation'lar, savings plan'ın kapsadığı bir servis içinse artık exchange edilemeyecek.
Spot VM'ler, Azure'un boştaki kapasitesini pay-as-you-go'ya göre "yüzde 90'a varan" indirimle satar; karşılığında Azure kapasiteye ihtiyaç duyduğunda makineyi geri alır. Kesintiye dayanıklı batch işler için uygundur, Bookstore.Api için değil. Azure Hybrid Benefit ise elindeki Windows Server ve SQL Server lisanslarını (Software Assurance ile) Azure'da kullanmanı sağlar. Aşağıdaki tablo bu modellerin ve yazının geri kalanındaki araçların AWS (Amazon Web Services; Amazon'un sunduğu bulut platformu) karşılıklarını veriyor.
| Azure | AWS karşılığı | Not |
|---|---|---|
| Reservation | Reserved Instances | Belirli kaynak tipi, 1 ya da 3 yıl |
| Savings plan (compute, database) | Savings Plans | Saatlik harcama taahhüdü; AWS "yüzde 72'ye varan" indirim diyor |
| Spot VM | Spot Instances | İkisi de "yüzde 90'a varan" indirim |
| Cost Management cost analysis | Cost Explorer | Maliyeti boyutlara göre kırmak |
| Budget ve action group | AWS Budgets ve budget actions | AWS, eşik aşılınca policy uygulayabiliyor |
| Anomaly alert | Cost Anomaly Detection | Beklenmeyen artışı bildirmek |
| Cost export | Data Exports | Ham maliyet verisini dışarı almak |
Bookstore'un Aylık Tahmini
Azure Pricing Calculator, kalem kalem tahmin yapmanın resmi yolu. Ama aynı fiyatlar, oturum açmadan sorgulanabilen Azure Retail Prices API'de de var ve bu, tahmini kod olarak tutmayı sağlıyor: bir kaynak değişince tahmin de aynı pull request'te değişir. Bookstore için küçük bir araç yazdık:
// Bookstore için aylık liste fiyatı tahmini; herkese açık Azure Retail Prices API'den (oturum açmak gerekmez).
// Çalıştır: dotnet run tools/cloud/cost-estimate.cs -- prod (ya da dev)
using System.Text.Json;
const double HoursPerMonth = 730; // Azure fiyat sayfalarının kullandığı ay
string environment = args.FirstOrDefault() ?? "prod";
// Etiket, OData filtresi, meter adı, meter'ın biriminde aylık miktar
(string Label, string Filter, string Meter, double Quantity)[] items = environment == "dev"
?
[
("App Service B1 Linux, 1 instance", AppService("Azure App Service Basic Plan - Linux", "B1"), "B1", HoursPerMonth),
("Azure SQL free offer", "", "", 0),
("Blob hot LRS, 5 GB", Blob, "Hot LRS Data Stored", 5),
("Log Analytics ingestion, 3 GB", Logs, "Analytics Logs Data Ingestion", 3),
("Internet egress, 20 GB", Egress, "Standard Data Transfer Out", 20),
]
:
[
("App Service P0v3 Linux, 2 instances", AppService("Azure App Service Premium v3 Plan - Linux", "P0v3"), "P0v3 App", 2 * HoursPerMonth),
("Azure SQL General Purpose, 2 vCores", Sql, "vCore", HoursPerMonth),
("Blob hot LRS, 50 GB", Blob, "Hot LRS Data Stored", 50),
("Private endpoints, 2", PrivateEndpoint, "Standard Private Endpoint", 2 * HoursPerMonth),
("NAT gateway, 1", Nat, "Standard Gateway", HoursPerMonth),
("Log Analytics ingestion, 30 GB", Logs, "Analytics Logs Data Ingestion", 30),
("Internet egress, 300 GB", Egress, "Standard Data Transfer Out", 300),
];
using HttpClient http = new() { BaseAddress = new Uri("https://prices.azure.com/") };
double total = 0;
Console.WriteLine($"Bookstore {environment}, westeurope, USD list prices retrieved {DateTime.UtcNow:yyyy-MM-dd}");
foreach ((string label, string filter, string meter, double quantity) in items)
{
double cost = filter.Length == 0 ? 0 : TieredCost(await GetTiersAsync(filter, meter), quantity);
total += cost;
Console.WriteLine($" {label,-38} {cost,9:0.00}");
}
Console.WriteLine($" {"Total per month",-38} {total,9:0.00}");
async Task<List<(double From, double Price)>> GetTiersAsync(string filter, string meter)
{
string url = "api/retail/prices?$filter=" + Uri.EscapeDataString($"{filter} and meterName eq '{meter}' and priceType eq 'Consumption'");
using JsonDocument doc = JsonDocument.Parse(await http.GetStringAsync(url));
return doc.RootElement.GetProperty("Items").EnumerateArray()
.Select(i => (From: i.GetProperty("tierMinimumUnits").GetDouble(), Price: i.GetProperty("retailPrice").GetDouble()))
.Distinct()
.OrderBy(t => t.From)
.ToList();
}
// Her kademenin fiyatı kendi alt sınırından bir sonraki kademenin alt sınırına kadar geçerli (ör. egress'in ilk 100 GB'ı ücretsiz)
static double TieredCost(List<(double From, double Price)> tiers, double quantity) =>
tiers.Select((tier, i) =>
{
double upTo = i + 1 < tiers.Count ? tiers[i + 1].From : double.MaxValue;
return Math.Max(0, Math.Min(quantity, upTo) - tier.From) * tier.Price;
}).Sum();
static string AppService(string product, string sku) =>
$"serviceName eq 'Azure App Service' and armRegionName eq 'westeurope' and productName eq '{product}' and skuName eq '{sku}'";
partial class Program
{
const string Sql = "serviceName eq 'SQL Database' and armRegionName eq 'westeurope' and productName eq 'SQL Database Single/Elastic Pool General Purpose - Compute Gen5' and skuName eq '2 vCore'";
const string Blob = "serviceName eq 'Storage' and armRegionName eq 'westeurope' and productName eq 'General Block Blob v2' and skuName eq 'Hot LRS'";
// Private Link ve NAT Gateway "Global" region'ında fiyatlanır
const string PrivateEndpoint = "serviceName eq 'Virtual Network' and armRegionName eq 'Global' and productName eq 'Virtual Network Private Link'";
const string Nat = "serviceName eq 'NAT Gateway' and armRegionName eq 'Global' and skuName eq 'Standard'";
const string Logs = "serviceName eq 'Log Analytics' and armRegionName eq 'westeurope' and skuName eq 'Analytics Logs'";
const string Egress = "serviceName eq 'Bandwidth' and armRegionName eq 'westeurope' and productName eq 'Rtn Preference: MGN' and skuName eq 'Standard'";
}
Araç her kalemin fiyatını API'den çekiyor ve kademeli fiyatları (ilk 100 GB egress'in ücretsiz olması gibi) hesaba katıyor. Production için:
$ dotnet run tools/cloud/cost-estimate.cs -- prod
Bookstore prod, westeurope, USD list prices retrieved 2026-11-14
App Service P0v3 Linux, 2 instances 129.94
Azure SQL General Purpose, 2 vCores 244.46
Blob hot LRS, 50 GB 0.98
Private endpoints, 2 14.60
NAT gateway, 1 32.85
Log Analytics ingestion, 30 GB 74.75
Internet egress, 300 GB 17.40
Total per month 514.98
İkinci tahmin sorusunun cevabı burada: 30 GB log, 300 GB egress'in dört katından fazla tutuyor. Analytics Logs'a yazılan her GB, ilk 5 GB'tan sonra 2,99 dolar; egress'in ilk 100 GB'ı ücretsiz, sonrası 0,087 dolar. Kapakların 50 GB'ı ise bir doları bulmuyor. Bir API'nin her isteği için birkaç satır log ve trace yazması, ayda 30 GB'a hızla ulaşır. Dev ortamının tahmini:
$ dotnet run tools/cloud/cost-estimate.cs -- dev
Bookstore dev, westeurope, USD list prices retrieved 2026-11-14
App Service B1 Linux, 1 instance 13.14
Azure SQL free offer 0.00
Blob hot LRS, 5 GB 0.10
Log Analytics ingestion, 3 GB 0.00
Internet egress, 20 GB 0.00
Total per month 13.24
Bu bir tahmin, fatura değil. Liste fiyatı kurumsal anlaşmalarda farklı olabilir, vergiler yok, Log Analytics'in ücretsiz 5 GB'ı aslında billing account başına ve araç bunu kaynak başına hesaplıyor. Amaç büyüklükleri görmek: neyin on dolar, neyin yüz dolar olduğunu bilmek.
Microsoft Cost Management
Gerçek harcamayı Cost Management'ta görürsün. Cost analysis, maliyeti resource group'a, servise, region'a ya da tag'e göre kırar. Budget, belirli bir scope için aylık bir tutar tanımlar ve gerçekleşen (actual) ya da tahmin edilen (forecasted) maliyet bir eşiği geçince bildirim gönderir. Learn'ün altını çizdiği nokta şu: budget kaynakları etkilemez ve harcamayı durdurmaz; yalnız haber verir. Maliyet verisi de 8-24 saat gecikmeyle gelir, yani budget bir saatlik bir patlamayı aynı saatte yakalamaz. Anomaly alert, subscription seviyesinde günde bir kez çalışır ve harcamayı son 60 günden üretilen bir tahminle karşılaştırır. Azure Advisor da boşta duran ya da gereğinden büyük kaynakları maliyet önerisi olarak listeler.
Ham veriyi dışarı almak için export var. FOCUS (FinOps Open Cost and Usage Specification; bulut sağlayıcılarının maliyet verisi için ortak şema), farklı bulutların faturalarını aynı kolonlarla okumayı sağlıyor. Learn'deki şema listesinde Azure'un FOCUS export'u 1.2-preview olarak geçiyor; FinOps Foundation'ın yayımladığı son sürüm Haziran 2026'da onaylanan 1.4. Birden çok bulut kullanıyorsan ya da maliyeti kendi veri ambarında analiz edeceksen bu biçimi seç.
Budget'ı Script ile Kurmak
Budget'ı ilk gün, portal'dan elle değil, script'le kurmak istiyoruz. 2. yazıda gördüğümüz bir sorun burada da var: az consumption budget create hâlâ preview ve bildirim tanımlayamıyor. Bu yüzden script REST (HTTP üzerinden kaynak odaklı API tarzı) API'yi az rest ile doğrudan çağırıyor:
#!/usr/bin/env bash
# app=bookstore tag'li her şey için aylık budget: gerçekleşen maliyette %80 ve tahminde %100 alarmı.
set -euo pipefail
: "${AZURE_SUBSCRIPTION_ID:?Set AZURE_SUBSCRIPTION_ID to the target subscription}"
AMOUNT="${1:?Usage: 10-budget.sh <monthly amount in the billing currency>}"
RG="rg-bookstore-prod-weu"
BUDGET="budget-bookstore-monthly"
az account set --subscription "$AZURE_SUBSCRIPTION_ID"
# Kim haberdar olur: şimdilik e-posta; aynı gruba sonra bir webhook ya da runbook eklenebilir
az monitor action-group create --name ag-bookstore-cost --resource-group "$RG" --short-name bscost \
--action email finops finops@example.com
AG_ID=$(az monitor action-group show --name ag-bookstore-cost --resource-group "$RG" --query id --output tsv)
# "az consumption budget create" preview ve alarm tanımlayamıyor; bu yüzden REST API doğrudan çağrılıyor
BODY=$(mktemp)
trap 'rm -f "$BODY"' EXIT
cat > "$BODY" <<JSON
{
"properties": {
"category": "Cost",
"amount": ${AMOUNT},
"timeGrain": "Monthly",
"timePeriod": { "startDate": "$(date -u +%Y-%m-01)T00:00:00Z" },
"filter": { "tags": { "name": "app", "operator": "In", "values": ["bookstore"] } },
"notifications": {
"actual-80": {
"enabled": true, "operator": "GreaterThan", "threshold": 80, "thresholdType": "Actual",
"contactGroups": ["${AG_ID}"], "locale": "en-us"
},
"forecast-100": {
"enabled": true, "operator": "GreaterThan", "threshold": 100, "thresholdType": "Forecasted",
"contactGroups": ["${AG_ID}"], "locale": "en-us"
}
}
}
}
JSON
az rest --method put --body "@${BODY}" \
--url "https://management.azure.com/subscriptions/${AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Consumption/budgets/${BUDGET}?api-version=2026-06-01"
Budget, app=bookstore tag'li her şeyi kapsıyor; 2. yazıdaki tag policy'leri bu yüzden önemli. İki bildirim var: gerçekleşen maliyet yüzde 80'i geçince ve ay sonu tahmini yüzde 100'ü geçince. Bildirimler bir action group'a gidiyor; bugün yalnız e-posta, ama aynı gruba bir webhook ya da runbook eklenerek bildirim bir otomasyona da bağlanabiliyor. Script'i Azure'a gitmeyen, çağrıları yazdıran sahte bir az ile çalıştırdık:
$ bash infra/cli/10-budget.sh 600
+ az account set --subscription 00000000-0000-0000-0000-000000000000
+ az monitor action-group create --name ag-bookstore-cost --resource-group rg-bookstore-prod-weu --short-name bscost --action email finops finops@example.com
+ az monitor action-group show --name ag-bookstore-cost --resource-group rg-bookstore-prod-weu --query id --output tsv
+ az rest --method put --body @/tmp/tmp.GYwWWkYJfx --url https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Consumption/budgets/budget-bookstore-monthly?api-version=2026-06-01
body is valid JSON; notifications: actual-80, forecast-100
Bu, Azure'ın budget'ı kabul ettiğini değil, script'in doğru çağrıları doğru gövdeyle ürettiğini gösteriyor.
Tag ile Maliyet Dağıtımı ve FinOps
"Bookstore ayda ne kadar tutuyor?" sorusunun cevabı tag'lerden gelir. 2. yazıda her resource group'a app, environment, owner ve cost-center tag'lerini koyduk, eksik olanı reddeden ve resource group'tan kaynağa kopyalayan policy'leri de kurduk. Cost analysis'te cost-center'a göre gruplayınca hangi ekibin ne harcadığı görünür. Paylaşılan kaynakların (ortak bir log workspace'i gibi) maliyetini ekipler arasında bölmek için cost allocation rule'ları var, ama Learn'e göre bunlar yalnız Enterprise Agreement ve Microsoft Customer Agreement müşterilerinde çalışıyor.
FinOps, bunun bir ekip alışkanlığına dönüşmüş hâli. FinOps Foundation'ın çerçevesi üç aşamadan oluşur: Inform (maliyeti görünür ve sahibine atanmış hâle getirmek), Optimize (israfı azaltmak, doğru boyut ve doğru fiyat modelini seçmek) ve Operate (bunu sürekli bir sürece bağlamak). Bookstore ölçeğinde bunun karşılığı basit: her kaynağın tag'i var, her ayın ilk haftası Selin ve ekip cost analysis'e bakıyor, her yeni servis maliyet tahminiyle birlikte geliyor.
Para Kaybettiren Hatalar
Unutulan ortamlar. Bir pull request için açılan önizleme ortamı, bir yük testi için kurulan büyük bir veritabanı, kimsenin silmediği bir deneme subscription'ı. Çözüm, geçici her resource group'a bir bitiş tarihi tag'i (expires-on) koymak ve süresi geçenleri düzenli olarak listelemek:
#!/usr/bin/env bash
# expires-on tag'i (yyyy-mm-dd) geçmişte kalan resource group'ları bulur; yalnız --delete ile siler.
set -euo pipefail
: "${AZURE_SUBSCRIPTION_ID:?Set AZURE_SUBSCRIPTION_ID to the target subscription}"
TODAY=$(date -u +%Y-%m-%d)
az account set --subscription "$AZURE_SUBSCRIPTION_ID"
# ISO tarihler string olarak da doğru sıralanır; string karşılaştırması tarih karşılaştırmasıdır
EXPIRED=$(az group list --output tsv \
--query "[?tags.\"expires-on\" && tags.\"expires-on\" < '${TODAY}'].name")
for RG in $EXPIRED; do
if [[ "${1:-}" == "--delete" ]]; then
az group delete --name "$RG" --yes --no-wait
echo "deleting ${RG}"
else
echo "would delete ${RG} (run with --delete)"
fi
done
Sorgu, tarihleri string olarak karşılaştırıyor; yyyy-mm-dd biçiminde bu, tarih karşılaştırmasıyla aynı sonucu verir. Azure CLI'ın kullandığı JMESPath (JSON üzerinde sorgu dili) kütüphanesiyle, dört resource group'luk örnek bir listeye karşı denedik:
$ bash infra/cli/10-cleanup-expired.sh
+ az account set --subscription 00000000-0000-0000-0000-000000000000
+ az group list --output tsv --query [?tags."expires-on" && tags."expires-on" < '2026-11-14'].name
would delete rg-bookstore-pr1042-weu (run with --delete)
Bitiş tarihi geçmiş tek grup listelendi; tarihi gelecekte olan ve tag'i olmayan gruplar listede yok. Script varsayılan olarak hiçbir şey silmiyor.
Durdurulan uygulamanın para yazmaya devam etmesi. Tahmin sorusunun ilk cevabı: hiç düşmez. App Service'te faturalanan şey uygulama değil, plan; Learn'e göre faturayı durdurmanın yolu planı silmek ya da Free tier'a indirmek. 10 Kasım 2026'da plan seviyesinde durdurma public preview olarak geldi ve durdurulan planda compute faturası duruyor, ama yalnız Premium v4 planlar için. Dev ortamında gece sıfıra inen bir şey istiyorsan Container Apps'in scale-to-zero'su ya da SQL'in ücretsiz teklifi daha doğru araçlar.
Log ve telemetri patlaması. Tahminde gördüğümüz gibi en hızlı büyüyen kalem genellikle bu. Debug seviyesinde bırakılmış bir log, her isteği tam gövdesiyle yazan bir middleware ya da sampling'siz trace, faturayı haftalar içinde katlar. Observability serisi sampling'i ve neyin toplanacağını ayrıntılı anlatıyor; workspace'e bir günlük üst sınır (daily cap) koymak da son savunma hattı.
Silinmeyen ekler. Learn'e göre bir VM silindiğinde, oluştururken silme seçeneği ayarlanmadıysa diskleri ve ağ kaynakları yerinde kalabilir. Sahipsiz diskler, snapshot'lar ve public IP'ler kimseye görünmeden her ay fatura yazar. Aşırı büyük SKU (ürün boyutu) da aynı gruptan: "ileride lazım olur" diye seçilen P3v3 plan, P0v3'ün birkaç katı tutar. 9. yazıdaki NAT gateway ve private endpoint'ler de dev ortamında gerçekten gerekli mi, bir kez daha sor.
Üretimde Dikkat
Taahhüt modellerine en az birkaç aylık kullanım verisiyle gir. Reservation ya da savings plan, kullanmadığın kapasite için de ödeme demek; Advisor'ın önerileri geçmiş kullanıma bakarak hesaplanıyor.
Budget'ı subscription'ın ilk gününde kur. Ücretsiz krediyle açılan bir hesapta bile bir eşik ve bir e-posta, yanlışlıkla açık kalan bir kaynağın ay sonuna kadar fark edilmemesini engeller.
Fiyatı mimari kararın parçası yap. Yeni bir servis eklenirken tahmin aracına bir satır eklemek, kararı veren kişinin maliyeti görmesini sağlar.
Sık Düşülen Tuzaklar
Budget'ın harcamayı durdurduğunu sanmak. Durdurmaz; yalnız bildirir. Durdurmak istiyorsan action group'a bağlı bir otomasyon yazman gerekir ve bu otomasyonun production'ı kapatmayacağından emin olmalısın.
Tag'leri sonradan eklemek. Tag'ler geçmiş maliyet satırlarını geriye dönük değiştirmez; tag'siz geçen ayların maliyeti tag'siz kalır.
Fiyat sayfasındaki para birimine ve bölgeye bakmamak. Retail Prices API varsayılan olarak dolar döner; currencyCode parametresiyle başka para birimi isteyebilirsin. Aynı servis region'lar arasında farklı fiyatlanır.
Küçük Bir Deneme
★☆☆ cost-estimate.cs'i currencyCode='EUR' ile çalışacak şekilde değiştir ve prod tahminini euro olarak al.
★★☆ Tahmine Container Apps'i ekle: aylık 2 milyon istek, ortalama 0,5 vCPU ve 1 GiB bellekle günde 8 saat aktif bir replica. Ücretsiz hakları hesaba kat ve sonucu App Service satırıyla karşılaştır.
★★★ 10-cleanup-expired.sh'i bir GitHub Actions workflow'unda her gece çalışacak şekilde tasarla: hangi kimlikle, hangi role sahip olarak çalışmalı, silme işlemi için insan onayı nasıl eklenir? GitHub Actions serisinin Azure'a şifresiz deploy'u anlatan 10. yazısı başlangıç noktası.
Serinin son yazısında bütün bu parçaları bir mimari gözden geçirmede birleştiriyoruz: Well-Architected Framework'ün beş pillar'ı, yedekleme ve felaket senaryosu, lock-in ve bir sonraki adım olarak Infrastructure as Code.