Platform Deploy Flow¶
A platform environment is deployed in three steps. Each step depends on the one before it.
flowchart LR
infra["1. Infra<br/><code>infrastructure</code>"] --> release["2. Release<br/><code>container</code>"]
release --> mcp["3. MCP"]
mcp --> hub["Hub"]
hub --> env["Platform environment<br/>canary → prod"]
env --> layers["Layers<br/>foundation … postdeployment"]
mcp --> spoke["Spokes"]
spoke --> n["Spoke 1 … N"]
| Step | Pipeline | What it does | When you run it |
|---|---|---|---|
| 1. Infra | infrastructure |
Deploys the job runners the other pipelines run on: virtual network and NAT gateway, Azure Container Registry, Managed DevOps Pool, Container Apps environment, DNS resolver (Bicep in src/Xebia.Mcp/Files/bicep/deploy/initialize/). Also creates the blob container in the hub state storage account. |
Once at bootstrap, and when a release changes the runner Bicep. |
| 2. Release | container |
Builds the mcp container image from the pinned code version and pushes it to the ACR. The image contains PowerShell, Terraform, Azure CLI, the Xebia.Mcp module and the hub Terraform. |
After every code version bump. |
| 3. MCP | hub, then spoke |
Deploys the platform itself, see below. | For every change. |
3a. Hub → platform environment → layers¶
The hub pipeline deploys one platform environment at a time: canary first, then prod (the prod stage depends on
the canary stage in the reference hub.yaml). Within a platform environment, the layers run in a fixed order:
flowchart LR
subgraph L1["Level 1: primary region"]
f1[foundation] --> c1[connectivity]
end
subgraph L2["Level 2: other regions"]
f2[foundation] --> c2[connectivity]
end
subgraph L3["Level 3: all regions"]
fw[firewall]
id[identity]
mg[management]
end
subgraph L4["Level 4: primary region"]
pd[postdeployment]
end
L1 --> L2 --> L3 --> L4
Each layer is planned, optionally approved, and applied from the saved plan. Details: Deployment layers and Pipelines and workflows.
3b. Spokes 1 … N¶
The spoke pipeline deploys the spoke JSON files that match spokeGlob in one platform environment. The spokes are
grouped by spoke environment and run in order dev → tst → acc → prd. Each spoke has two Terraform states:
- the subscription layer (tags, name, management group), and
- the spoke canvas layer (network, identity, Key Vault, storage, Log Analytics).
Spokes depend on the hub: the virtual hub connection needs the hub, and the management group must exist. Deploy the hub before the first spoke.
Bootstrapping a new platform environment¶
For the complete sequence around this table (workshop, prerequisites, identities, repositories, validation and hand-over), see Implementing the platform.
| # | Step | Who / what |
|---|---|---|
| 0 | Create the Terraform state storage account(s), the spoke state blob container, and the deployment service principal(s), and grant them access | By hand, these are prerequisites |
| 0 | Create <env-folder>/mcp.json, global.auto.tfvars and the region tfvars in the configuration repository |
Config |
| 1 | Run infrastructure |
Job runners + hub state container |
| 2 | Run container |
mcp image |
| 3 | Run hub (first in Plan mode, then Apply) |
Hub layers, canary then prod |
| 3 | Run spoke for each spoke |
Spokes |
Spoke state container
No pipeline creates the spoke state blob container (Azure.TerraformState.Spoke.ContainerName). Create it by hand
before the first spoke run, or the backend initialization fails.
More detail: Provisioning.