Nasazení minimální hub-spoke topologie v Azure - část 3
29.10.2026Pokračování předchozího článku. K hub-spoke topologii přidáme management group hierarchii, Azure politiky a nahradíme stávající Linux router za Azure Firewall.
Slovník
| Azure Landing Zone (ALZ) | Ověřená a doporučená architektura pro řízení, zabezpečení a škálování Azure prostředí s více subskripcemi. Skládá se z platform landing zóny, která tvoří centrální základ se sdílenými službami, a z workload landing zón, kam se nasazují aplikace v rámci definovaných pravidel. |
| Hub-spoke topologie | Doporučená síťová topologie v Azure, kde je centrální síť (hub) propojena s dalšími sítěmi (spokes). Alternativou je Virtual WAN. |
| Management Group (MG) | Skupina, která sdružuje subskripce. Politiky a oprávnění přiřazené na management skupinu se automaticky dědí na všechny subskripce pod ní, což usnadňuje centrální správu. |
| Azure Policy | Pravidla, která se přiřazují na management skupinu, subskripci nebo resource group. Politiky slouží k vynucení standardů nebo compliance. |
| Azure Firewall | Spravovaná služba, která filtruje síťový provoz podle definovaných pravidel. V hub-spoke topologii se obvykle umisťuje do hubu a centrálně kontroluje provoz mezi spoky i do internetu. |
| User Defined Route (UDR) | Směrovací pravidlo, které přepisuje výchozí směrování v Azure. Zapisuje se do route table, která se přiřazuje k subnetu. Pomocí UDR lze například směrovat veškerý provoz ze subnetu na firewall nebo router v hubu. |
| Privátní subnet | Subnet s vypnutým přístupem do internetu (default outbound access). Prostředky v něm se do internetu dostanou jen přes explicitně nastavenou cestu, například NAT Gateway, veřejnou IP adresu nebo UDR směrující provoz na firewall či router v hubu. |
Obsah
Úvod
V předchozím článku jsme vytvořili hub-spoke topologii s centrálním hubem a dvěma spokes (aplikacemi). Dále máme vytvořený Linux server, který funguje jako router, privátní DNS zónu pro překlad doménových jmen na IP adresy, Azure Bastion pro vzdálené přihlášení na virtuální servery a NSG pro filtrování síťového provozu na subnetech. Dnes přidáme management group hierarchii, která nám pomůže s centrální správou a využijeme ji k nastavení Azure politik pro spoke subskripce, které zařadíme do management skupiny Corp. Linux server v hubu nahradíme Azure Firewallem, přes který budeme routovat provoz do internetu, a zároveň přepneme spoke subnety do privátního režimu.
Příprava prostředí
V Azure portálu vytvoříme novou Management subskripci, kterou budeme potřebovat pro Log Analytics workspace, do kterého se budou ukládat logy z Azure Firewallu. Celkem musíme mít k dispozici tyto subskripce: Management, Connectivity , app1-dev , app2-dev. Dále musíme mít nainstalovaný Azure CLI a Bicep CLI. Veškeré příkazy v článku spouštíme z PowerShell terminálu.winget install --exact --id "Microsoft.AzureCLI"
az bicep upgrade
git clone "https://github.com/Ninjanaut/azure-hub-spoke-bicep-template-03.git"
config/
├── platform.json
└── platform.bicep
landing-zones/
├── main.bicep
├── app1-dev.bicepparam
└── app2-dev.bicepparam
platform/
├── connectivity/
│ ├── main.bicep
│ └── main.bicepparam
├── management/
│ ├── main.bicep
│ └── main.bicepparam
└── governance/
└── mgmt-groups/
└── corp/
├── main.bicep
├── main.bicepparam
└── policy-definitions/
└── Deny-Subnet-Without-Udr.alz_policy_definition.json
scripts/
├── setup-entra.ps1
├── setup-management-groups.ps1
├── deploy-governance.ps1
├── deploy.ps1
└── cleanup.ps1
tenantId
sshPublicKeyPath
testUserUpn
management.subscriptionId
connectivity.subscriptionId
landingZones.app1-dev.subscriptionId
landingZones.app2-dev.subscriptionId
- vmAdminLoginGroup.objectId není potřeba vyplňovat, nastaví se automaticky skriptem ./scripts/setup-entra.ps1.
-
Pokud bychom neměli vytvořený klíč, tak ho můžeme vytvořit následovně
ssh-keygen -t ed25519 -f "$HOME\.ssh\azure-hub-spoke-template-02" -C "azure-hub-spoke-template-02"
Deployment
Nejdříve připravíme uživatele a skupiny v Entra ID. Poté vytvoříme management group hierarchii a přiřadíme do ní subskripce. Dále nasadíme politiky (Azure Policy) a nakonec spustíme deployment do všech prostředí (management, hub, app1, app2). Skripty v sobě obsahují kontroly a je možné je spustit opakovaně, aniž by vznikaly duplicity.
# Přihlásíme se do Azure
az login --tenant "<tenant-id>"
# Vytvoříme testovacího uživatele a security groups, do kterých ho přidáme.
# ID vytvořených skupin se automaticky uloží do souboru config/platform.json.
./scripts/setup-entra.ps1
# Vytvoříme management group hierarchii a přiřadíme do ní subskripce.
./scripts/setup-management-groups.ps1
# Na Corp management group skupině nastavíme politiky (Azure Policy).
./scripts/deploy-governance.ps1
# Nasazení do management, hub, app1 a app2 subskripcí.
./scripts/deploy.ps1
Oproti první a druhé části se navíc vytvoří následující resources:
Změny
Management group hierarchie
Skript setup-management-groups.ps1 vytvořil hierarchii management skupin podle referenční architektury a přiřadil do ní subskripce. Corp skupina obsahuje aplikace, které nejsou přímo vystavené do internetu ani do něj nemají přímý přístup. Pokud by aplikace měla komunikovat s internetem přímo, a ne třeba přes platformní firewall nebo aplikační gateway, patřila by podle ALZ do Online skupiny.
Azure Policy
Skript deploy-governance.ps1 nastavil na Corp management skupině tři politiky. První dvě jsou built-in a třetí má definici v souboru Deny-Subnet-Without-Udr.alz_policy_definition.json. Všechny politiky mají efekt Deny a režim vynucení Policy enforcement: Default (enforce). Po přiřazení tedy začnou platit a ihned blokovat případné nepovolené operace.
- Deny the creation of public IP (built-in)
- Deny network interfaces having a public IP (built-in)
- Subnets should have a User Defined Route (custom)
Azure Firewall
Původní Linux server, který fungoval jako router, jsme nahradili službou Azure Firewall. Skript deploy.ps1 vytvořil Azure Firewall v tieru Basic. Ten kromě subnetu AzureFirewallSubnet vyžaduje také AzureFirewallManagementSubnet a druhou veřejnou IP adresu pro management provoz. Tiery Standard a Premium dedikovaný management subnet ani druhou veřejnou IP adresu nepotřebují. Abychom vyzkoušeli, zda nám vše funguje, tak se přihlásíme pod testovacím uživatelem do Azure portálu a pomocí Bastion služby se přihlásíme k virtuálnímu serveru aplikace 1 (10.0.4.4) a pingneme DNS název virtuálního serveru aplikace 2 (10.0.8.4).
curl -s -m 10 "https://api.ipify.org"
$workspaceId = az monitor log-analytics workspace show `
-g "rg-management-shared" `
-n "log-management-shared-swedencentral-001" `
--subscription "<management-subscription-id>" `
--query customerId `
-o tsv
az monitor log-analytics query `
-w $workspaceId `
--analytics-query "AZFWNetworkRule | where TimeGenerated > ago(30m) | project TimeGenerated, SourceIp, DestinationIp, Protocol, Action, Rule" `
-o table
# Result
Action DestinationIp Protocol Rule SourceIp TableName TimeGenerated
-------- --------------- ----------- -------------------- ---------- ------------- ---------------------------
Allow 10.0.8.4 ICMP Type=8 allow-spoke-to-spoke 10.0.4.4 PrimaryResult 2026-10-29T14:43:12.538532Z
Allow 172.67.74.152 TCP allow-spoke-internet 10.0.4.4 PrimaryResult 2026-10-29T14:44:33.089767Z
Privátní subnet a UDR
Všechny spoke subnety jsou nově nastavené jako privátní, pomocí vlastnosti defaultOutboundAccess: false v souboru landing-zones/main.bicep.
Dealokace a smazání
Vzhledem k provozním nákladům můžeme Firewall dealokovat.$fw = Get-AzFirewall -ResourceGroupName "rg-hub-shared" -Name "afw-hub-shared-swedencentral-001"
$fw.Deallocate()
Set-AzFirewall -AzureFirewall $fw
# Kontrola, dealokovaný fw by měl vrátit "0"
# (Get-AzFirewall -ResourceGroupName rg-hub-shared -Name afw-hub-shared-swedencentral-001).IpConfigurations.Count
az network bastion delete -g "rg-hub-shared" -n "bas-hub-shared-swedencentral-001" --subscription "<hub-subscription-id>"
az network public-ip delete -g "rg-hub-shared" -n "pip-bas-hub-shared-swedencentral-001" --subscription "<hub-subscription-id>"
az vm deallocate -g "rg-spoke-app1-dev" -n "vm-conntest-app1-dev-swedencentral-001" --subscription "<app1-subscription-id>"
az vm deallocate -g "rg-spoke-app2-dev" -n "vm-conntest-app2-dev-swedencentral-001" --subscription "<app2-subscription-id>"
./scripts/cleanup.ps1
Závěr
Vytvořili jsme management group hierarchii, abychom mohli prostředí centrálně spravovat. Na skupině Corp jsme nastavili Azure politiky. Spoke subnety jsme přepnuli do privátního režimu, aktualizovali směrování a centrální Linux server, který fungoval jako router, jsme nahradili Azure Firewallem. Příště se podíváme na VPN Gateway 🙌.