Zum Inhalt

Bekannte Probleme

Beim Schreiben dieses Leitfadens gefundene Einschränkungen, mit Workarounds. Wie du mit einem Incident umgehst, steht unter Incident-Management.

Verifizierungsstatus (15. Oktober 2026)

Die Punkte unter Behoben (Merge ausstehend) wurden auf einem Arbeits-Branch behoben, während der Leitfaden geschrieben wurde, sie sind aber noch nicht in main oder release/v4.12 von xms-cloud-platform-code. Geprüft auf main (0426660) und release/v4.12 (534ff80):

  • dev/dev.ps1 hat noch das alte ValidateSet (Deploy, Unlock, DeploySpoke, …), während seine Handler HubDeploy, HubUnlock, SpokeDeploy, … heißen. -Action HubDeploy wird von der Parametervalidierung abgelehnt, und -Action Deploy findet keinen Handler. Die spoke-Handler sind fest auf patrick/canvas_nonprod_dev_str.json verdrahtet. Bis der Fix gemergt ist, ruf die Funktionen direkt auf (siehe Einen einzelnen Layer lokal ausführen).
  • .azure-devops/pipelines/spoke-destroy.yaml zerstört noch in der Reihenfolge dev → prd.
  • Das spoke-Schema environment ist noch ein enum (kein acc<n>-Muster).

Behandle jede Zeile unter Behoben (Merge ausstehend) als offen, bis du sie in der von dir gepinnten Version geprüft hast.

Behoben (Merge ausstehend)

Problem Fix
Das spoke-Apply verwendete den Literal-String spoke_${stateKeyId}.tfstate als State-Key, weil einfache Anführungszeichen die Interpolation in PowerShell verhindern. Invoke-XebiaMcpSpokeApply.ps1 verwendet jetzt doppelte Anführungszeichen. Ein Unit-Test wurde ergänzt.
Das spoke-Schema lehnte nummerierte Abnahme-Umgebungen (acc1, acc2, …) ab, obwohl die Pipeline sie unter acc gruppiert. spokeschema.json: environment akzeptiert jetzt dev, tst, test, acc, acc<n>, prd, prod, shrd und shared (Regex-Muster).
dev/dev.ps1 listete Aktionsnamen (Deploy, Unlock, DeploySpoke, …) auf, für die es keinen Handler gab, sodass die hub-/spoke-Aktionen nicht laufen konnten. Die spoke-Datei war fest verdrahtet. Das ValidateSet passt jetzt zu den Handlern (HubDeploy, SpokeDeploy, …), und ein Parameter -SpokeFilePath wurde ergänzt.
Azure-DevOps-hub-Stage: Die Bedingung des firewall-Jobs las job_deploy_1_connectivity_apply, was keine seiner Abhängigkeiten war. Die identity- und management-Jobs hatten dasselbe Problem in ihrem Single-Region-Fallback. stage-mcp-hub.yaml: Die drei Level-3-Jobs hängen jetzt von beiden connectivity-Apply-Jobs ab und verwenden dieselbe Bedingung, passend zum GitHub-Workflow.
Azure DevOps spoke-destroy.yaml zerstörte in der Reihenfolge dev → prd, obwohl der Header (und der GitHub-Workflow) prd → dev angibt. Die Reihenfolge ist jetzt prd → acc → tst → dev. Konfigurations-Repositories haben eine eigene Kopie dieser Entry-Datei, prüfe also deine.
Get-XebiaOrderedDeployments dokumentierte 3 Level und lehnte -Level 4 (postdeployment) ab. Hilfetext und ValidateSet aktualisiert.
hub-Genehmigungen: Der Analyse-Schritt behielt nur die Plan-Zusammenfassung der letzten Region, sodass Änderungen in anderen Regionen ohne Genehmigung durchgehen konnten. Invoke-XebiaHubAnalyseAction.ps1 aggregiert jetzt alle Plan-Dateien. Ein Unit-Test wurde ergänzt.
Der Azure-DevOps-hub-Analyse-Job lud <layer>_$(region)_<level>_json herunter, aber dieser Job ist nicht als Matrix definiert, sodass $(region) undefiniert war. job-mcp-hub.yaml lädt jetzt <layer>_*_<level>_json/** herunter und analysiert jede Region, passend zu GitHub.

Offen: Pipelines

Problem Auswirkung Workaround
Entry Pipelines tragen mode und whatIf fest ein. Im Referenz-Konfigurations-Repository verwenden spoke.yaml / spoke-destroy.yaml whatIf: true und hub.yaml verwendet mode: Apply, whatIf: false. spokes werden nur geplant; der hub wendet ohne Genehmigung an. Bearbeite die Entry-Dateien oder stelle die Parameter bereit (so geht's).
Der spoke-subscription-Layer wird während Plan angewendet, auch mit whatIf: true. Ein reiner Plan-Lauf kann den subscription-Layer trotzdem ändern. Derzeit erstellt dieser Layer nur einen Subscription-Alias, wenn azureSubscriptionId leer ist. Setze immer azureSubscriptionId.
Das Anlegen von Subscriptions braucht CSP-Abrechnungswerte (xmscsp_*), die die Pipeline als leere Strings übergibt. Die spoke Pipeline kann keine Subscriptions anlegen. Lege die Subscriptions vorher an (Neuer spoke).
Spoke destroy kündigt die Subscription nie und setzt weder deren Tags noch Namen zurück. Die Subscription läuft weiter. Außerbetriebnahme von Hand (spoke löschen).
Ein spoke, dessen environment nicht in der environments-Liste der Pipeline steht, lässt den Config-Test fehlschlagen, wenn der Glob ihn trifft (zum Beispiel shared mit den Standardwerten dev/tst/acc/prd). Ein breiter spokeGlob schlägt fehl. Verwende einen engen spokeGlob oder füge shared zu environments hinzu.
Die Layer ghrunners und policy_exemptions sind nicht Teil der aktuellen hub-Orchestrierung. Ihre tfvars haben keine Wirkung. Policy-Ausnahmen laufen über postdeployment (Policy-Zuweisungen).
ADR-0009 sagt, der firewall-Plan bleibe nebenläufig, aber Invoke-XebiaHubPlanAction.ps1 plant die firewall ebenfalls mit -parallelism=1. Langsamere firewall-Pläne. Keiner nötig.

Offen: spokes

Problem Auswirkung Workaround
Das azurerm_management_group_subscription_association des spoke hat einen count, der von einer externen Prüfung abhängt: "Ist die Subscription bereits in der Gruppe?" (spoke-canvas/modules/subscription_managementgroup/main.tf). Nach dem ersten Apply liefert die Prüfung true, sodass der nächste Plan die Association zerstören will. Der Lauf danach erstellt sie neu. Routinemäßige spoke-Wiederholungsläufe können die Subscription aus ihrer management group heraus und wieder zurück verschieben. Lies jeden spoke-Plan. Wende kein Destroy dieser Ressource an. Ein Code-Fix ist nötig: die Association einmal festlegen oder importieren, statt einen datengesteuerten count zu verwenden.
Die spoke-Genehmigung (Approve*-Modi) wird pro spoke-Umgebungs-Stage über jede im Lauf heruntergeladene Plan-Zusammenfassung entschieden, einschließlich der Pläne des subscription-Layers und früherer Umgebungen. Genehmigungsabfragen sind breiter als ein einzelner spoke. Führe einen spoke pro Lauf aus (spokeGlob = eine Datei).
hub-Config-Tests (firewall, App Gateway, WAF, DNS-Baseline) laufen auch im spoke-Prepare-Schritt. Ein kaputtes hub-JSON blockiert spoke-Deployments. Halte das hub-JSON auf dem Branch, von dem du deployst, gültig.
Keine Pipeline legt den spoke-State-Blob-Container an. Der erste spoke-Lauf schlägt am Backend fehl. Lege den Container von Hand an (Bootstrap).
Ein mit Purge Protection zerstörter Key Vault wird beim erneuten Anlegen wiederhergestellt (recover_soft_deleted_key_vaults = true). Alte Secrets kommen zurück. Beachte das, wenn du einen gelöschten spoke neu anlegst.

Offen: Entry-Dateien des Referenz-Konfigurations-Repositorys

Diese wurden im Referenz-Konfigurations-Repository gefunden und können auch bei deinem zutreffen:

Problem Auswirkung Workaround
pipelines/hub-destroy.yaml und pipelines/spoke-destroy.yaml verwenden template: ./templates/stage-mcp-*.yaml@mcp-code und übergeben agentPoolMdp nicht. Die anderen Entries verwenden .azure-devops/pipelines/templates/…@mcp-code und übergeben es. Die destroy Pipelines lassen sich wahrscheinlich nicht kompilieren. Verwende denselben Template-Pfad und dieselben Parameter wie hub.yaml / spoke.yaml.
spoke.yaml zielt auf environments/prod/mcp.json; spoke-destroy.yaml (ADO und GitHub) zielt auf environments/canary/mcp.json. Ein mit spoke deployter spoke kann nicht mit spoke-destroy zerstört werden. Richte beide auf dieselbe mcp.json oder füge einen Umgebungsparameter hinzu.
spoke-destroy.yaml läuft dev → prd. Die Destroy-Reihenfolge ist nicht die Umkehrung der Deploy-Reihenfolge. Verwende prd → acc → tst → dev, wie es die Entry-Datei des Code-Repositorys jetzt tut.
tfvars-Pfade sind ab dem Repository-Root geschrieben (zum Beispiel ip_group_json_file_relative_path = "environments/prod/gwc/ip_groups/"), aber Terraform hängt sie an config_path an, das bereits <repo>/environments/prod ist (wie Pfade aufgelöst werden). Im Code verifiziert: config_path ist der Ordner, der mcp.json enthält (Resolve-XebiaMcpConfiguration übergibt Split-Path -Parent des mcp.json-Pfads). environments/prod/gwc/ip_groups/ wird daher zu <repo>/environments/prod/environments/prod/gwc/ip_groups/ aufgelöst, den es nicht gibt, sodass die firewall-, Policy- und App-Gateway-Ordner keine Dateien finden. Mache die Pfade relativ zum Umgebungsordner, zum Beispiel gwc/ip_groups/ und policies/definitions, wie in config/Demo/canary des Code-Repositorys. Plane zuerst und bestätige, dass die erwarteten Ressourcen keine Änderungen zeigen.
postdeployment.auto.tfvars setzt security_contacts = {…}. Der aktuelle Code deklariert security_contact_email (String, Standard CustomerSupport@Xebia.com). Die Einstellung wird nur mit einer Warnung ignoriert, und der Standardkontakt wird verwendet. Setze security_contact_email.

Offen: Konfiguration und Validierung

Problem Auswirkung Workaround
Ein falscher Ordnerpfad in tfvars lässt fileset() ohne Fehler nichts zurückgeben. Der Plan löscht alle Ressourcen aus diesem Ordner. Lies die Plan-Zusammenfassung; siehe relative Pfade.
Keine Prüfungen auf IP-Überlappung oder -Enthaltensein bei spoke-Adressbereichen. Überlappende spokes werden ohne Warnung deployt. Pflege einen IP-Plan und prüfe ihn im pull request.
Die Associations von management_group_structure.*.subscription_ids werden über die Listenposition indiziert, mit ignore_changes. Das Entfernen oder Umsortieren von Einträgen verschiebt die falsche Subscription. Nur anhängen (Details).
Spoke-Entra-ID-Gruppen ignorieren spätere Änderungen an owners / members. Das Bearbeiten von ad_*Members nach der Erstellung hat keine Wirkung. Siehe spoke ändern.
Das spoke-Schema lehnt Keys ab, die das Terraform liest: extensions.github, extensions.integrations, extensions.apim.workspace, extensions.eventhub.eventhubs, die Service-Bus-Gruppenfelder und azdo: null. Diese Features können den Config-Test nicht bestehen. Lass azdo weg, statt es auf null zu setzen. Die Extension-Features brauchen ein Schema-Update im Code-Repository. Was jede Extension tut: Spoke-Erweiterungen.
App-Gateway-Config-Tests prüfen nur Dateien mit dem Namen application_gateway_hub.json. Andere Gateway-Dateien werden nicht validiert. Verwende diesen Dateinamen.
Es gibt zwei auseinandergelaufene Kopien der firewall-, App-Gateway- und WAF-Schemas: scripts/pr-validation/schemas/ und src/Xebia.Mcp/Files/json/. Die Pipelines verwenden die src-Kopie. Die Validatoren scripts/pr-validation/*.ps1 erwarten ein environments/{CANARY,PROD}-Layout und werden von keiner Pipeline aufgerufen. Validator-Ergebnisse weichen ab. Vertraue den Config-Tests der Pipeline (src-Kopie).
Der firewall-Config-Test für "sich gegenseitig ausschließende Ziele bei Application Rules" prüft Keys, die in Application Rules nicht existieren (fqdn_targets). Diese Prüfung schlägt nie fehl. Prüfe Application Rules von Hand: Verwende destination_fqdns oder destination_fqdn_tags.
Beispieldateien für Policy-Ausnahmen (*.jason) verwenden policy_definition_reference_ids. Das Modul liest policy_definition_ids. Eine Beispieldatei in .json umzubenennen funktioniert nicht wie erwartet. Verwende policy_definition_ids (Policy-Ausnahmen).
JSON-Zuweisungen an management groups müssen auf ein Policy-Set verweisen. Eine einzelne Definition schlägt zur Plan-Zeit fehl. Verpacke sie in eine initiative.
Der Azure-Anzeigename einer benutzerdefinierten initiative ist ihr name (display_name = each.value.name). properties.displayName wird ignoriert. Wähle gut lesbare initiative-Namen.
Eine nicht deklarierte Variable in einer tfvars-Datei ist nur eine Terraform-Warnung, sodass Tippfehler und umbenannte Variablen stillschweigend ignoriert werden. Die Einstellung hat keine Wirkung. Prüfe Variablennamen gegen infra/deploy/<layer>/variables*.tf.

Offen: Application Gateway und WAF

Problem Auswirkung Workaround
policy_settings von WAF policies steht in ignore_changes. Änderungen an Modus oder Limits nach der Erstellung werden nicht deployt. Ändere sie im Portal und halte es fest, oder lege eine neue Policy an.
create_application_gateway wird im Template auf true überschrieben. Nur use_application_gateway_module schaltet das Gateway. Verwende use_application_gateway_module.
Das WAF-Template legt eine eigene resource group an (rg-<company>-agw-…) und ignoriert die übergebene Gateway-resource-group (rg-<company>-appgw-…). WAF policies und das Gateway liegen in unterschiedlichen resource groups. Bilde firewall_policy_id aus der -agw--resource-group.
Im Gateway-JSON wird identity_ids ignoriert (die Template-Identität wird immer verwendet), und kv_name, pip_name, uai_name und fips_enabled werden nicht gelesen. Das Bearbeiten hat keine Wirkung. –
Zertifikatspasswörter werden mit azapi_resource .properties.value gelesen. Mit azapi 2.x kann dieser Pfad zu null aufgelöst werden. Nicht verifiziert. Passwortgeschützte PFX-Secrets können fehlschlagen. Speichere Zertifikate ohne separates Passwort-Secret (Key-Vault-Zertifikatsimport).

Betriebliche Fallstricke

Sie stammen aus Incidents und Post-Mortems laufender Plattformen. Sie beschreiben, wie sich die Plattform im Betrieb verhält, nicht Defekte in einer einzelnen Datei. Prüfe sie gegen die Version, die du fixiert hast.

Fallstrick Auswirkung Was zu tun ist
Eine große firewall-Änderung (viele Rule Collections gleichzeitig hinzugefügt und entfernt) läuft in das Update-Limit für Regelsätze: Azure akzeptiert keine gleichzeitigen Updates mehrerer Regelsätze, daher staut sich der Apply und endet in einem Time-out, und einige Rule Collections existieren in Azure, aber nicht im state. Der nächste Lauf schlägt mit „already exists“ fehl. Der Verkehr kann unterbrochen werden, solange Regeln fehlen. Teile die Änderung in mehrere kleinere pull requests. Behandle einen Time-out auf canary als Grund anzuhalten. Füge neue Regeln hinzu, bevor du alte entfernst. Behebe state-Unterschiede mit terraform import, nicht durch Zerstören von Produktionsregeln (Post-Mortems).
Der firewall-Layer wird mit -parallelism=1 angewendet, daher dauert eine große Änderung lange (Firewallregeln). Ein langer Lauf kann das Apply-Time-out überschreiten. Halte Änderungen klein.
Eine zusätzliche WAF-Einstellung, etwa die Inspektion des Request Body, ohne Test aktivieren. Legitime Anfragen treffen WAF-Regeln und Nutzer erhalten 403. Teste auf canary. Halte die Änderung fest. Siehe Application Gateway.
Ein fehlender Private-DNS-Eintrag für einen Backend-Namen. Das Application-Gateway-Backend ist unhealthy und Nutzer erhalten 502. Leicht mit einem firewall-Problem zu verwechseln. Prüfe die Namensauflösung vom hub aus, bevor du firewall-Regeln änderst (Incident-Management).
Eine Site-to-Site-VPN-Verbindung meldet connected, leitet aber keinen Verkehr durch. Ein Ausfall, den kein zustandsbasierter Alert erkennt. Alarmiere auf Traffic, nicht nur auf den Zustand. Nutze wo möglich zwei Verbindungen. In einem gemeldeten Fall stellte das Zurücksetzen der Verbindung auf beiden Seiten den Verkehr wieder her.
Ein Destroy, der auf halbem Weg scheitert (zum Beispiel eine gestoppte VM, deren Extensions sich nicht entfernen lassen), hinterlässt ein Teilergebnis. Ein späterer erneuter Lauf erstellt Teile neu, zum Beispiel eine leere Daten-Disk, die nicht angehängt ist. Prüfe, was nach einem fehlgeschlagenen Destroy übrig ist, bevor du erneut ausführst oder neu baust.
Ressourcen- oder Konfigurationsnamen, die die Umgebung doppelt enthalten. Die falsche Ressource wird zum Löschen ausgewählt. Vergleiche den Plan mit den echten Ressourcen und hole die Bestätigung des Eigentümers ein, bevor du einen Destroy anwendest.

Dokumentation, die an anderer Stelle in diesem Repository veraltet ist

Dokument Problem
docs/howto/run-initialize-pipeline.md, run-container-pipeline.md Sie verweisen auf initialize.yaml / stage-initialize.yaml und Selektorvariablen für canary/production. Die aktuelle Pipeline ist infrastructure.yaml, die alles aus mcp.json liest.
PLATFORM_FEATURES.md Sie behauptet, alle Ressourcen erhielten die Tags environment/managedBy/layer/region, und nennt Terraform >= 1.0 / AzureRM >= 3.0. Der Code hat keine globalen Tags (siehe hub-Tags); das Image pinnt Terraform 1.14.4, und die Layer pinnen azurerm 4.60.0. Für die Ressourcen und ihre Schalter nutze Was die Plattform deployt.
docs/howto/configure-terraform-logging.md Sie beschreibt die Parameter terraformLogCore und terraformLogProvider der pipelines environment_canary und environment_prod. Prüfe, ob die Entry-pipelines, die du verwendest, sie anbieten (Troubleshooting).
docs/howto/run-pool-smoke-tests.md Sie ruft Resolve-XebiaMcpConfiguration -Environment canary auf (die Funktion hat nur -Path) und dev.ps1 -Action Initialize. Verwende den Aufruf aus Troubleshooting.
Ältere Update-Runbooks (einzelne main.yaml-pipeline) Sie weichen bei der Layer-Reihenfolge ab (wo ghrunners steht) und beschreiben Layer, die die aktuelle hub-pipeline nicht ausführt. Siehe Generisches Update-Runbook.
Übersicht der Release Notes Sie nennt v4.4.0 als aktuelle stabile Version und endet bei v4.6.1. Siehe Release-Historie.
Ältere Alerting-Übersichtsdokumente Zwei Dokumente nennen unterschiedliche Severities für dieselben Alerts (zum Beispiel die VPN-Tunnel-Alerts), und eines nennt einen Alert für das Löschen einer Firewallregel mit der Operation eines anderen Resource Providers. Behandle die Alert-Definitionen im Code als maßgeblich (Alert-Katalog).
docs/policy_exemptions/current-platform-exemptions.md Mehrere Listen weichen von infra/deploy/postdeployment/main.tf ab, zum Beispiel die Subscription-Ausnahmen für NIS2 und CIS 1.4.0.
docs/service_management/standard_changes.md Ältere Anfrageformulare. Die Anfragefelder in diesem Leitfaden folgen dem aktuellen Standardänderungs-Katalog.
CONTRIBUTING.md Sie verwendet Resolve-XebiaMcpConfiguration -Environment (die Funktion hat nur -Path) und verweist auf Functions/Public/Runner/, das es nicht gibt.