Een klantomgeving onboarden¶
Dit runbook is voor het platformteam. Het beschrijft hoe een nieuwe omgeving van de portal wordt toegevoegd aan de gedeelde codebase en wordt gedeployd. Het is generiek: waarden staan als placeholders (<customer>, <env>, <tenant-id>) en de procedure beschrijft het referentieontwerp. Jouw deployment kan afwijken. "Klant" is de organisatie die eigenaar is van de Azure subscriptions; als het platformteam en de klant dezelfde organisatie zijn (zelfbeheerd model), lees de stappen dan dienovereenkomstig (Operating models).
Code en pipelines blijven bij de provider
In het leveringsmodel van de bron krijgt de klant een gedeployd product en de Azure-resources in zijn subscription. De klant krijgt de code en de pipelines niet. Hoe een zelfbeheerd team de portal zonder die code en pipelines draait, staat niet in de bron. Stem dat dus eerst af met de provider.
Fasen¶
| Fase | Resultaat | Eigenaar |
|---|---|---|
| Plan | Kick-off gehouden (60 minuten): wat de portal is, kernboodschappen, wat de klant aanlevert, planning. Daarna worden de vragenlijst en de prerequisites verstuurd. | Delivery manager |
| Prepare | Vragenlijst ingevuld en prerequisites vervuld | Engineer houdt de voortgang bij, klant vervult |
| Deploy | Omgeving gedefinieerd in de repository en gedeployd via de pipeline. Er wordt niets handmatig geconfigureerd in de tenant van de klant, behalve de goedkeuringen en rechten hieronder. | Engineer |
| Validate | Een tweede engineer controleert de validatielijst | Tweede engineer |
| Closure | Technisch overdrachtsgesprek (60 tot 90 minuten) met de technische en security-contactpersonen van de klant: demo met de eigen data van de klant, self-service, agents, MCP in de ontwikkelomgeving. Acceptatie. | Delivery manager, engineer geeft de demo |
Kernboodschappen om te herhalen
De Azure-kosten komen op de rekening van de klant. De provider blijft eigenaar van de code. Data blijft in de omgeving van de klant. Benoem de operationele garantie zoals afgesproken in het contract: die staat niet in de technische bronnen.
Er worden geen klantspecifieke codewijzigingen gedaan. Een aanvraag die niet in de gedeelde codebase past, wordt apart featurewerk. Zie ADR-0007 in Decisions.
Procedure¶
Gebruik voor stap 1 tot en met 6 een branch en een pull request.
1. De GitHub Environments aanmaken¶
Maak per Azure-omgeving één GitHub Environment aan, met de naam <customer>_<env> (bijvoorbeeld <customer>_acc en <customer>_prod). Vereis reviewers op productie. Acceptatie heeft geen reviewers. Het environment bevat de goedkeuringsstap voor het toepassen van een Terraform plan (Deployment en omgevingen).
2. Federated credentials toevoegen¶
Voeg Entra federated credentials toe aan de app registration van de deployment, één voor elk van deze subjects, met audience api://AzureADTokenExchange:
| Subject | Gebruikt door |
|---|---|
pull_request |
Plan op pull requests |
ref:refs/heads/main |
Plan en build op main |
environment:<customer>_<env> |
Apply, één per omgeving |
De issuer is de OIDC-issuer van de GitHub Enterprise-tenant. De subjects gebruiken de onveranderlijke owner- en repository-ID's in plaats van namen. Als er geen federated credential kan worden aangemaakt, val dan terug op een client secret (AZURE_CLIENT_SECRET_<OWNER>_<ENV>) en vraag opnieuw om de federated credential. Zie Authenticatie naar Azure.
3. Rijen toevoegen aan het omgevingenbestand¶
Voeg per omgeving één rij toe aan het omgevingenbestand (infra/customer-environments.json). De rij bevat de owner, de omgeving, de ring, de Terraform backend, de deployment identity en de namen van de web app en de registry. Zie Het omgevingenbestand.
Zet de eerste omgeving (acceptatie of test) in dezelfde ring als de eerste omgevingen van andere klanten en productie in de volgende ring. Een strikte volgorde ten opzichte van een specifieke andere klant vraagt om een nieuw ringnummer, en dat verandert de volgorde voor elke klant. Bespreek dat voordat je het doet.
4. De secrets instellen¶
Maak het repository secret aan waarnaar de rij verwijst voor de Terraform client secret, BACKSTAGE_CLIENT_SECRET_<OWNER>_<ENV>. Het is het enige echte secret in de opzet; de pull request bevat alleen de naam ervan. Andere app-secrets (bijvoorbeeld GitHub App-waarden) staan met naam in de rij en komen terug als Key Vault-verwijzingen.
5. De infrastructuur toevoegen¶
Elke klantomgeving heeft een eigen Terraform root module:
infra/
<customer>/
acc/main.tf
prod/main.tf
De root combineert de gedeelde modules: spoke canvas (bestaand netwerk lezen), naming, resource group, App Service plan, Key Vault, container registry, Azure Monitor, tenantconfiguratie, de backstage module en, indien nodig, foundry_platform, cost_insights en pagerduty. Zie Deployment en omgevingen en ADR-0009 in Decisions.
Zet de app setting APP_CONFIG_organization_name op de backstage module. Die selecteert het configuratiebestand app-config.<customer>.yaml, dus de waarde in de module en de bestandsnaam moeten exact overeenkomen, inclusief hoofdletters.
6. Het configuratiebestand toevoegen¶
Maak app-config.<customer>.yaml aan met de Microsoft-aanmelding en de repository provider. Voorbeeld (placeholders):
auth:
providers:
microsoft:
production:
clientId: ${BACKSTAGE_CLIENT_ID}
clientSecret: ${BACKSTAGE_CLIENT_SECRET}
tenantId: ${BACKSTAGE_TENANT_ID}
signIn:
resolvers:
- resolver: emailMatchingUserEntityAnnotation
catalog:
providers:
azureDevOps:
<organisation>:
host: dev.azure.com
organization: <organisation>
project: '*'
repository: '*'
path: 'catalog-info.yaml'
schedule:
frequency: { minutes: 30 }
timeout: { minutes: 3 }
Voeg optioneel een feature loader voor de klant toe in packages/backend/src/features/<customer>.ts om backend plugins aan of uit te zetten. Doe dit alleen als een configuratieflag het niet kan. Zie Configuratie.
Voeg optioneel alerting toe. De pagerduty module maakt een service aan, een afhankelijkheid van een business service en een Azure Monitor action group. Het gedeelde escalation policy waarnaar de module verwijst, moet al bestaan (Operations).
Private connectiviteit¶
Er zijn meerdere rondes nodig
Als de provider vanuit zijn eigen netwerk deployt, heeft die private endpoints nodig om resources te bereiken die de provider zelf aanmaakt. De provider heeft een verbinding nodig om te deployen, en de deployment maakt de volgende resources aan die bereikt moeten worden. Verwacht dat een eerste run mislukt.
- Voeg het storage account voor de Terraform state toe aan de lijst met private connections in de platform root van de provider (resource-ID en subresource
blob). - Merge. De platformpipeline maakt een plan op pull requests en past toe bij een merge naar main.
- De klant keurt de openstaande private endpoint connections op de doelresources goed. Het verzoek bevat een bericht dat uitlegt dat het nodig is voor de deployment. De klant kan een verbinding later intrekken.
- Koppel de nieuwe private endpoints aan de private DNS-zones van het platform. Deze stap is handmatig voor endpoints die goedkeuring nodig hebben, omdat de policy die dit automatisch doet daarop niet van toepassing is.
-
Start de dispatch workflow met infrastructuur aan en de portalbuild uit:
gh workflow run cicd-dispatch.yml --ref <your-branch> \ -f "deploy_to=ring 3" -f deploy_infra=true -f build_and_deploy_backstage=falseDe eerste run mislukt wanneer Terraform Key Vault of de registry via het data plane bereikt, omdat hun private endpoints nog niet bestaan. Dit is verwacht gedrag. 6. Voeg de private connections toe voor de Key Vault (
vault), de container registry (registry) en de andere resources die nu bestaan (SQL server, web app en staging slot, blob). Herhaal stap 2 tot en met 5 tot de run slaagt.
Het goedkeuren van verbindingen kan worden gescript. Het kerncommando is:
az network private-endpoint-connection approve --id <connection-id> \
--description "Required for the deployment of the portal"
7. De portal deployen¶
Start de dispatch workflow met zowel infrastructuur als portal aan:
gh workflow run cicd-dispatch.yml --ref <your-branch> \
-f "deploy_to=ring 3" -f deploy_infra=true -f build_and_deploy_backstage=true
Herhaal daarna stap 5 en 6 voor de volgende omgeving en deploy die.
8. Toegang verlenen aan de managed identity¶
De managed identity van de portal bestaat pas na de eerste deployment. Daarna:
- Een Entra-beheerder verleent de Graph application permissions
User.Read.AllenGroupMember.Read.Allmet admin consent (Prerequisites). - De beheerder van het cloudplatform verleent de Azure-rollen (Prerequisites).
Zolang beide niet zijn gedaan, ontbreken gebruikers en groepen en zijn de insights leeg.
9. Optionele features inschakelen¶
| Feature | Pagina |
|---|---|
| Cost insights | Cost insights setup |
| AI agents | AI setup |
| Eigen domein en WAF | WAF en eigen domein |
| GitHub-integratie, thema, module registry | Configuratie |
Validatie¶
Een tweede engineer voert de controles uit en legt per controle de gebruikte entity of waarde vast, niet alleen een vinkje.
| Controle | Hoe |
|---|---|
| Aanmelden | Een gebruiker uit de geconfigureerde groep meldt zich aan en komt in een gevulde catalog terecht |
| Azure-ingestie | Een bekende workload verschijnt in de catalog, met insights (kosten, compliance, security) |
| Timing van kosten | Exports draaien normaal binnen 24 uur en de ingestie 's nachts, dus kostendata kan één tot twee dagen duren. Start ze zo nodig handmatig. Een bekende subscription toont de laatste volledige maand. |
| Repository-ingestie | Het catalog-info.yaml van een bekende repository verschijnt |
| Gebruikers en groepen | Een bekende gebruiker en groep bestaan |
| Agents | De spoke agent beantwoordt een testprompt zoals "List all spoke files" en de toollijst van de MCP-server is niet leeg |
| Toegangsbeheer | Een gebruiker buiten het eigenaarsteam kan het detail van geblokkeerde firewallverzoeken van een workload die hij niet bezit niet zien |
| Private endpoints | Key Vault, registry en SQL server zijn alleen via private endpoints bereikbaar |
| Dataresidentie | Er verlaat geen data de subscriptions van de klant |
| Security baseline | Defender-aanbevelingen getrieerd, geen publieke netwerktoegang op dataservices, overal managed identities gebruikt |