Forside · Gennemgået oktober 2026 · Af John Nielsen
Mange IT-tvister drejer sig om et tidspunkt: hvad kørte i produktion, da fejlen opstod, da SLA’en blev brudt, eller da leverancen blev overtaget? Svaret findes sjældent ét sted. Pipelinen ved, hvad den forsøgte at udrulle. Miljøet ved, hvad det faktisk kører. Ind imellem ligger manuelle rettelser, tilbagerulninger og funktionsflag. En pålidelig tidslinje for udrulninger bygges derfor af flere kilder, der kontrollerer hinanden.
Om byggelogs og testresultater i pipelinen, se CI/CD-logs og testdokumentation. Denne artikel handler om udrulningerne: vejen fra et byg til et kørende system, og hvordan den dokumenteres bagefter.
Spørgsmålet, der skal besvares
Formulér spørgsmålet præcist: hvilken version af hvilken komponent kørte i hvilket miljø i hvilket tidsrum? En moderne løsning består ofte af flere tjenester, en database med skemaændringer og konfiguration, der kan ændres uden ny kode. Versionen skal derfor angives pr. komponent og helst som et commit-id eller en entydig digest, ikke kun som et versionsnummer.
Kilderne
- Pipelinens udrulningshistorik · Hvad den viser: Hvilken kørsel der udrullede hvad til hvilket miljø, og hvem der godkendte · Svaghed: Viser forsøget, ikke nødvendigvis resultatet
- Containerregister · Hvad den viser: Hvilke images der fandtes, med digest og tidspunkt · Svaghed: Tags kan flyttes til et andet image
- Orkestrering, fx Kubernetes · Hvad den viser: Revisioner af en udrulning og hvilket image hver brugte · Svaghed: Begrænset antal gamle revisioner gemmes
- Cloudplatformens aktivitetslog · Hvad den viser: Ændringer af ressourcer, konfiguration og udrulninger · Svaghed: Ofte begrænset opbevaring
- Applikationens egne logs · Hvad den viser: Versionsnummer ved opstart, build-id i svar eller logs · Svaghed: Kun hvis applikationen skriver det
- Databasens migrationshistorik · Hvad den viser: Hvilke skemaændringer der er kørt og hvornår · Svaghed: Viser databasen, ikke koden
- Funktionsflag · Hvad den viser: Hvilke funktioner der var slået til · Svaghed: Har ofte egen, separat historik
Pipelines og miljøer
GitHub har en side med repositoriets udrulningshistorik, der kan filtreres pr. miljø og viser udløsende commit, status, workflow-logs og eventuelle pull requests. GitLab viser udrulninger pr. miljø, og en tilbagerulning vælges fra miljøets liste over udrulninger. Azure Pipelines registrerer udrulninger til et miljø med pipeline og kørsel, og under hver udrulning kan ses de commits og work items, der kom ud i miljøet med netop den udrulning.
Udrulningshistorikken er bundet til pipelinens kørsler, og kørsler slettes efter platformens regler for opbevaring. I Azure DevOps sættes opbevaringen i projektets indstillinger, oprydningen køres en gang i døgnet, og slettede kørsler tager logs, artefakter og testresultater med sig. Kørsler kan markeres til at blive bevaret. Er en tvist under opsejling, bør det gøres for de relevante kørsler, eller data eksporteres via API.
Containere og Kubernetes
Et image identificeres entydigt af sin digest, en hashværdi af manifestet. Et tag som latest eller 1.4 kan derimod flyttes til et nyt image. Udrulningshistorik, der kun nævner tags, skal derfor holdes op mod registrets oplysninger om, hvilken digest tagget pegede på hvornår.
I Kubernetes viser kubectl rollout history revisionerne af en Deployment. Antallet af gamle revisioner, der gemmes, styres af .spec.revisionHistoryLimit, som ifølge Kubernetes-dokumentationen er 10 som standard. Kolonnen CHANGE-CAUSE udfyldes kun, hvis annotationen kubernetes.io/change-cause er sat. I et aktivt projekt kan den relevante revision derfor være væk efter få uger. Om sikring af klyngen i øvrigt, se containere og Kubernetes forensisk.
Applikationen og databasen
Den mest direkte kilde er ofte applikationen selv. Mange applikationer skriver versionsnummer eller build-id i loggen ved opstart, viser det på en statusside eller sender det med i svar. Opstartslinjerne giver samtidig tidspunkterne for genstarter, der kan sammenholdes med pipelinens udrulninger.
Databaser med versionerede skemaændringer har typisk en tabel over kørte migrationer, fx flyway_schema_history ved Flyway eller __EFMigrationsHistory ved Entity Framework Core. Tabellen viser, hvornår en skemaændring blev kørt, og dermed tidligst hvornår den tilhørende kodeversion kunne være i drift.
Ændringer uden om pipelinen
De vanskeligste tilfælde er ændringer, der ikke gik gennem pipelinen: en manuel rettelse direkte på en server, en konfigurationsændring i cloudportalen, en tilbagerulning udført i hast eller en database, der blev rettet med et script. Spor af den slags findes typisk i:
- cloudplatformens aktivitetslog, se Azure Activity Log
- serverens egne logs og filsystemets tidsstempler
- fjernadgangslogs og administratorers sessioner
- ticket-systemet, hvor driften har registreret indgrebet
Uoverensstemmelse mellem pipelinens historik og applikationens egne versionsspor er i sig selv et fund, der bør beskrives.
Sikring
- Eksportér udrulningshistorikken for de relevante miljøer med kørsel, commit, godkender, status og tidspunkter.
- Markér relevante kørsler til bevarelse, eller eksportér logs og artefakter, før opbevaringen udløber.
- Hent registrets oplysninger om images, tags og digests i perioden.
- Sikr orkestreringens revisioner og udrulningsbeskrivelser.
- Sikr applikationslogs med opstartslinjer og versionsoplysninger.
- Eksportér migrationstabellen og flaghistorikken.
- Hash alle eksporter, og registrér værktøj, konto og tidspunkt.
Skal hele miljøet fastfryses, fx fordi en kunde påstår fejl, se sikring af produktion ved påstået fejl.
Tidslinjen
Kilderne samles i én tidslinje pr. miljø, med en række pr. hændelse: udrulning startet, udrulning gennemført, genstart med ny version, migration kørt, flag ændret, tilbagerulning. Hver række henviser til sin kilde. Tidspunkter normaliseres til samme tidszone, og forskelle mellem kilderne for samme hændelse noteres. Hvor kilderne er uenige, angives begge, og det forklares, hvilken der vurderes som mest pålidelig og hvorfor.
Godkendelser og adgang
Mange pipelines kræver en godkendelse, før der udrulles til produktion. Godkendelsen viser, hvem der gav lov og hvornår, og den kan være afgørende i en tvist om, hvem der besluttede at sætte en bestemt version i drift. Sikr derfor godkendelsesreglerne for miljøet, som de så ud i perioden, og listen over, hvem der havde ret til at udrulle eller ændre miljøet. Har kunden og leverandøren begge haft adgang, er det særligt vigtigt at kunne skelne mellem deres handlinger.
Typiske fejl i fortolkningen
- En gennemført pipeline-kørsel tages som bevis for, at versionen kørte, selvom udrulningen kan være fejlet i miljøet eller rullet tilbage.
- Tags forveksles med entydige versioner.
- Kun én komponent undersøges, selvom fejlen lå i samspillet med en anden.
- Funktionsflag overses, så en funktion antages at have været aktiv, fordi koden var udrullet.
- Fravær af udrulninger tolkes som, at intet blev ændret, selvom ændringer kan være sket uden om pipelinen.
Hvad deployment-historikken kan og ikke kan bevise
En tidslinje bygget af flere uafhængige kilder kan med stor sikkerhed vise, hvilken version der kørte i et miljø i et bestemt tidsrum. Den kan ikke alene vise, at versionen virkede efter hensigten. Det viser overvågningsdata bedre, se monitoreringsdata som bevis. Hvad der var indeholdt i en version, dokumenteres med SBOM og byggeartefakter.
Kilder og versioner
- GitHub Docs: se udrulningshistorik
- GitLab Docs: miljøer
- Microsoft Learn: miljøer i Azure Pipelines
- Microsoft Learn: opbevaringspolitikker i Azure Pipelines
- Kubernetes: Deployments
Senest gennemgået: oktober 2026.
Næste skridt
- Ticket-systemer: ændringshistorik i Jira, ServiceNow og lignende
- SLA-målinger: hvordan tallene beregnes, og hvor de kan være forkerte
- Leverancens tilstand på overdragelsestidspunktet: sikring af miljøer og builds
Læs også: Git-historik i projekttvister: hvem leverede hvad og hvornår · Performance og kapacitet: måling, når SLA’en bestrides
→ Uvildig IT-sagkyndig med forensic-baggrund · For IT-afdelingen · Tlf. 70 13 63 23 · Digital bevissikring hos Nielco IT