Deployment-Layer¶
Der hub ist in separate Terraform Root Modules aufgeteilt, die Layer genannt werden und in infra/deploy/<layer>/ liegen.
Jeder Layer hat seine eigene State-Datei, seinen eigenen Plan und Apply und läuft in einer festen Reihenfolge.
Warum Layer¶
Die Bewertung hinter dieser Aufteilung: Architekturnotizen.
- Blast Radius. Eine Änderung an einer Firewallregel plant nur den
firewall-State. Sie kann nicht versehentlich management groups oder Gateways anfassen. - Abhängigkeitsreihenfolge. Spätere Layer lesen Ressourcen, die frühere Layer erstellt haben, etwa den virtual hub, die firewall policy oder die management groups.
- Geschwindigkeit und Locking. Kleinere States werden schneller geplant, und Läufe auf verschiedenen Layern blockieren sich nicht gegenseitig über das State-Lock.
- Unterschiedliche Änderungsfrequenz. Firewallregeln und Policies ändern sich wöchentlich; Gateways und das Virtual WAN ändern sich selten.
Die Layer¶
| Level | Layer | Regionen | Wichtigste Ressourcen | Subscription |
|---|---|---|---|---|
| 1 | foundation |
primär | Management groups und Subscription-Platzierung; benutzerdefinierte Policy-Definitionen und initiatives; Registrierung von Resource Providern; action groups; activity log alerts; DDoS plan (optional); Azure Virtual Network Manager und IPAM-Pools (optional); Private-DNS-Policy-Definitionen | management, connectivity, identity |
| 1 | connectivity |
primär | Virtual WAN, virtual hub, Azure Firewall und firewall policy, VPN-/ExpressRoute-Gateways, Point-to-Site-VPN, private DNS zones und resolver, Bastion, Application Gateway und WAF policies, alert processing rule, hub-24/7-Routing (optional) | connectivity |
| 2 | foundation |
andere Regionen | Regionale Teile von foundation (zum Beispiel die regionalen action groups) | wie oben |
| 2 | connectivity |
andere Regionen | Regionaler hub jeder zusätzlichen Region | connectivity |
| 3 | firewall |
alle | IP groups und firewall policy rule collection groups (aus JSON); Network-Manager-Security-Admin-Rules (optional) | connectivity |
| 3 | identity |
alle | Identity virtual network und seine virtual-hub-Verbindung, alert processing rule | identity (+ connectivity) |
| 3 | management |
alle | Management virtual network und hub-Verbindung; Key Vault, Automation Account, Log Analytics, Storage, Sentinel (optional); alert processing rule | management (+ connectivity) |
| 4 | postdeployment |
primär | Eingebaute Compliance-initiatives; Policy-Zuweisungen und Policy-Ausnahmen (aus JSON); Defender-for-Cloud-Einstellungen; AMBA-Alert-initiatives | management |
Innerhalb von Level 1 und Level 2 wartet connectivity auf das foundation-Apply (im Plan-Modus werden beide parallel geplant). Die Layer von Level 3 laufen parallel; Level 4 wartet auf alle drei.
Wo die Reihenfolge definiert ist:
- Pipelines: als Job-Abhängigkeiten in
.azure-devops/pipelines/templates/stage-mcp-hub.yamlund alsneeds:in.github/workflows/stage-mcp-hub-deploy.yaml. Die Region-Matrix pro Level kommt ausSet-XebiaRegionMatrix.ps1. - Lokales Tooling:
src/Xebia.Mcp/Functions/Private/Config/Get-XebiaOrderedDeployments.ps1, verwendet vonDeploy-,Remove-undUnlock-XebiaLocal.
Primäre und andere Regionen stammen aus primary_region und active_regions in <env-folder>/global.auto.tfvars.
Mehrere foundation- und postdeployment-Ressourcen existieren nur einmal pro Plattformumgebung, obwohl der Layer in
mehreren Regionen läuft. Sie sind mit count = var.scaffold_location_short_name == var.primary_region ? 1 : 0 abgesichert. Beispiele:
management groups, Policy-Definitionen, Policy-Zuweisungen und Alert-initiatives.
Layer, die nicht Teil der hub Pipeline sind¶
infra/deploy/ghrunners und infra/deploy/policy_exemptions gibt es im Code, aber weder die hub-Pipeline-Templates
noch Get-XebiaOrderedDeployments beziehen sie ein. Nur Legacy-Pipelines verwenden sie.
- Policy-Ausnahmen werden stattdessen vom
postdeployment-Layer deployt. - Eine Datei
ghrunners.auto.tfvarsin einem Konfigurations-Repository hat keine Wirkung auf die aktuelle hub Pipeline. (Ältere Update- Runbooks führenghrunnersnoch als auszuführenden Layer auf; das gilt nur für die Legacy-main.yaml-Pipelines.)
Destroy-Reihenfolge¶
hub-destroy führt dieselben Layer in umgekehrter Reihenfolge aus (postdeployment → … → foundation): siehe die Destroy-Jobs in
stage-mcp-hub.yaml und Remove-XebiaLocal, das Get-XebiaOrderedDeployments -Reverse aufruft.
Parallelität¶
| Layer | terraform -parallelism |
|---|---|
firewall |
1 (Azure Firewall Policy akzeptiert nur ein Update einer rule collection group gleichzeitig, ADR-0009) |
postdeployment |
10 |
| alle anderen | 100 |
Gesetzt in Invoke-XebiaHubPlanAction.ps1 und Invoke-XebiaHubApplyAction.ps1. Eine große Firewall-Änderung dauert daher
spürbar länger.
Terraform State¶
| Was | Backend (mcp.json) |
State-Key |
|---|---|---|
| Hub-Layer | Azure.TerraformState.Hub |
<env>-<region>-<layer>.tfstate, z. B. prod-gwc-firewall.tfstate |
| Spoke subscription | Azure.TerraformState.Spoke |
<workloadShortName>_<environment>_Subscription.tfstate |
| Spoke canvas | Azure.TerraformState.Spoke |
spoke_<workloadShortName>_<environment>.tfstate |
<env> ist der Name des Ordners, der mcp.json enthält. Spoke-Keys sind kleingeschrieben. Das Backend nutzt Entra-ID-
Authentifizierung (use_azuread_auth=true); die Deployment-Identität braucht daher eine Data-Plane-Rolle auf dem State-Storage-Account.
Welche Änderung welchen Layer betrifft¶
| Änderung | Layer, die im Plan Änderungen zeigen |
|---|---|
| Firewallregel oder IP group | firewall |
| Application Gateway oder WAF policy | connectivity |
| hub-Feature-Schalter (VPN, Bastion, App Gateway, DNS zones, …) | connectivity (die meisten Schalter), siehe Feature Flags |
| Management group oder Subscription-Platzierung | foundation (primäre Region) |
| Benutzerdefinierte Policy-Definition oder initiative | foundation (primäre Region) |
| Policy-Zuweisung oder Policy-Ausnahme, Alert-initiatives, Defender-Einstellungen | postdeployment |
| Log Analytics, Key Vault, Automation | management |
| Spoke-JSON | spoke Pipeline (kein hub-Layer) |
Die hub Pipeline plant immer alle Layer. Ein Layer ohne Änderungen ergibt einen leeren Plan und ein Apply, das nichts tut. Um einen einzelnen Layer auszuführen, nutze das lokale Tooling, siehe Einen einzelnen Layer lokal ausführen.