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_poolsder gemeinsamen Einstellungen existieren. Sonst schlägt der Plan fehl und listet die verfügbaren Namen auf. addressPrefixundipamPoolschließen sich aus, für ein VNet und für ein Subnetz.- Ein VNet ohne
numberOfIpAddressesbekommt 256 Adressen. Jedes Subnetz muss seine eigene Größe angeben. - Ein Subnetz erbt den Pool seines VNets. Wenn du
numberOfIpAddressesunter einem VNet mit fest codiertemaddressPrefixverwendest, 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>.resVirtualNetworkAddressSpaceundresAllSubnets.
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.