High-angle view of a yellow ethernet cable on a bright blue background.
Azure

Manisa’da 380 çalışanlı bir tarımsal makine üreticisi, başlangıçta “default VNet” ile başladığı Azure ortamını 6 ayda hub-spoke + ExpressRoute + private endpoint mimarisine taşıdı. Bu yazı tasarımın sahadaki teknik notlarını paylaşıyor.

Hub-Spoke Topology

Hub VNet (10.0.0.0/16) - Northeurope
├── GatewaySubnet (10.0.0.0/27) → ExpressRoute + VPN Gateway
├── AzureFirewallSubnet (10.0.1.0/26) → Azure Firewall Premium
├── AzureBastionSubnet (10.0.2.0/27) → Bastion Standard
└── PrivateDNSResolverSubnet (10.0.3.0/28) → DNS Resolver

Spoke 1: Production (10.10.0.0/16)
├── App tier (10.10.1.0/24)
├── API tier (10.10.2.0/24)
├── Data tier (10.10.3.0/24, private endpoints)
└── AKS subnet (10.10.10.0/22)

Spoke 2: Test/Staging (10.20.0.0/16)
└── (Production benzeri yapı)

Spoke 3: Management (10.30.0.0/16)
├── Monitoring tools (10.30.1.0/24)
└── Build agents (10.30.2.0/24)

Spoke 4: DMZ (10.40.0.0/24)
└── Reverse proxy, WAF backend

Spoke’lar Hub’a peer’lı, birbirine doğrudan değil. Aralarındaki trafik Hub firewall’dan geçer.

VNet Peering ve Route Tables

# Hub → Spoke 1 peering (transit gateway, allow forwarded)
az network vnet peering create -g rg-network 
  --name hub-to-spoke1 
  --vnet-name vnet-hub --remote-vnet vnet-spoke1-prod 
  --allow-vnet-access --allow-forwarded-traffic 
  --allow-gateway-transit

az network vnet peering create -g rg-network 
  --name spoke1-to-hub 
  --vnet-name vnet-spoke1-prod --remote-vnet vnet-hub 
  --allow-vnet-access --allow-forwarded-traffic 
  --use-remote-gateways

Spoke 1’deki route table:

az network route-table create -g rg-network -n rt-spoke1-default
az network route-table route create -g rg-network 
  --route-table-name rt-spoke1-default 
  --name default-via-firewall 
  --address-prefix 0.0.0.0/0 
  --next-hop-type VirtualAppliance 
  --next-hop-ip-address 10.0.1.4   # Azure Firewall private IP

az network route-table route create -g rg-network 
  --route-table-name rt-spoke1-default 
  --name onprem-via-er 
  --address-prefix 192.168.0.0/16 
  --next-hop-type VirtualNetworkGateway

ExpressRoute

On-prem (üretim sahası, Manisa) → Azure Northeurope. ExpressRoute 200 Mbps, Türk Telekom + Equinix MD2 peering location.

az network express-route create -g rg-network -n er-manisa 
  --location northeurope 
  --provider "Equinix" 
  --peering-location "Amsterdam" 
  --bandwidth 200 
  --sku-tier Standard --sku-family MeteredData

# ExpressRoute Gateway (Hub'da)
az network vnet-gateway create -g rg-network -n vgw-hub-er 
  --vnet vnet-hub 
  --gateway-type ExpressRoute --sku Standard 
  --public-ip-addresses pip-vgw

# Connection
az network vpn-connection create -g rg-network -n conn-er 
  --vnet-gateway1 vgw-hub-er 
  --express-route-circuit2 er-manisa

S2S VPN (Yedek Hat)

ExpressRoute outage senaryosu için S2S VPN backup:

az network vnet-gateway create -g rg-network -n vgw-hub-vpn 
  --vnet vnet-hub --gateway-type Vpn --sku VpnGw2 
  --vpn-type RouteBased 
  --public-ip-addresses pip-vpn

az network local-gateway create -g rg-network -n lgw-manisa 
  --gateway-ip-address 1.2.3.4 
  --local-address-prefixes 192.168.0.0/16

az network vpn-connection create -g rg-network -n conn-vpn-manisa 
  --vnet-gateway1 vgw-hub-vpn --local-gateway2 lgw-manisa 
  --shared-key 'StrongPSK_xx' --routing-weight 50

Routing weight: ExpressRoute primary (100), VPN failover (50). ER düşerse otomatik VPN devreye giriyor.

Azure Firewall Premium

az network firewall create -g rg-network -n fw-hub 
  --tier Premium --sku AZFW_VNet 
  --vnet-name vnet-hub --location northeurope

# Rule: production → on-prem SAP'a izin
az network firewall network-rule create -g rg-network 
  --collection-name "spoke1-to-onprem" --firewall-name fw-hub 
  --name "allow-sap" --action Allow --priority 100 
  --source-addresses 10.10.0.0/16 
  --destination-addresses 192.168.10.50 
  --destination-ports 3200 3300 3600 
  --protocols TCP

# IDPS aktif
az network firewall update -g rg-network -n fw-hub 
  --idps-mode Alert

Private Endpoint

Storage, SQL, Cosmos, Key Vault, ACR — public endpoint kapalı, sadece VNet’ten erişim:

az storage account update -g rg-prod -n stgproddata 
  --public-network-access Disabled

az network private-endpoint create -g rg-network -n pe-storage 
  --vnet-name vnet-spoke1-prod --subnet snet-data 
  --private-connection-resource-id /subscriptions/.../storageAccounts/stgproddata 
  --group-id blob 
  --connection-name pe-storage-conn

# Private DNS zone link
az network private-dns zone create -g rg-network --name privatelink.blob.core.windows.net
az network private-dns link vnet create -g rg-network 
  --zone-name privatelink.blob.core.windows.net 
  --name link-hub --virtual-network vnet-hub --registration-enabled false

NSG: Defense in Depth

az network nsg create -g rg-network -n nsg-app-tier
az network nsg rule create -g rg-network --nsg-name nsg-app-tier 
  --name "Allow-API-from-AppGw" 
  --priority 100 --direction Inbound --access Allow 
  --protocol Tcp --source-address-prefixes 10.10.5.0/24 
  --source-port-ranges '*' 
  --destination-address-prefixes '*' 
  --destination-port-ranges 443

az network nsg rule create -g rg-network --nsg-name nsg-app-tier 
  --name "Deny-All-Inbound" 
  --priority 4096 --direction Inbound --access Deny 
  --protocol '*' --source-address-prefixes '*' 
  --source-port-ranges '*' --destination-address-prefixes '*' 
  --destination-port-ranges '*'

NSG Flow Logs + Traffic Analytics

NSG flow log’lar Storage’a gönderiliyor, Log Analytics’te analiz:

AzureNetworkAnalytics_CL
| where SubType_s == "FlowLog"
| where TimeGenerated > ago(24h)
| where FlowStatus_s == "D"  // Denied
| summarize DenyCount = count() by SrcIP_s, DestIP_s, DestPort_d
| order by DenyCount desc
| take 20

Sonuçlar

Metrik Önce Sonra
Internet’ten erişilebilir resource 62 4 (Front Door + Bastion)
VNet sayısı 1 (default) 5 (hub + 4 spoke)
Defender for Cloud network secure score 42 89
On-prem latency ~~80ms (internet) ~~12ms (ExpressRoute)

Sahada Düşülen Üç Tuzak

  1. Default VNet ile başlamak: Sonradan hub-spoke’a geçiş ağrılı (re-IP). Day 1 tasarım.
  2. Private DNS zone’u atlamak: Private endpoint var ama DNS resolution Public IP’ye dönüyor — bağlantı çalışmıyor. Private DNS zone + VNet link şart.
  3. S2S VPN’i yedek tutmamak: ExpressRoute outage olunca her şey kapalı. VPN backup low-cost insurance.

CloudSpark olarak Azure ağ mimarisi tasarımı, hub-spoke deployment, ExpressRoute + VPN konfigürasyonu, Private Endpoint stratejisi ve NSG governance için danışmanlık veriyoruz.

🇹🇷 Türkçe🇬🇧 English🇩🇪 Deutsch🇫🇷 Français🇸🇦 العربية🇷🇺 Русский🇪🇸 Español