Idriftsettelse: Kai Platform prod på ekte data⚓︎
Denne runbooken tar Kai Platform (v2) i prod fra hardkodet testdata til ekte data:
API-et leser fra PostgreSQL og workeren kjører daglig synk + pipeline (seleksjon →
dokumenter → ekstraksjon → regelkjøring). Den speiler oppsettet som allerede kjører i
test (infrastructure/environments/test/main.tf).
Alt kode-/config-arbeidet ligger i PR-en som lukker AB#21247. Prod er config +
bootstrap — ingen ny kode. Fordi promote-pipelinene for prod er trigger: none,
skjer ingenting automatisk ved merge; hvert steg under kjøres manuelt av deg.
Rekkefølge er viktig
Kjør stegene i rekkefølge. Promoterer du image-ene (steg 5–6) før infra er
applied (steg 3) og DB-en er bootstrappet (steg 4), krasjer app-ene ved oppstart
(ValidateOnStart på Mimir/Websak, eller Postgres-tilkobling som timer ut).
Go-live-gate (AB#21247 AC#3)⚓︎
Saksbehandlere skal ikke se prod-resultater før noen har besluttet at de er til å stole på.
- Godkjenner: Bjørn Kristian Punsvik (BK). (TODO: flytt til PO/fagansvarlig når det er avklart med teamet.)
- Beslutning dokumenteres her når den er tatt: dato, hvem, og hva som ble verifisert (minst én ekte sak gjennom hele pipelinen med korrekt regelutfall).
- Gate: ikke slipp saksbehandlere til prod-flaten før denne beslutningen er ført.
| Dato | Godkjent av | Verifisert |
|---|---|---|
| 2026-07-16 | BK (Noone is using prod v2 atm so its safe to deploy) | 2026-07-17: sak 26/23624 gikk hele pipelinen (CU-ekstraksjon → 3 tilbud med tilbudsdato+konfidens → regelutfall «Ikke godkjent: 3 tilbud, men nøyaktig 2 kreves»). Ekte data, korrekt regelutfall. |
Prod-fakta⚓︎
| Ting | Verdi |
|---|---|
| Subscription | b6eeed57-7d07-45d6-ac3d-147c5cf872f6 (pv-kai-prod) |
| Ressursgruppe | rg-kai-platform-prod |
| Deploy-SP | 5d4dc673-10b6-4f9d-81b6-d1543a81e646 (kai-azure-prod) |
NAT-egress-IP (pip-ng-kai-prod) |
51.107.216.52 |
| PG-server / FQDN | psql-kai-platform-prod / psql-kai-platform-prod.postgres.database.azure.com |
| Entra-admin-gruppe (= psql-login-bruker) | kai-platform-db-admins-prod |
| App-principaler | app-kai-platform-api-prod, app-kai-platform-worker-prod |
| Foundry (CU + chat) | aif-kai-prod · https://aif-kai-prod.services.ai.azure.com |
| Websak (prod) | base https://api.data.enova.no/websak · scope api://websak-api-authentication-prod.enovasf.onmicrosoft.com/.default |
| Mimir / Databricks (delt prod-instans) | url https://adb-3890932255281591.11.azuredatabricks.net · warehouse abbe6bba5318fc3c |
Manuelle forutsetninger (AB#21247 AC#4)⚓︎
Disse krever prod-privilegier og gjøres av en prod-admin. Kryss av før go-live.
- [ ] pg-bootstrap — kjør
pg-onetime-bootstrap.sql(steg 4 under). Oppretter api/worker-principalene, grants (inkl.CREATE ON DATABASE kaifor worker → TickerQticker-schema), og forhåndsopprettervector-extensionen. - [ ] Databricks-grant — worker-managed-identity må ha lesetilgang til å spørre
Mimir/Databricks-warehouset (SELECT/USE på
production.gold+CAN_USEpå warehouset). Ellers er workeren «healthy» menReplikaSync/SakSeleksjonfeiler (403). Api-en kaller IKKE Mimir (den leser kun ferdig-ekstraherte fakta fra Postgres) — kun worker-MI-en trenger denne granten. - [ ] Tenant-consent — admin-consent på prod-app-registreringene (Websak-scope m.m.), slik at Entra-token-flyten fungerer.
- [ ] Websak-gruppemedlemskap — worker-MI-en må være medlem av (ha app-rollen på)
websak-api-authentication-prod(«user assignment required»).enable_worker_computewirer app-rolle-tildelingen i modulen; bekreft at den faktisk ble opprettet. - [x] KV-secret —
websak-subscription-key(APIM-nøkkel; ikke[Required], men Websak-kall 401-er uten den) legges i prod-Key-Vault når Websak faktisk kalles. - [x] Foundry-deployment — prod bruker
gpt-4.1, som allerede er Terraform-styrt påaif-kai-prod(infrastructure/prod/main.tf→foundry_models_to_deploy). Ingen manuell handling. NB: test kjører pågpt-5.2-257303(portal-opprettet, ikke i Terraform), så prod/test har modell-gap; å gjøregpt-5.2Terraform-styrt i begge miljøer spores i AB#21273 (Kai får egen AIF-konto eid av kai-platform). - [x] CU-analyzere deployet til prod — pipelinene deployer dem nå automatisk:
kai-worker-promotekjører etdeploy-cu-preDeployStep (somkai-azure-prod-SP-en) FØR ACR-retag, så analyzerne finnes iaif-kai-prodfør worker-imaget som forventer dem rulles ut. En fersk CU-ressurs har ingenmodelDeployments-defaults; verktøyet setter dem nå idempotent selv (før het det manuelt/portal). Forutsetning:kai-azure-prod-SP-en må ha direkteCognitive Services Content Understanding Contributorpåaif-kai-prod— CU sin (preview) data-plane-RBAC honorerer KUN direkte bruker/SP-tildelinger, ikke gruppe-baserte (nested eller ei). Terraform-styrt (infrastructure/{prod,test}/main.tf, v1-rot). Uten den:ExtractDocument→404 ModelNotFound.
Rulleut-steg⚓︎
Steg 1 — Merge PR-en (AB#21247)⚓︎
Endrer, alt i én PR:
src/Enova.Kai.Api/appsettings.Production.json— AIF-endepunkt (gpt-4.1).src/Enova.Kai.Worker/appsettings.Production.json(ny) — AIF, Websak, CU (prod).infrastructure/environments/prod/main.tf—enable_worker_compute=true, api/workerConnectionStrings__kai+ blob-URI,db_admin_upns,backend_app_role_group_member_upns, NAT-IP iprod_trusted_ips.
Merge er trygt — ingenting deployes til prod automatisk. appsettings.Production.json
lastes kun når ASPNETCORE_ENVIRONMENT=Production (kun prod), så test er urørt.
Steg 2 — (ingen)⚓︎
Steg 3 — La kai-infra apply prod⚓︎
Kjør/godkjenn kai-infra-promote. Oppretter/oppdaterer app-settings for api+worker,
firewall-regelen for NAT-IP-en, kai-platform-db-admins-prod-gruppen + AD-admin, og
worker-compute. Prod krever godkjenning; kjører som kai-terraform-prod-SP-en.
- Se opp for
azuread_group_member«already exists» hvis prod-gruppene har manuelle medlemmer (traff oss i test) — fjern/importer dem og kjør på nytt.
Steg 4 — Én-gangs DB-bootstrap (kjøres én gang, som prod-team-admin)⚓︎
Bruk kai-postgres-connect-skillen. Koble som gruppenavnet mot postgres-DB-en:
- Din egen laptop-IP må ligge i
prod_trusted_ipsfor å koble (BK sin hjemme-IP er der). - Gruppe-sync mynter individuelle UPN-roller ~30 min etter enable; frem til da bruk gruppenavnet som psql-bruker (funker alltid). Idempotent.
Steg 5 — Deploy worker⚓︎
Kjør/godkjenn kai-worker-promote til prod → workeren migrerer DB-en på oppstart →
/health 200. Se etter Applying N pending EF migrations → EF migrations applied →
Now listening on :8080 i loggen. Bruk appservice-container-logs hvis den ikke
kommer opp. (Worker først så schemaet finnes før api-en kobler.)
Promote deployer også CU-analyzerne (preDeployStep)
kai-worker-promote kjører deploy-cu mot prod FØR ACR-retag. Feiler det steget
(manglende SP-rolle, brannmur), stopper promoten før imaget flippes — så en worker
aldri peker på en analyzer som ikke er i CU. Se CU-forutsetningen i AC#4. En feilende
promote her betyr som regel at kai-terraform-prod ikke har applyet CU-Contributor-rollen
ennå (kjør den først), eller at agent-poolens egress-IP mangler i Foundry-brannmuren.
Steg 6 — Deploy api⚓︎
Kjør/godkjenn kai-api-promote til prod → /health 200.
Steg 7 — Verifiser⚓︎
| Bash | |
|---|---|
Deretter, mot ekte data:
- API returnerer ekte saker (ikke
FakeData-fixturene) på/cases. - Worker-loggen viser
ReplikaSyncogSakSeleksjonsom kjører (Success: True). - Minst én ekte sak går hele pipelinen igjennom med korrekt regelutfall → før dette i go-live-gate-tabellen over.
Feller (alle truffet under test-idriftsettelsen)⚓︎
- NAT-egress-IP i
trusted_ipsellers timer tilkoblinger ut (brannmuren dropper, avviser ikke). - Mimir/Websak
ValidateOnStart— manglende config krasjer app-en ved oppstart, før noen hosted service starter. vector:CREATE EXTENSIONkreverazure_pg_admin; bootstrap forhåndsoppretter den.- Worker trenger
CREATE ON DATABASE(TickerQticker-schema) — ligger i bootstrap. - Image/port: worker bruker aspnet-base-imaget med
EXPOSE 8080— ellers prober App Service :80 og evicter containeren i loop. - TickerQ-dashboard basic auth — sett
Kai:TickerQ:Dashboard:Username/Passwordi prod for å unngå et uautentisert dashboard (logges som warning). - Foundry-brannmur = NAT-IP OG v2-subnett-VNet-regel.
aif-kai-prodhardefault_action=Deny. Workeren når CU via NAT-egress-IP-en (ip_rules), MEN et subnett medMicrosoft.CognitiveServices-service-endpoint treffer kontoen som en VNet-regel, ikke via den offentlige IP-en — såsnet-kai-platform-prod-appmå ligge i Foundry-kontoensvirtual_network_rules. Bare NAT-IP-en →ExtractDocument403 «Virtual Network/Firewall». - MI-token-cache ved redeploy. Managed-identity-token cacher roles-claimet. Etter en ny app-rolle-tildeling (Websak) eller RBAC-endring får MI-en først det nye claimet i et ferskt token — en redeploy/restart av app-en tvinger et nytt token. Symptom: 401 mot Websak som «magisk» forsvinner etter neste deploy.
- Regelmotor-seed kjører ved worker-oppstart.
RegelmotorSeedHostedServiceseeder regler+workflow i alle Postgres-miljøer ved boot (idempotent). Kjører Evaluation FØR seeden har landet (fersk DB, worker ikke startet ennå) →Ingen gyldig workflow for virkemiddel …. Ikke en bug igyldig_fra(seeden bruker åpent vindu2000-01-01); det er timing — reanalyser saken etter at workeren har seedet.
Avgrensning⚓︎
- Prod kjører mot Postgres. Fjerningen av den tidligere InMemory-modusen fra koden er dekket av AB#21248 og er ikke en del av denne runbooken.
- Migrering av
aif-kai-prod+ Websak-app-registreringen til kai-platform-Terraform er AB#21273 / AB#21275 (v1-avvikling). Runbooken peker på de v1-eide ressursene som de er i dag.