Spoke Canvas Module Reference¶
The spoke canvas Terraform has two root modules: deploy/subscription and deploy/spoke, both in
src/Xebia.Mcp/Files/terraform/spoke-canvas/ of the code repository (layout). The pipelines
fill their variables; you normally do not run them by hand. This page groups the inputs by purpose, lists the modules,
and shows what the outputs hold. It is a reading guide: the generated tables in the README of each root module (made by
terraform-docs) stay the exact source.
For what the result looks like, see Spoke canvas: what a deployment creates. For the JSON that drives it, see the Spoke JSON reference.
Subscription root (deploy/subscription)¶
The subscription layer prepares the subscription for a spoke: it is the step before the spoke canvas. It calls the
subscription module and outputs the subscription ID that the canvas layer then uses. The design behind it is in
Subscription provisioning.
| Input | Required | Purpose |
|---|---|---|
FileName |
yes | Path of the spoke JSON file |
IncrementName |
no (default 001) |
Increment value for generated names. The sources do not describe it further |
TenantId |
yes | Tenant of the subscription |
xmscsp_billing_account_name, xmscsp_subscription, xmscsp_tenant, xmscspclient_id, xmscspclient_secret |
yes | Billing account and service principal that are needed to create a subscription (CSP route) |
| Output | Holds |
|---|---|
subscriptionId |
The ID of the subscription for the spoke |
The pipeline passes empty CSP values
The CSP inputs exist because the code can create a subscription when azureSubscriptionId is empty. The pipelines
pass the five CSP values as empty strings, so the subscription must exist before the run
(New spoke).
Spoke root (deploy/spoke)¶
Inputs by purpose¶
| Purpose | Input | Required | Description |
|---|---|---|---|
| Spoke definition | FileName |
yes | Path to the spoke configuration JSON file |
subscriptionOutputFileName |
yes | Path to the JSON file with the output of the subscription layer | |
subscription_id |
no | Subscription ID, when it is given directly | |
IncrementName |
no (default 001) |
Increment value for generated names. The sources do not describe it further | |
spoke_canvas_version |
no | Version identifier of the spoke canvas code. Written as the spoke_canvas_version tag |
|
| Deployment identity | xmscsp_tenant, xmscsp_subscription |
yes | Tenant and subscription the deployment runs against |
xmscspclient_id, xmscspclient_secret |
yes | Client ID and secret of the deployment identity | |
| Name overrides | overwrite_KeyVault, overwrite_KeyVaultPE, overwrite_StorageAccount, overwrite_StorageAccountPE, overwrite_LogAnalytics, overwrite_AutomationAccount, overwrite_DefaultNSGName, overwrite_VWanConnection, overwrite_SubscriptionName |
no | Replace the generated name of one resource. null keeps the standard name |
| GitHub integration | ghinfo |
no | Object with BaseUrl, OrganizationName and OidcIssuer of the GitHub host |
github_app_id |
no | GitHub App ID, for app authentication of the GitHub providers. Passed as TF_VAR_github_app_id in CI/CD. Leave unset to use token authentication |
|
github_app_installation_id |
no | Installation ID of the GitHub App on the platform organisation | |
github_app_installation_id_workload |
no | Installation ID on the organisation that holds the workload repository. Equals the platform installation when both are in the same organisation | |
github_token |
no | Token for repository management. In CI/CD normally a short-lived GitHub App installation token, passed as TF_VAR_github_token |
|
integration_module_source |
no | Git source of the integration modules used by the GitHub and shared-service extensions. Has a default; override it when your platform syncs the modules elsewhere |
Secrets as variables
xmscspclient_secret, github_token and the GitHub App credentials are secrets. Pass them from the pipeline's secret
store through TF_VAR_* variables. Never put them in a spoke file or a tfvars file in the configuration repository.
Modules¶
The spoke root is a composition. Modules by area:
| Area | Modules | What they do |
|---|---|---|
| Subscription | subscription_managementgroup, subscription_rename, subscription_tags |
Place the subscription in the management group, rename it, apply tags |
| Identity and access | privileges_adgroups, privileges_service_principal, privileges_roleassignments, pim_group_config, storespnsecret |
Create the Entra ID groups and the service principal, assign roles, configure PIM for the groups, store the service principal secret in the Key Vault |
| Resource groups | resourcegroup, resourcegroup_networkwatcher |
The resource group per region, and the dedicated group for Network Watchers |
| Network | virtualnetwork, virtualnetworkvhublink, networkwatcher |
Network, subnets, NSGs and route tables, the virtual hub connection, Network Watcher |
| Private DNS | private_dns_zone, private_dns_zone_vnet_link_hub |
An optional private DNS zone for the spoke, linked to the hub DNS resolver network |
| Resources for the workload | keyvault, storageaccount, loganalyticsworkspace |
Key Vault, storage account (with customer-managed key), Log Analytics workspace |
| Azure DevOps | AzureDevOps |
Optional repository and service connection |
| Extensions | apim_configuration, acr_configuration, servicebus_configuration, eventhub_configuration, github_repository_configuration, github_integration_configuration |
Optional use of shared services, and the GitHub repository with its federated credentials |
Besides the modules, the root creates an Azure Monitor activity log alert for policy operations. The sources do not describe its trigger or action group.
Outputs¶
Outputs are the hand-over between the layers and the information a pipeline can show or pass on. The sources list the names only, without a description:
| Output | Reports on |
|---|---|
workloadinfo |
The workload of the spoke |
resourcegroup |
The resource groups |
networking |
The network resources |
keyvault |
The Key Vault |
storage_account |
The storage account |
loganalytics |
The Log Analytics workspace |
groups |
The spoke Entra ID groups |
ProductTeamGroups |
The team groups that were given access |
privileges |
The role assignments |
spn |
The service principal |
Run terraform output on a spoke state to see the exact content for your version, and check it before you rely on it in
a script. Treat the output of spn as sensitive until you know that it holds no secret.
Providers and versions¶
The spoke root pins exact provider versions, as every root module does (Tools).
| Provider | Used for |
|---|---|
azurerm, azapi |
Azure resources |
azuread |
Groups, service principals, PIM |
azuredevops |
Repository and service connection |
github |
Repository and federated credentials |
external, time |
Supporting lookups and timing |
At the time of the extraction, the spoke root required Terraform 1.9.2 or higher. The exact versions per release are in the README of the root module in the version you pin.
Settings shared by all spokes¶
Settings that are valid for every spoke are kept once and not repeated in each spoke file. In the current platform they
are in mcp.json under SpokeCommon (mcp.json). In the older, separate spoke canvas
they were in a common.tf file. The groups of settings are the same:
| Group | Holds |
|---|---|
Tenant information (tenantinfo) |
Tenant, administrative unit ID, prefix for group names, validity of service principal secrets in days. Changing the validity creates new secrets for all spoke service principals |
| Networking | The subscription of the central virtual hub, and optionally the Azure Virtual Network Manager IPAM pools that spoke files may allocate address space from |
| Regions | Per region: Azure region name, friendly name, DNS server (normally the hub firewall in that region), resource ID of the virtual hub, resource ID of the central Log Analytics workspace |
| PIM configurations | The named PIM profiles nopim, self-approve and approval |
| Overrides for the PIM role map | Optional, see Data-plane access through PIM |
GitHub host (ghinfo) |
Base URL, organisation and OIDC issuer of the GitHub host. For GitHub.com the OIDC issuer is https://token.actions.githubusercontent.com |
| Shared services | The subscription of the shared services, used by the extensions |
An IPAM pool is regional, so name the pool with its region when you have more than one region. Spoke files that do not
use a pool keep their fixed address prefixes, which stays supported. A spoke file uses either addressPrefix or an
ipamPool with numberOfIpAddresses, not both. When a virtual network uses a pool, its subnets inherit it and only give
numberOfIpAddresses; a subnet in a network with a fixed address prefix cannot ask for a pool allocation.
Check the field names for your version
The names in this table are those of the older layout. Look in the Spoke JSON reference
and in mcp.json of your configuration repository for the names your version uses.
Related pages¶
- Spoke canvas: what a deployment creates
- Provisioning and Pipelines and workflows
- Spoke canvas upgrade guides for changes to these settings between versions