Cloud Networking Temelleri: VNet, Subnet, NSG, Private Endpoint ve Uygulamayı İnternete Kapatmak
Bir PaaS uygulamasını internete kapatmak için giden trafiği VNet integration ile VNet'e sokar, veritabanına ve storage'a private endpoint ile özel IP verir, private DNS zone'u VNet'e bağlar ve public erişimi en son kapatırsın. Bookstore'un adres planını bir araçla denetliyor, NSG kurallarını, NAT gateway'i, DNS'in neden asıl tuzak olduğunu, maliyeti ve AWS VPC karşılıklarını 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. Adres planı aracı yerelde çalıştırıldı; ağ script'i ShellCheck ile denetlendi ve parametreleri az ... --help ile kontrol edildi, ama Azure'a karşı çalıştırılmadı. Azure davranışları Microsoft Learn'den, liste fiyatları Azure Retail Prices API'den alındı (14 Kasım 2026).
Önce Tahmin Et
Sitedeki serilerin ortak örnek uygulaması Bookstore'da (bir online kitapçı) BookstoreDb'nin sunucusu için bir private endpoint oluşturdun, ardından sunucunun public erişimini kapattın. Ama private DNS zone'u VNet'e bağlamayı unuttun. Bookstore.Api, connection string'deki sql-bookstore-dev-weu.database.windows.net adına bağlanmaya çalıştığında ne olur: private endpoint'in adresine mi gider, hata mı alır, hangi hatayı alır? İkinci soru: storage hesabının da public erişimini kapatırsan Bookstore'da ne bozulur? Cevaplar yazının içinde.
VNet, Subnet ve Adres Planı
VNet (Virtual Network; Azure'da sana ayrılmış özel ağ), bir region'daki kaynaklarının birbirleriyle özel IP adresleri üzerinden konuştuğu ağdır. Adres aralığını CIDR (Classless Inter-Domain Routing; 10.20.0.0/16 gibi adres ve önek uzunluğuyla gösterim) ile verirsin ve onu subnet'lere bölersin. CIDR ve subnet'in temeli, NAT (Network Address Translation; özel adresleri public bir adrese çeviren mekanizma) ile birlikte Networking ve HTTP serisinin "IP Adresi, Subnet, Port ve NAT: localhost, 0.0.0.0 ve Container'larda Bağlantı" yazısında; burada Azure'a özgü kurallara bakıyoruz.
İlk kural: Azure her subnet'te beş adresi kendine ayırır. Learn'e göre bunlar ağ adresi, varsayılan gateway, Azure DNS'i VNet'e taşıyan iki adres ve broadcast adresi. En küçük subnet /29, yani sekiz adresten üçü kullanılabilir. İkinci kural: bazı servisler subnet'i kendine ister. App Service'in VNet integration'ı için subnet Microsoft.Web/serverFarms'a delege edilir ve en az /28 olmalı; Learn, bir planın en büyük ölçeğini karşılamak için /26 öneriyor. Container Apps'in workload profiles environment'ı Microsoft.App/environments'a delege edilmiş en az /27 bir subnet ister ve 12 adresi altyapı için ayırır. Bir subnet'e environment kurulduktan sonra onu büyütmek kolay değil; bu yüzden planı baştan yazıyoruz. Küçük bir araç planı denetliyor:
// Bookstore VNet'inin adres planı: boyutları, çakışmaları ve Azure'un her subnet'te ayırdığı adresleri kontrol eder.
// Çalıştır: dotnet run tools/cloud/subnets.cs
using System.Net;
IPNetwork vnet = IPNetwork.Parse("10.20.0.0/16");
// Bu VNet'in ileride peering ya da VPN ile bağlanabileceği ağlar: çakışmamalı
(string Name, IPNetwork Range)[] neighbours =
[
("vnet-bookstore-prod-weu", IPNetwork.Parse("10.21.0.0/16")),
("office network over VPN", IPNetwork.Parse("10.20.128.0/20")),
];
(string Name, string Cidr, int MinPrefix, string Purpose)[] plan =
[
("snet-app", "10.20.1.0/26", 28, "App Service VNet integration (Microsoft.Web/serverFarms)"),
("snet-cae", "10.20.2.0/27", 27, "Container Apps environment (Microsoft.App/environments)"),
("snet-pe", "10.20.3.0/27", 29, "Private endpoints: SQL, Blob"),
("snet-jobs", "10.20.4.0/28", 27, "A mistake: too small for a second environment"),
("snet-pe-old", "10.20.3.16/28", 29, "A mistake: overlaps snet-pe"),
];
const int AzureReserved = 5; // ağ adresi, gateway, 2 x Azure DNS, broadcast
List<(string Name, IPNetwork Range)> accepted = [];
Console.WriteLine($"{"Subnet",-12} {"CIDR",-15} {"First usable",-13} {"Usable",6} Result");
foreach ((string name, string cidr, int minPrefix, string purpose) in plan)
{
IPNetwork range = IPNetwork.Parse(cidr);
int size = 1 << (32 - range.PrefixLength);
byte[] first = range.BaseAddress.GetAddressBytes();
first[3] += 4; // .0 ağ adresi, .1 gateway, .2 ve .3 Azure DNS
string result =
!vnet.Contains(range.BaseAddress) ? "outside the VNet"
: range.PrefixLength > minPrefix ? $"too small, needs /{minPrefix} or larger"
: accepted.FirstOrDefault(a => Overlaps(a.Range, range)) is { Name: not null } hit ? $"overlaps {hit.Name}"
: "ok";
if (result == "ok")
{
accepted.Add((name, range));
}
Console.WriteLine($"{name,-12} {cidr,-15} {new IPAddress(first),-13} {size - AzureReserved,6} {result} ({purpose})");
}
foreach ((string name, IPNetwork range) in neighbours)
{
Console.WriteLine($"VNet {vnet} vs {name} {range}: {(Overlaps(vnet, range) ? "OVERLAP, they can not be connected" : "no overlap")}");
}
static bool Overlaps(IPNetwork a, IPNetwork b) => a.Contains(b.BaseAddress) || b.Contains(a.BaseAddress);
Plana bilerek iki hata koyduk. Çıktı:
$ dotnet run tools/cloud/subnets.cs
Subnet CIDR First usable Usable Result
snet-app 10.20.1.0/26 10.20.1.4 59 ok (App Service VNet integration (Microsoft.Web/serverFarms))
snet-cae 10.20.2.0/27 10.20.2.4 27 ok (Container Apps environment (Microsoft.App/environments))
snet-pe 10.20.3.0/27 10.20.3.4 27 ok (Private endpoints: SQL, Blob)
snet-jobs 10.20.4.0/28 10.20.4.4 11 too small, needs /27 or larger (A mistake: too small for a second environment)
snet-pe-old 10.20.3.16/28 10.20.3.20 11 overlaps snet-pe (A mistake: overlaps snet-pe)
VNet 10.20.0.0/16 vs vnet-bookstore-prod-weu 10.21.0.0/16: no overlap
VNet 10.20.0.0/16 vs office network over VPN 10.20.128.0/20: OVERLAP, they can not be connected
İlk kullanılabilir adresin .4 olduğuna dikkat et. Son satır, en pahalı hatayı gösteriyor: ofis ağı VNet'in içine düşen bir aralık kullanıyorsa, VPN (iki ağı internet üzerinden şifreli olarak bağlayan bağlantı) ile bağlandığında iki taraf aynı adreslere farklı yerlerden ulaşmaya çalışır. VNet'in adres aralığını değiştirmek de içindeki kaynakları taşımak demek. Bu yüzden şirketteki bütün ağların (ofis, diğer VNet'ler, diğer bulutlar) aralıklarını bir yerde tutup her yeni VNet'e çakışmayan bir aralık ver; dev, staging ve prod için ayrı /16'lar rahat bir başlangıç.
NSG Kuralları ve AWS Karşılıkları
NSG (Network Security Group; subnet'e ya da ağ kartına bağlanan trafik kuralları listesi), gelen ve giden trafiği öncelik sırasıyla süzer. Öncelik 100 ile 4096 arası bir sayı; küçük sayı önce değerlendirilir ve ilk eşleşen kural kazanır. Kuralların altında silinemeyen varsayılanlar var: gelen yönde VNet içi trafiğe (65000) ve Azure load balancer'ına (65001) izin, sonra her şeyi reddeden 65500; giden yönde VNet içine ve internete izin, sonra ret. NSG stateful çalışır: izin verilen bir bağlantının dönüş trafiği için ayrı kural gerekmez. Kaynak ya da hedef olarak IP aralığı yerine VirtualNetwork, Internet, AzureLoadBalancer gibi service tag'ler kullanabilirsin. Aşağıdaki tablo bu yazıdaki kavramların AWS (Amazon Web Services; Amazon'un sunduğu bulut platformu) karşılıklarını veriyor; tablodaki VPC (Virtual Private Cloud; AWS'nin VNet'e karşılık gelen özel ağı) ve S3 (AWS'nin object storage servisi) önceki yazılarda da geçti.
| Azure | AWS karşılığı | Not |
|---|---|---|
| VNet, subnet | VPC, subnet | İkisi de her subnet'te 5 adres ayırır |
| NSG (stateful, izin ve ret kuralı) | Security group (stateful, yalnız izin) ve network access control list (stateless) | AWS'de iki ayrı katman |
| Private endpoint | Interface VPC endpoint (PrivateLink) | Servise VNet içinden özel IP ile erişim |
| Service endpoint | Gateway endpoint (S3 ve DynamoDB, ücretsiz) | Servisin public adresine özel yol |
| NAT gateway | NAT gateway | Liste fiyatı ikisinde de saatte 0,045 ve GB başına 0,045 dolar |
| Private DNS zone | Route 53 private hosted zone | Yalnız bağlı ağlarda cevap veren DNS |
Default Outbound Access ve NAT Gateway
Eskiden bir subnet'teki VM, hiçbir ayar yapmadan internete çıkabiliyordu; Azure ona görünmez bir public IP üzerinden çıkış veriyordu. Learn'e göre 31 Mart 2026'dan sonra yayınlanan API sürümleriyle oluşturulan yeni VNet'lerde subnet'ler varsayılan olarak private: bu örtük çıkış yok. Eski API sürümüne sabitlenmiş araçlar eski davranışı sürdürüyor, mevcut VNet'ler de değişmiyor. Script'teki --default-outbound false bu yüzden açıkça yazıldı: hangi araçla oluşturulursa oluşturulsun sonuç aynı olsun.
Uygulamanın internete sabit bir adresten çıkması gerektiğinde NAT gateway kullanırsın. Bookstore'da örnek hazır: kargo firmasının API'si yalnız izin listesindeki IP'lerden gelen istekleri kabul ediyor. NAT gateway'i subnet'e bağlarsın, ona bir ya da birkaç public IP verirsin ve o subnet'ten internete giden bütün trafik bu adreslerden çıkar. Learn'e göre Standard SKU (ürün seviyesi) zonal, yeni StandardV2 zone-redundant. Fiyatı küçük değil: liste fiyatı saatte 0,045 dolar (ayda yaklaşık 33 dolar) artı işlenen GB başına 0,045 dolar, üstüne public IPv4 adresi için saatte 0,005 dolar. Partner izin listesi gibi gerçek bir ihtiyaç yoksa dev ortamına koyma.
PaaS'ı Ağa Bağlamak: İçeri ve Dışarı
App Service, Container Apps ve Azure SQL birer PaaS (Platform as a Service; altyapıyı platformun yönettiği servis modeli) servisi; senin VNet'inin içinde çalışmazlar. Onları ağa bağlarken iki yönü ayırmak gerekiyor.

Dışarı giden trafik için App Service'te VNet integration var. Learn bunu açıkça söylüyor: VNet integration yalnız outbound'dur, uygulamaya VNet'ten gelen trafiği sağlamaz. Uygulamanın instance'ları delege edilmiş snet-app subnet'ine bağlanır ve SQL'e, storage'a giden istekler VNet'in içinden geçer. --vnet-route-all-enabled true, internete giden trafiği de VNet'e sokar; NSG ve NAT gateway ancak böyle bütün trafiğe uygulanır. Container Apps'te karşılığı environment'ı oluştururken bir subnet vermek; bu sonradan değiştirilemiyor, 5. yazıda VNet'siz açtığımız environment'ı yeniden oluşturmak gerekir.
İçeri gelen trafik için private endpoint var: bir PaaS kaynağına senin subnet'inden özel bir IP adresi verir. SQL sunucusuna snet-pe'de örneğin 10.20.3.4 adresi verilir ve VNet'teki her şey ona bu adresten ulaşır. Bir alternatif olan service endpoint ise subnet'ten servisin public adresine Azure omurgası üzerinden bir yol açar; kaynak hâlâ public IP'yi kullanır, on-prem'den çalışmaz ve tek bir kaynağı değil servisin tamamını hedefler. Learn, yeni tasarımlarda private endpoint'i öneriyor. Fiyatı endpoint başına saatte 0,01 dolar (ayda yaklaşık 7,3 dolar) ve işlenen veri için her yönde GB başına 0,01 dolar.
Private Endpoint ve Private DNS
Private endpoint'in incelikli kısmı DNS. Connection string'deki ad değişmiyor: sql-bookstore-dev-weu.database.windows.net. Private endpoint oluşturulunca Azure bu public ada, sql-bookstore-dev-weu.privatelink.database.windows.net'e işaret eden bir CNAME (bir adı başka bir ada yönlendiren DNS kaydı) ekler. Bu CNAME her yerden görünür; asıl iş, privatelink adının nereye çözüldüğünde. VNet'e bağlı (link'li) bir privatelink.database.windows.net private DNS zone'u varsa, VNet'teki sorgular Azure'un DNS adresine (168.63.129.16) gider ve zone'daki A kaydı private IP'yi döner. Zone yoksa ya da VNet'e bağlı değilse, ad public IP'ye çözülür.
Tahmin sorusunun cevabı bu. Link unutulunca API, sunucunun public adresine gider. Public erişim kapalı olduğu için SQL bağlantıyı reddeder; Learn'e göre public erişim kapalıyken dışarıdan gelen bağlantılar 47073 hatası alır. Hata mesajı DNS'ten bahsetmez; ilk bakışta "private endpoint çalışmıyor" gibi görünür. Kontrol etmek için VNet'teki bir makineden (ya da App Service'in Kudu konsolundan) nslookup sql-bookstore-dev-weu.database.windows.net çalıştırırsın: cevap 10.20.3.x değilse sorun DNS'te. Learn'ün yeni bir uyarısı da önemli: DNS erişim değildir. Public ad çözülüyor olsa bile, public erişim kapalıysa servis bağlantıyı reddeder; tersine, DNS'i doğru kurmak public erişimi kendiliğinden kapatmaz.
Zone ile endpoint'i bağlamanın en temiz yolu DNS zone group: endpoint'in A kaydını zone'a kendisi yazar, IP değişirse günceller, endpoint silinince kaydı siler. Ofisten VPN ile bağlanan geliştiriciler için de aynı sorun var: Learn, on-prem DNS sunucusunda conditional forwarder'ın privatelink zone'una değil, public zone'a (database.windows.net) yönlendirilmesini söylüyor.
Bookstore'un Ağ Script'i
Hepsini bir araya getiren script:
#!/usr/bin/env bash
# Bookstore'un ağı: VNet, delege edilmiş subnet'ler, SQL ve Blob için private endpoint'ler, sonra public erişimi kapatmak.
set -euo pipefail
: "${AZURE_SUBSCRIPTION_ID:?Set AZURE_SUBSCRIPTION_ID to the target subscription}"
ENVIRONMENT="${1:?Usage: 09-network.sh <dev|staging|prod>}"
LOCATION="westeurope"
RG="rg-bookstore-${ENVIRONMENT}-weu"
VNET="vnet-bookstore-${ENVIRONMENT}-weu"
NSG_PE="nsg-bookstore-pe-${ENVIRONMENT}-weu"
APP="app-bookstore-${ENVIRONMENT}-weu"
SQL_SERVER="sql-bookstore-${ENVIRONMENT}-weu"
STORAGE="stbookstore${ENVIRONMENT}weu"
az account set --subscription "$AZURE_SUBSCRIPTION_ID"
# Adres planı tools/cloud/subnets.cs'ten; hiçbir subnet'te varsayılan internet çıkışı yok
az network vnet create --name "$VNET" --resource-group "$RG" --location "$LOCATION" \
--address-prefixes 10.20.0.0/16
az network vnet subnet create --vnet-name "$VNET" --resource-group "$RG" --name snet-app \
--address-prefixes 10.20.1.0/26 --delegations Microsoft.Web/serverFarms --default-outbound false
# Private endpoint subnet'i: SQL'e (1433) ve Blob'a (443) yalnız app subnet'i ulaşabilir
az network nsg create --name "$NSG_PE" --resource-group "$RG" --location "$LOCATION"
az network nsg rule create --nsg-name "$NSG_PE" --resource-group "$RG" --name allow-app-to-data \
--priority 100 --direction Inbound --access Allow --protocol Tcp \
--source-address-prefixes 10.20.1.0/26 --destination-port-ranges 1433 443
az network nsg rule create --nsg-name "$NSG_PE" --resource-group "$RG" --name deny-other-vnet \
--priority 4000 --direction Inbound --access Deny --protocol '*' \
--source-address-prefixes VirtualNetwork --destination-port-ranges '*'
az network vnet subnet create --vnet-name "$VNET" --resource-group "$RG" --name snet-pe \
--address-prefixes 10.20.3.0/27 --nsg "$NSG_PE" --default-outbound false \
--private-endpoint-network-policies NetworkSecurityGroupEnabled
# Private DNS: VNet içinde privatelink.* adlarına bu zone'lar cevap verir
for ZONE in privatelink.database.windows.net privatelink.blob.core.windows.net; do
az network private-dns zone create --resource-group "$RG" --name "$ZONE"
az network private-dns link vnet create --resource-group "$RG" --zone-name "$ZONE" \
--name "link-${VNET}" --virtual-network "$VNET" --registration-enabled false
done
SQL_ID=$(az sql server show --name "$SQL_SERVER" --resource-group "$RG" --query id --output tsv)
STORAGE_ID=$(az storage account show --name "$STORAGE" --resource-group "$RG" --query id --output tsv)
# Her kaynak ve alt kaynak için bir private endpoint; zone group A kaydını güncel tutar
az network private-endpoint create --name "pe-sql-bookstore-${ENVIRONMENT}-weu" --resource-group "$RG" \
--vnet-name "$VNET" --subnet snet-pe --private-connection-resource-id "$SQL_ID" \
--group-id sqlServer --connection-name sql
az network private-endpoint dns-zone-group create --endpoint-name "pe-sql-bookstore-${ENVIRONMENT}-weu" \
--resource-group "$RG" --name default --private-dns-zone privatelink.database.windows.net --zone-name sql
az network private-endpoint create --name "pe-blob-bookstore-${ENVIRONMENT}-weu" --resource-group "$RG" \
--vnet-name "$VNET" --subnet snet-pe --private-connection-resource-id "$STORAGE_ID" \
--group-id blob --connection-name blob
az network private-endpoint dns-zone-group create --endpoint-name "pe-blob-bookstore-${ENVIRONMENT}-weu" \
--resource-group "$RG" --name default --private-dns-zone privatelink.blob.core.windows.net --zone-name blob
# Bookstore.Api'nin giden trafiği VNet'e girer; böylece DNS sorguları private zone'ları görür
az webapp vnet-integration add --name "$APP" --resource-group "$RG" --vnet "$VNET" --subnet snet-app
az webapp config set --name "$APP" --resource-group "$RG" --vnet-route-all-enabled true
# Public kapıları en son kapat: daha önce kapatmak API'yi keser
az sql server update --name "$SQL_SERVER" --resource-group "$RG" --enable-public-network false
# Tarayıcılar kapakları SAS adresleriyle indiriyor (7. yazı), function app de kapakları okuyor. Blob'u ancak
# kapaklar Private Link origin'li Front Door Premium üzerinden sunulunca ve function VNet'e girince kapat.
if [[ "${CLOSE_STORAGE:-false}" == "true" ]]; then
az storage account update --name "$STORAGE" --resource-group "$RG" --public-network-access Disabled
fi
Sıralama önemli. Önce ağ, DNS ve private endpoint'ler kuruluyor, App Service VNet'e bağlanıyor ve ancak en sonda SQL'in public erişimi kapatılıyor. Ters sırada API, private yol hazır olmadan public yolunu kaybeder. snet-pe'deki NSG yalnız snet-app'ten 1433 ve 443 portlarına izin veriyor; NSG'nin private endpoint'lere uygulanması için subnet'te --private-endpoint-network-policies ayarı gerekiyor, çünkü Learn'e göre bu policy'ler varsayılan olarak kapalı.
İkinci tahmin sorusunun cevabı script'in son bloğunda. Storage'ın public erişimini kapatırsan 7. yazıdaki SAS (süresi ve yetkisi sınırlı erişim adresi) adresleri tarayıcıdan çalışmaz, çünkü tarayıcı internetten geliyor; 6. yazıdaki function da VNet'e bağlı değilse kapakları okuyamaz. Kapakları önce Front Door Premium'un Private Link origin'i üzerinden sunmak ve function'ı VNet'e almak gerekiyor. Bu yüzden storage'ı kapatan satır bir bayrağa bağlı ve varsayılan olarak çalışmıyor.
Giriş Noktası: Front Door ve Application Gateway
Uygulamanın internete açık yüzü için iki seçenek var. Application Gateway, region içinde çalışan bir layer 7 load balancer; WAF (Web Application Firewall; HTTP isteklerini bilinen saldırı kalıplarına karşı süzen katman) ile birlikte kullanılabilir. Front Door ise global çalışır: kullanıcıya en yakın noktada TLS'i (Transport Layer Security; HTTPS'in şifreleme katmanı) sonlandırır, cache'ler ve WAF uygular. Bookstore'un müşterileri dağınık ve statik içeriği bol olduğu için Front Door doğal seçim. Premium plan, origin'e Private Link ile bağlanabiliyor; böylece App Service'in de public erişimini kapatıp yalnız Front Door'dan gelen trafiği kabul edebilirsin. Front Door (classic) 31 Mart 2027'de emekliye ayrılıyor, yeni kurulumlar Standard ya da Premium ile yapılmalı. DNS, sertifika ve CDN (içeriği kullanıcıya yakın sunuculardan dağıtan ağ) ayrıntıları Domain, DNS ve CDN serisinde.
Ağa girince bir şey değişmiyor: 5. yazıdaki Proxy__KnownNetworks ayarı. Front Door ya da App Service'in front-end sunucuları isteği özel adreslerden iletmeye devam ediyor; forwarded header'lara yalnız bu ağlardan güvenmek hâlâ doğru.
Üretimde Dikkat
Maliyeti topla. Her private endpoint ayda yaklaşık 7,3 dolar; SQL, blob, ileride queue ve Key Vault derken dört-beş endpoint ayda 30-40 dolar eder. NAT gateway ayda yaklaşık 33 dolar artı trafik. Küçük bir dev ortamında bu, compute'tan pahalı olabilir; dev ve prod için farklı karar verebilirsin.
Akış log'larını aç. Bir bağlantının neden reddedildiğini anlamanın yolu, NSG'nin kararlarını görmek. Learn'e göre NSG flow log'ları 30 Eylül 2027'de emekliye ayrılıyor ve artık yeni oluşturulamıyor; yerine VNet flow log'ları kullanılıyor.
Ağ kurallarını da kod gibi gözden geçir. Bir NSG kuralına Any yazmak, bir firewall'a "geçici" bir IP eklemek kolay; geri almayı hatırlamak zor. Azure Policy ile public erişimi açık SQL sunucularını ve storage hesaplarını raporlatabilirsin.
Sık Düşülen Tuzaklar
Private DNS zone'u VNet'e link'lemeyi unutmak. Belirtisi, private endpoint varken trafiğin public IP'ye gitmesi; public erişim açıksa her şey çalışır gibi görünür ve sorun, public erişimi kapattığın gün ortaya çıkar.
Subnet'i küçük açmak. App Service planını ölçeklediğinde ya da Container Apps'e yeni replica'lar geldiğinde adres biter; delege edilmiş bir subnet'i dolu hâldeyken büyütmek zahmetli.
Public erişimi önce kapatmak. Private yol hazır olmadan public yolu kapatmak uygulamayı keser. Sıra: ağ, DNS, private endpoint, VNet integration, test, sonra kapatma.
Egress'i ve NAT'ı unutmak. VNet içi trafik ucuz, ama NAT gateway'den geçen her GB ve internete çıkan her GB faturada ayrı satır olarak görünür.
Küçük Bir Deneme
★☆☆ subnets.cs'e Flex Consumption function app'i için bir subnet ekle. Learn'deki gereksinimi (delegation ve en küçük boyut) bulup aracın kuralına yaz.
★★☆ 09-network.sh'e kargo firmasına sabit IP'den çıkmak için bir NAT gateway ekle: public IP'yi oluştur, NAT gateway'e bağla, snet-app'e ata. Hangi trafiğin bu IP'den çıkacağını --vnet-route-all-enabled ayarıyla ilişkilendirerek yaz.
★★★ Bookstore'un kapaklarını Front Door Premium arkasına al ve storage'ın public erişimini kapat. 7. yazıdaki SAS yaklaşımı bu durumda nasıl değişmeli? İki seçeneği karşılaştır: SAS'ı Front Door üzerinden iletmek ya da Front Door'un (Kasım 2026'da preview olan) managed identity ile origin kimlik doğrulamasını kullanmak. İkincisinin Learn'deki kısıtlarını da not et.
Bir sonraki yazıda bu kaynakların faturasına bakıyoruz: fiyatlandırma modelleri, budget alarmları, tag'le maliyet dağıtımı ve en sık para kaybettiren hatalar.