Zum Inhalt

Spoke-JSON-Referenz

Eine JSON-Datei pro Spoke (ein workload in einem Spoke-Environment), abgelegt unter <env-folder>/spokes/.

Die Anleitung für eine neue Datei steht in Neuer Spoke. Einstellungen, die für alle spokes gelten (Tenant, Regionen, IPAM-Pools, PIM-Profile), stehen in Gemeinsame Spoke-Einstellungen.

  • Schema: src/Xebia.Mcp/Files/json/spokeschema.json (JSON Schema draft-07).
  • Konsument: src/Xebia.Mcp/Files/terraform/spoke-canvas/deploy/spoke/ (locals.tf, main.tf).

Pflicht = vom Schema vorgeschrieben. Verwendet = von Terraform gelesen. Felder, die im Schema stehen, aber nicht verwendet werden, sind als ohne Wirkung markiert.

Oberste Ebene

Feld Typ Pflicht Beschreibung
workloadShortName string, max 6 ja Kurzer workload-Code. Wird in Ressourcennamen, Gruppennamen und im state key verwendet. Nach der Erstellung nicht ändern.
environment string ja dev, tst, test, acc, acc<n>, prd, prod, shrd, shared. Die pipeline fasst sie zu den Stages dev / tst / acc / prd / shared zusammen, aber Namen und state key verwenden den Rohwert. Nach der Erstellung nicht ändern.
azureSubscriptionId string ja ID einer bestehenden subscription (siehe Neuer Spoke).
azureSubscriptionName string ja Die subscription wird in diesen Namen umbenannt. Wenn leer, wird SpokeCommon.tenantinfo.SubsciptionNamingTemplate verwendet.
managementGroupId string ja Name der management group (nicht die vollständige ID), zum Beispiel cloudplatform-landingzones-corp. Muss eine id in <env-folder>/<targetRegions.primary>/foundation.auto.tfvars sein (Config-Test).
subType string nein Ohne Wirkung.
resourceGroup.name string/null nein Überschreibt den Namen der resource group rg-canvas-<wl>-<env>-<region>-001.
tags object ja Pflicht-Keys: owner, department, workload, pii (yes/no), costcentre, environment. Zusätzliche Keys sind erlaubt. Werden auf die subscription und die canvas-Ressourcen angewendet, zusammen mit spoke_canvas_version. Das Deployment fügt außerdem einen reservierten Tag hidden-XebiaSpokeMetadata mit JSON-codierten Metadaten aus der spoke-Datei hinzu. Trage diesen Tag nicht in die Datei ein.
adInfo object ja Identität, siehe unten.
targetRegions.primary string ja Kurzname der Region, zum Beispiel weu.
targetRegions.additional array ja Zusätzliche Regionen ([] für keine).
azdo object nein Erstellt ein Azure DevOps-Repo und eine Service Connection. Lass den Key ganz weg, um das zu überspringen; null verletzt das Schema. Siehe Spoke-Integrationen.
extensions object nein Das Schema erlaubt nur apim, acr, servicebus, eventhub, jeweils als { "enabled": bool }. Sie nutzen die Shared-Dienste aus mcp.json SpokeCommon.shared_services (was jede Extension einrichtet). Terraform liest außerdem extensions.github (siehe Spoke-Integrationen) und extensions.integrations, aber das Schema mancher Versionen lehnt sie ab. servicebus.enabled: true benötigt Gruppennamen-Keys, die das Schema ablehnt, daher kann es den Config-Test derzeit nicht bestehen (Bekannte Probleme).
resourceconfiguration object ja Ressourcen, siehe unten.

adInfo

Feld Typ Pflicht Beschreibung
ProductTeamGroupNames string[] ja Anzeigenamen bestehender Entra ID-Gruppen, die über die Spoke-Gruppen Zugriff erhalten.
PIMGroupConfig.Readers / .Contributors / .Owners enum ja nopim = aktive Mitgliedschaft, self-approve = PIM-eligible ohne Genehmigung, approval = PIM-eligible mit Genehmigung. Die Profile sind in pim_configurations definiert (gemeinsame Einstellungen). Die Support-Gruppe ist nicht konfigurierbar: Die Deployment-Logik setzt sie immer (RBAC und PIM).
ad_OwnersMembers, ad_OwnersMembersUPN string[] (E-Mail / UPN) nein Initiale Owner der Spoke-Gruppen. Zusammen mit der Deployment-Identität und dem Spoke-SPN werden sie Owner aller vier Spoke-Gruppen, nur bei der Erstellung (ignore_changes).
ad_ReadersMembers, ad_ReadersMembersUPN array nein Werden Mitglieder der Readers-Gruppe, nur bei der Erstellung.
ad_EngineersMembers, ad_EngineersMembersUPN array nein Ohne Wirkung (werden gelesen, aber auf keine Gruppe angewendet).
PIMAssignments object nein Überschreibung der RBAC role map pro spoke, mit dem exakten Azure-Rollennamen als Key, plus levels und/oder pim_profile. Siehe RBAC und PIM für spokes.
SPNGraphPermissions string[] nein (nicht im Schema) Microsoft-Graph-App-Rollen, die dem Spoke-Service-Principal zugewiesen werden.
SupportManagementInfo object nein Ohne Wirkung (wird von Terraform nicht gelesen).

resourceconfiguration.network[]

Feld Typ Pflicht Beschreibung
name string ja VNet-Name. Die Platzhalter ##wlshortname##, ##environment## und ##region## werden ersetzt.
region string ja Kurzname der Region dieses VNets.
addressPrefix string[] (CIDR) ja, außer bei ipamPool Adressraum des VNets, zum Beispiel 10.20.4.0/23. Keine Prüfung auf Überlappung. Schließt sich mit ipamPool aus.
ipamPool string nein Name eines IPAM-Pools aus networking.ipam_pools in den gemeinsamen Einstellungen. Verwende ihn statt addressPrefix. Siehe unten.
numberOfIpAddresses number nein Größe des Blocks, der aus dem Pool zugewiesen wird, zum Beispiel 256 für ein /24. Nur mit ipamPool. Default 256.
peerHub bool ja Die virtual-hub-Verbindung erstellen (Default true).
dnsServerOverwrite string ja "" = den Hub-DNS-Server der Region verwenden. Sonst eine IP.
InternetSecurityEnabled bool nein (nicht im Schema) internet_security_enabled auf der Hub-Verbindung (Default true: Internet über die Hub-firewall).
overwritePeeringConnectionName string nein Überschreibt den Namen der Hub-Verbindung (Default: VNet-Name mit vnet- → con-).
useIPAM bool nein Ohne Wirkung.
subnets[] array ja Siehe unten.
networksecuritygroups[] array ja { name, rules[] }. Eine NSG wird von Subnetzen mit demselben name referenziert. Ändere nicht die priority einer bestehenden Regel (sie wird neu erstellt, was fehlschlagen kann): Füge eine neue Regel mit neuem Namen und neuer Priority hinzu und entferne die alte Regel später. Jede Regel benötigt name, priority (string), direction, access, protocol (*, Tcp, Udp, Icmp, Ah, Esp), source_port_range, destination_port_range, source_address_prefix, destination_address_prefix. Regelnamen müssen eindeutig sein und sagen, wofür die Regel da ist. priority ist pro NSG eindeutig, von 100 bis 4096 (niedriger heißt höhere Priorität). Ports sind 1 bis 65535, ein Bereich (2048-2055) oder eine Liste (80,443). Adresspräfixe sind ein CIDR, ein Bereich oder ein Service Tag.
routetables[] array ja { name, routes[] }. Eine Route ist { name, properties: { addressPrefix, nextHopType, nextHopIpAddress } }. nextHopType ist einer von VirtualNetworkGateway, VnetLocal, Internet, VirtualAppliance, None.

subnets[]

Feld Typ Pflicht Beschreibung
name string ja Platzhalter werden ersetzt.
addressPrefix string (CIDR) ja, außer bei einem IPAM-Pool Muss im Adressraum des VNets liegen. Schließt sich mit ipamPool und numberOfIpAddresses aus.
ipamPool string nein Nur nötig, wenn das Subnetz aus einem anderen Pool stammen soll als sein VNet. Subnetze erben den Pool des VNets.
numberOfIpAddresses number ja für ein Subnetz, das einen Pool nutzt Größe des Subnetzes, zum Beispiel 16 für ein /28. Ein Subnetz hat keinen Default.
isprivatelinksubnet bool ja Subnetz für Private Endpoints. Jeder network[]-Eintrag benötigt mindestens ein Subnetz mit true; das erste wird für die Private Endpoints von Key Vault und Storage des Spokes verwendet. Bestimme dafür ein Subnetz.
privateEndpointNetworkPoliciesEnabled bool ja true → Enabled. Sonst RouteTableEnabled für Private-Link-Subnetze, andernfalls Disabled.
privateLinkServiceNetworkPoliciesEnabled bool nein
serviceEndpoints [{ "service": "<name>" }] ja Zum Beispiel Microsoft.Storage, Microsoft.KeyVault.
delegations [{ "name", "actions": [] }] ja name aus der Schema-Liste (66 Werte, zum Beispiel Microsoft.Web/serverFarms, Microsoft.App/environments, Microsoft.DBforPostgreSQL/flexibleServers).
linkedroutetablename string/null ja Name einer Route Table in routetables[], oder null. Neuere Versionen brauchen keine zusätzlichen Routen, daher sollte eine Route Table die Ausnahme sein.
linkednetworksecuritygroupname string nein Name einer NSG in networksecuritygroups[]. Leer → eine Standard-NSG wird erstellt und zugeordnet.

Adressraum aus einem IPAM-Pool

Statt Adresspräfixe fest zu codieren, kann ein spoke bei einem Azure-Virtual-Network-Manager-IPAM-Pool Adressraum anfordern. Konfiguriert werden nur der Pool-Name und die Größe. Azure wählt die Adressen.

"network": [
  {
    "name": "vnet-##wlshortname##-##environment##-##region##-001",
    "region": "weu",
    "ipamPool": "dev-weu",
    "numberOfIpAddresses": 512,
    "peerHub": true,
    "dnsServerOverwrite": "",
    "subnets": [
      {
        "name": "snet-##wlshortname##-default-##environment##-##region##-001",
        "isprivatelinksubnet": false,
        "numberOfIpAddresses": 256,
        "privateEndpointNetworkPoliciesEnabled": false,
        "serviceEndpoints": [],
        "delegations": [],
        "linkedroutetablename": null,
        "linkednetworksecuritygroupname": ""
      }
    ],
    "networksecuritygroups": [],
    "routetables": []
  }
]

Regeln:

  • Der Pool-Name muss in networking.ipam_pools der gemeinsamen Einstellungen existieren. Sonst schlägt der Plan fehl und listet die verfügbaren Namen auf.
  • addressPrefix und ipamPool schließen sich aus, für ein VNet und für ein Subnetz.
  • Ein VNet ohne numberOfIpAddresses bekommt 256 Adressen. Jedes Subnetz muss seine eigene Größe angeben.
  • Ein Subnetz erbt den Pool seines VNets. Wenn du numberOfIpAddresses unter einem VNet mit fest codiertem addressPrefix verwendest, schlägt der Plan fehl, weil es keinen Pool gibt, aus dem zugewiesen werden kann.
  • Die Adressen sind beim Schreiben der Datei nicht bekannt. Schreibe NSG-Regeln und Routen gegen Service Tags oder den Tag VirtualNetwork, nicht gegen konkrete CIDRs.
  • Die zugewiesenen Bereiche stehen im Deployment-Output: networking.virtualnetwork.<vnet>.resVirtualNetworkAddressSpace und resAllSubnets.

Optionale Ressourcenblöcke

Ist ein Block nicht vorhanden, gelten die Defaults in Terraform. Storage account, Key Vault und Log Analytics werden standardmäßig deployt. Ist ein Block vorhanden, müssen alle vom Schema vorgeschriebenen Keys vorhanden sein.

Block Pflicht-Keys, wenn vorhanden Hinweise
storageaccount EnablePublicAccess, CreatePrivateEndpoint, AccountReplicationType, AccessTier (Cool/Hot/Premium), AccountKind, AccountTier, infrastructure_encryption_enabled, allow_nested_items_to_be_public Optional: deploy (Default true), name, PrivateEndpointList (blob, queue, file, table, dfs, web), EnableSAS, Containers. Ein Storage account erzwingt einen Key Vault (Customer-managed Key).
keyvault enablepublicaccess, createprivateendpoint, EnableRBACAuthorization (muss true sein), SKUName, SoftDeleteRetentionInDays, EnabledForDeployment, EnabledForDiskEncryption, EnabledForTemplateDeployment Optional: deploy (Default true), name.
loganalytics deploy, sku, RetentionInDays, AllowResourceOnlyPermissions Optional: name. forwardactivitylog ist ohne Wirkung.
networkwatcher deploy Default false.
privatedns – name: erstellt eine private DNS zone, die mit dem VNet des Hub-DNS-Resolvers verknüpft ist. null = keine.

Standardwerte und Hinweise

Einstellung Default oder Hinweis
Storage account EnablePublicAccess false. true sollte die Ausnahme sein.
Storage account / Key Vault CreatePrivateEndpoint true. false sollte die Ausnahme sein.
AccountReplicationType, AccessTier, AccountTier ZRS, Hot, Standard
PrivateEndpointList Nur Kleinbuchstaben. Ein Private Endpoint pro aufgeführtem Subtyp.
Containers Liste der Container-Namen, die im Storage account erstellt werden (zum Beispiel einer für den Terraform state).
Key Vault SoftDeleteRetentionInDays 30. Erlaubt sind 7 bis 90.
Key Vault deploy: false Kein Key Vault und kein Private Endpoint, und es wird kein Secret des Service Principals gespeichert. Wird ignoriert (auf true erzwungen), solange der Storage account deployt wird.
Storage account deploy: false Kein Storage account und keine Private Endpoints.
loganalytics.deploy true. false sollte die Ausnahme sein.
Network watcher Einer pro Region, wenn aktiviert, in einer eigenen resource group, nicht in der canvas-resource-group.

azdo

Feld Beschreibung
projectName Bestehendes Azure DevOps-Projekt
repoName Zu erstellendes Repository (##wlshortname## und ##environment## werden ersetzt)
serviceConnectionName Azure-RM-Service-Connection, die für den Spoke-SPN erstellt wird (##wlshortname## und ##environment## werden ersetzt)
useFederatedCredentials true = workload identity federation statt eines Secrets. Es wird kein Secret erzeugt oder im Key Vault gespeichert, und auf der App Registration wird ein Federated Credential erstellt. Default false. Bei manchen Versionen nicht im Schema, wird von Terraform gelesen.

Was das Deployment mit diesem Block macht, und das GitHub-Pendant: Spoke-Integrationen.