Onboarding av ett team ska vara en pull request
Ett nytt team ska in på plattformen. I många organisationer betyder det ett uppstartsmöte, en kedja av tickets och ett par veckors kalendertid innan teamet kan deploya någonting alls. Jag bygger det så att det kostar en pull request. Så här ser den ut, och varför varje del ser ut som den gör.
Kontraktet: en fil per team
Allt plattformen behöver veta om ett team ryms i en fil:
name: team-payments
owner: usg-team-payments # AD group, not individuals
costCenter: "4711"
environments: [dev, test, prod]
size: medium # small | medium | large
Filen är teamets kontrakt med plattformen, och varje rad är ett beslut som ingen behöver fatta manuellt igen. Teamnamnet används konsekvent överallt: i namespace, pipelines och DNS. Ägaren pekar på en AD-grupp, inte på personer, så när teamet byter medlemmar behöver plattformen aldrig få veta det. Kostnadsstället gör att kostnaderna fördelas rätt från dag ett, inte i ett städprojekt i november.
Resursnivån är medvetet trubbig: tre storlekar, inte fri konfiguration. Varje fält som går att fylla i fritt är ett fält som går att fylla i fel, och ett unikt konfigurerat team är ett team plattformen inte kan resonera om. Behöver någon mer än large är det ett samtal, och det är precis de samtalen jag vill lägga tid på istället för alla andra.
Repostrukturen: teamet äger sin egen fil
platform/
├── tenants/
│ ├── team-payments.yaml
│ └── team-cards.yaml
└── CODEOWNERS
Mer än så behöver repot inte innehålla. Vid merge expanderas kontrakten till byggblock för namespace, RBAC och network policies. De kan ligga i Helm, Terraform eller en operator. Verktyget spelar mindre roll. Kontrakten själva bor däremot alltid här: plattformsteamet äger repot, schemat, valideringen och byggblocken, teamen äger innehållet i sina egna filer. Den första PR:en, när filen skapas, granskas av plattformsteamet, eftersom den innebär ett nytt tenant-kontrakt med en resursbudget och en egen säkerhetsgräns. Efter det äger teamet sin egen fil. En rad i CODEOWNERS gör att team-payments själva godkänner ändringar i team-payments.yaml:
/tenants/team-payments.yaml @org/team-payments
Vill de gå från small till medium är det deras beslut och deras review. Det som skyddar plattformen är inte att jag tittar på varje ändring, det är att valideringen gör det.
Valideringen: CI säger nej så att ingen människa behöver
Allt som går att säga nej till i ett möte ska gå att säga nej till i CI. Vid varje PR mot tenants/ körs samma kontroller: att filen följer schemat, att namnet matchar standarden, att kostnadsstället finns i ekonomisystemet, att summan av alla teams kvoter ryms i klustrens kapacitet. Bryter något blir PR:en röd med ett meddelande som säger vad och varför.
Poängen med valideringen är inte främst att fånga fel. Det är att göra reglerna exekverbara. En policy som bara finns på en wikisida är en åsikt. En policy i CI är en regel. Och ett nej från en pipeline är dessutom inget personligt: ingen har någonsin blivit långsint på ett rött bygge.
Merge är hela ceremonin
Vid merge tar automationen över. Verktyget är utbytbart. Det viktiga är att merge är det sista manuella steget.
Ur de tio raderna genereras allt teamet behöver i varje miljö: namespace med kvoter och limits, RBAC bundet till AD-gruppen, network policies med default deny, en deploy-pipeline med rättigheter till exakt sitt namespace och budgetlarm kopplat till kostnadsstället. Ett femtiotal resurser, noll handpåläggning.
Var går då gränsen för vad som ska in i tenant-filen? Öppningar inom det egna namespacet gör teamet själva. Men det som korsar en gräns påverkar någon annan och hör hemma i kontraktet, som ett valfritt fält i samma fil:
network:
ingress:
- from: team-cards # another tenant on the platform
egress:
- to: onprem-payment-gateway # leaves the platform
ports: [443]
Raderna blir network policies och firewall-regler vid merge, på plattformens sida. Ägaren på andra sidan, i det här fallet on-prem-brandväggen, måste fortfarande godkänna sin del. Är deras regler också kod kan pipelinen öppna en PR hos dem, och överlämningen blir synlig och versionshanterad i stället för att försvinna i en kö. Är de inte det blir det en ticket, och där går automationens gräns.
Kalendertiden för onboarding blir tiden det tar att få en PR granskad. Är filen rätt är teamet igång samma dag, inte samma kvartal.
Varför inte ett formulär?
Ett formulär kan samla in samma tio fält, så varför envisas med en fil i git? Skillnaden syns efteråt. Formulärets svar sparas i portalens databas och blir en andra sanning vid sidan av den som faktiskt kör, en kopia som ingen granskar och som sakta glider ifrån verkligheten. Filen är ingen kopia av konfigurationen, den är konfigurationen. Vill du veta varför team-cards har en large-kvot är svaret en git blame bort. Vill du testa en ny policy mot alla team är det en dry-run mot en mapp med filer. Vill du återskapa plattformen i en ny region är tenants-mappen hela sanningen.
Och offboarding, som formulär sällan har någon knapp för, är samma PR baklänges: ta bort filen, låt automationen städa. I en reglerad miljö är det ofta där revisionen hittar sina fynd: i sådant som skapades för tre år sedan och aldrig togs bort. Här är borttaget lika spårbart som skapandet.
Första intrycket sätter kulturen
Onboarding är plattformens första intryck. Gör den till ett projekt och teamet lär sig från dag ett att plattformen är någon man väntar på. Gör den till en pull request och teamet lär sig att plattformen är något man använder. Tio rader YAML säger mer om din plattform än trettio sidor dokumentation.
Tar onboarding av ett nytt team fortfarande veckor hos er? Så jobbar jag.