Config: Welche Konfiguration haben wir¶
Jeder Kunde hat ein Konfigurations-Repository. Es enthält nur Werte; der Terraform-Code liegt im Code-Repository. Es gibt zwei Arten von Konfiguration:
| Hub | Spoke | |
|---|---|---|
| Was wird konfiguriert | Die gemeinsame Plattform: management groups, Netzwerk, firewall, Policies, Monitoring | Eine Workload-landing-zone pro Datei |
| Format | *.auto.tfvars + JSON (firewall, IP groups, App Gateway, WAF, Policies) |
Eine JSON-Datei pro Spoke |
| Pipeline | hub |
spoke |
| Mehr dazu | Hub-Config | Spoke-Config |
So änderst du beides: Änderungen sicher durchführen (PR + CI + CD). Die häufigsten Änderungen findest du unter Häufige Anfragen.
Referenzseiten für spokes: Spoke-JSON-Referenz, Allgemeine spoke-Einstellungen, RBAC und PIM für spokes und Spoke-Integrationen.
Konventionen und Review: Prüfung von pull requests, Richtlinien für Firewallregeln und IP groups und, wenn du das optionale Modul betreibst, Managed-VM-Modul.
Aufbau eines Konfigurations-Repositorys¶
<config-repo>/
├── environments/
│ ├── canary/ ← <env-folder> for canary
│ │ ├── mcp.json Platform environment settings
│ │ ├── global.auto.tfvars Regions, environment names, platform subscription IDs
│ │ ├── <layer>.auto.tfvars Optional: values for one layer in every region
│ │ ├── <region>/ One folder per active region, e.g. gwc/
│ │ │ ├── global.auto.tfvars Region name and short name
│ │ │ ├── foundation.auto.tfvars
│ │ │ ├── connectivity.auto.tfvars
│ │ │ ├── firewall.auto.tfvars
│ │ │ ├── identity.auto.tfvars
│ │ │ ├── management.auto.tfvars
│ │ │ ├── postdeployment.auto.tfvars
│ │ │ ├── firewall_rule_configuration/*.json
│ │ │ ├── ip_groups/*.json
│ │ │ ├── application_gateways/*.json
│ │ │ └── web_application_firewall_policies/*.json
│ │ ├── firewall_rule_configuration/*.json Optional: global rule collection groups (all regions)
│ │ ├── ip_groups/*.json Optional: global IP groups (all regions)
│ │ ├── policies/ Definitions, set definitions, assignments, exemptions
│ │ └── spokes/<team>/*.json Spoke definitions
│ └── prod/ ← same structure
├── pipelines/ Azure DevOps entry pipelines + variables.yaml
└── .github/workflows/ GitHub Actions entry workflows
Zwei Namen sind durch den Code fest vorgegeben:
mcp.json. Der übergeordnete Ordner ist der<env-folder>. Der Ordnername wird zum Environment-Namen, der in den state keys verwendet wird (zum Beispielcanary).spokes/direkt unter dem<env-folder>.
Alle anderen Ordnernamen werden über die Variablen *_relative_path / *_file_location in den tfvars festgelegt.
mcp.json¶
Wird von src/Xebia.Mcp/Functions/Public/Config/Resolve-XebiaMcpConfiguration.ps1 gelesen. Als required markierte Schlüssel werden
validiert; GUID-Felder müssen gültige GUIDs sein.
| Key | Pflicht | Zweck |
|---|---|---|
CustomerName |
ja | Anzeigename des Tenants/Kunden. |
Azure.TenantId |
ja (GUID) | Entra ID tenant. |
Azure.TerraformState.Hub.{SubscriptionId, ResourceGroupName, StorageAccountName, ContainerName} |
ja | Backend für alle hub layers. Der Storage Account muss bereits existieren. |
Azure.TerraformState.Hub.ServicePrincipalId |
für GitHub, SPN-Login | Client-ID für den Azure-Login (GitHub OIDC) und den SPN-Login. |
Azure.TerraformState.Hub.KeyvaultName |
optional | Key Vault, der die SPN-Credentials speichert (update-spn). |
Azure.TerraformState.Spoke.* |
ja (gleiche Felder) | Backend und Identität für Spoke-Deployments. |
Azure.JobRunner.{SubscriptionId, ResourceGroupName, Location} |
ja | Wo die Job-runner bereitgestellt werden. |
Azure.JobRunner.MaximumAgents, .Sku, .IpAddressPrefixes.* |
optional | Poolgröße, VM-Größe und Adressbereiche des runner-Netzwerks. |
AzureDevops.OrganizationName, .AgentPool |
ja, außer wenn ein GitHub-Abschnitt vorhanden ist |
Azure DevOps-Organisation und Managed DevOps Pool. Der Container-Pool heißt <AgentPool>-CTR. |
AzureDevops.ContainerImageName |
optional | Images, die die container-pipeline baut (normalerweise ["mcp"]). |
GitHub.{AppId, AppInstallationId, AppPrivateKeySecretName} |
für GitHub-runner | GitHub App, mit der self-hosted runner registriert werden. |
SpokeCommon.tenantinfo |
für Spokes | AdministrativeUnitId, GroupnamePrefix (z. B. SG_SPOKE_), SPNNamePrefix (z. B. SPN-SPOKE-), SubsciptionNamingTemplate (die falsche Schreibweise ist der tatsächliche Key), SPNSecretrotationPeriod (Tage). |
SpokeCommon.shared_services |
für Spoke-Erweiterungen | subscription und regionsspezifische Resource-IDs der Shared-Dienste APIM, ACR, Service Bus, Event Hub. |
Die übrigen spoke-weiten Einstellungen (Regionen, IPAM-Pools, PIM-Profile, GitHub-Instanz) beschreibt Allgemeine spoke-Einstellungen.
Wie relative Pfade in tfvars aufgelöst werden¶
Jeder layer erhält -var config_path=<env-folder>, den Ordner, der mcp.json enthält. Terraform baut Dateipfade als
"${var.config_path}/${var.<x>_relative_path}". Schreibe relative Pfade ausgehend vom <env-folder>:
# environments/prod/gwc/firewall.auto.tfvars
firewall_rule_collection_file_location = "gwc/firewall_rule_configuration" # correct
ip_group_json_file_relative_path = "gwc/ip_groups/" # correct
ip_group_json_file_relative_path = "environments/prod/gwc/ip_groups/" # wrong: resolves to environments/prod/environments/prod/…
Ein falscher Pfad löscht Ressourcen
Ist ein Ordnerpfad falsch, findet fileset() keine Dateien und schlägt nicht fehl. Der Plan will dann jede
Ressource löschen, die aus diesem Ordner stammte (rule collection groups, IP groups, Policy-Zuweisungen). Lies immer die
Plan-Zusammenfassung, bevor du apply ausführst. Das Referenz-Konfigurations-Repository xms-cloud-platform-config verwendet derzeit
Pfade ab dem Repository-Root; siehe Bekannte Probleme.
Welche tfvars-Dateien ein layer liest¶
Für den layer <layer> in der Region <region> übergibt der Plan diese var-Dateien in dieser Reihenfolge und überspringt Dateien, die nicht existieren
(Invoke-XebiaHubPlanAction.ps1):
<env-folder>/<region>/<layer>.auto.tfvars<env-folder>/<region>/global.auto.tfvars<env-folder>/<layer>.auto.tfvars<env-folder>/global.auto.tfvars
Wenn eine Variable in mehr als einer Datei gesetzt ist, verwendet Terraform den Wert aus der Datei, die zuletzt übergeben wird. Setze jede Variable in genau einer Datei.
Eine nicht deklarierte Variable in einer tfvars-Datei erzeugt nur eine Warnung, ein Tippfehler wird also stillschweigend ignoriert. Prüfe die Namen gegen
infra/deploy/<layer>/variables*.tf.