Pillar page

Legacy-modernisering

Inkrementel refaktorering fra monolit til mikroservices, migrering fra forældede teknologier til moderne stacks, cloud-migrering — uden nedetid for forretningen, med rollback-plan og komplet audit trail.

Hver virksomhed har et eller andet legacy-system. Nogle har flere. En regnskabsapplikation fra 2008, der på en eller anden måde stadig fungerer. Et CRM skrevet af konsulenter, som ingen længere husker. Et lager, der kører i Access. Hver af dem skal udskiftes på et tidspunkt — spørgsmålet er ikke om, men hvornår og hvordan.

Legacy-modernisering er en af de sværeste typer IT-projekter. Det kræver balance mellem tre kræfter: forretningskontinuitet (systemet skal køre hele tiden), indførelse af moderne teknologier (mikroservices, cloud, AI) og risikokontrol (hver refaktorering kan ødelægge noget, der har virket i årevis).

Hvorfor ikke bare „skrive om fra bunden"?

Fra vores erfaring er 9 ud af 10 vellykkede moderniseringer inkrementel refaktorering, ikke omskrivning. Omskrivninger er begrebsmæssigt fristende („vi starter på en frisk"), men i praksis har de tre grundlæggende problemer:

  • Usynlig forretningslogik. Det gamle system indeholder års forretningsregler — særlige betingelser for de største kunder, skattefritagelser for bestemte brancher, workarounds for regler fra 2015. Det meste er udokumenteret. En omskrivning skal genskabe alt det fra folks hukommelse eller kodeanalyse.
  • Dobbeltarbejde. Mens det nye system skrives, kræver forretningen stadig ændringer i det gamle (regler, nye kunder, små fejl). Teamet enten duplikerer arbejdet (ændringer to steder) eller fryser det gamle system (forretningsrisiko).
  • Big bang-deployment. Efter et års arbejde er det nye system „næsten klar". At skifte alle brugere over på én nat skaber en monumental risiko. Ethvert uventet problem betyder retur til det gamle system, tab af teamets moral og forretningens tillid.

Inkrementel refaktorering (typisk efter Strangler Fig-mønsteret) løser alle tre: forretningslogik opdages gradvist, én sandhedskilde pr. enhed, deployment i etaper med feature flags.

Seks moderniseringsmønstre

Hvert mønster adresserer en specifik risiko. I de fleste projekter kombinerer vi flere og vælger et mønster pr. modul.

Strangler Fig

Gradvis „indpakning" af det gamle system med nye komponenter. Den gamle kode kører stadig, men hver ny feature går til en ny mikroservice, og eksisterende moduler udskiftes ét ad gangen. Efter 12-24 måneder slukkes den gamle monolit.

Anti-corruption layer

En adapter, der beskytter ny kode mod det gamle systems særheder (ulæselige feltnavne, mærkelige datoformater, inkonsistente typer). Al „grim" logik isoleres ét sted — ny kode arbejder på en ren domænemodel.

Database-refaktorering

Mønstre fra Refactoring Databases (Ambler/Sadalage): expand-and-contract til skemamigreringer, datavalidering før fjernelse af gamle kolonner, parallel kørsel af begge skemaer under applikationsmigrering.

Branch by abstraction

Indførelse af et abstraktionslag omkring den gamle komponent, parallel implementering af den nye komponent, gradvis skift af trafik fra 0% til 100% (feature flag). Uden en „big bang"-deployment.

Shadow mode

Den nye kode kører sideløbende med den gamle — begge behandler samme requests, men kun resultater fra det gamle system når brugeren. Resultaterne sammenlignes offline. Efter bekræftet kompatibilitet (typisk 2-4 uger) skifter vi trafik til den nye kode.

Event sourcing til migrering

Vi registrerer strømmen af forretningshændelser fra det gamle system og afspiller dem i det nye. Det giver mulighed for foreløbig validering af den nye arkitektur uden produktionsrisiko og evne til at vende tilbage til enhver historisk tilstand.

Typisk moderniseringsplan

For et mellemstort system (en monolit på ~200k linjer kode, 5-10 forretningsmoduler):

  1. Måned 1: Discovery og dokumentation. Reverse engineering af arkitektur, kortlægning af afhængigheder, identifikation af datastrømme, dokumentation af forretningsprocesser med hjælp fra forretningsejere.
  2. Måned 2: Målarkitektur og pilot. Design af ny arkitektur, teknologivalg, pilot på det enkleste modul (proof of concept). Første validering af tilgangen.
  3. Måned 3-4: Udskæring af det første produktionsmodul. Strangler Fig-mønster, shadow mode i 2-3 uger, trafik-omlægning, hypercare. Første ægte forretningsværdi.
  4. Måned 5-12: Iterativ udskæring af efterfølgende moduler. Hvert i en cyklus på 4-6 uger: refaktorering → test → shadow → produktion → hypercare. Løbende procesforbedring, reduktion af tid pr. modul.
  5. Måned 12-18: Datamigrering og udfasning af monolitten. Når alle kritiske moduler er udskåret, færdiggør vi den historiske datamigrering, slukker det gamle system, arkiverer. Fejre.

Legacy-system vs. moderniseret

AspektLegacy-system (typisk)Efter modernisering
Tid til levering af en ny feature4-8 uger (høj regressionsrisiko)3-7 dage (automatiserede test minimerer risiko)
Testdækning5-15% (eller ingen)>80%, i CI/CD-pipelinen
UdviklertilgængelighedLav (forældet teknologi)Høj (populære, moderne stacks)
SikkerhedGamle biblioteker med ikke-patchede CVE'erOWASP-scanning, gitleaks, automatiserede opdateringer
SkaleringVertikal (flere ressourcer til monolitten)Horisontal (skalering af specifikke mikroservices)
ObservabilitetLogs i filer, ingen metrikkerPrometheus + Grafana + Sentry + SIEM
Compliance (GDPR, EU AI Act, ISO 27001)Krævende, dyr at dokumentereIndbygget i arkitekturen, klar til audit

Seks typiske risici — og hvordan vi håndterer dem

Risiko: Ingen test i legacy-systemet

Mitigering: Først bygger vi karakteristik-test (capture tests) — registrering af systemets nuværende adfærd baseret på produktionslogs og trafik-captures. Først derefter starter vi refaktorering med test som sikkerhedsnet.

Risiko: Viden koncentreret hos én person („truck factor 1")

Mitigering: Vidensoverførsel starter i projektets første uge. Alle møder med den person, der kender systemet, optages og transskriberes, nøgleprocesser dokumenteres, arkitekturbeslutninger begrundes. Efter projektet forstår hele teamet systemet.

Risiko: Midlertidig team-opbremsning

Mitigering: I de første 2-3 måneder vedligeholder teamet det gamle system + bygger det nye. En naturlig opbremsning i ændringshastighed. Vi mitigerer ved: prioritering af ændringer, der kun går til det nye system, frysning af lavprioriterede ændringer i den gamle codebase.

Risiko: Datamigrering

Mitigering: Hver datamigrering har tre faser: dry-run (på en produktionskopi), staging (i testmiljø med data i realskala), produktion (i et servicevindue eller inkrementelt). Rollback-plan klar inden start.

Risiko: Organisatorisk modstand

Mitigering: Kommunikation med forretningen fra dag ét: hvorfor vi moderniserer, hvad ændres for brugeren, hvad er tidsplanen, hvordan måler vi succes. Den første iteration vælges, så den hurtigt viser konkret værdi (f.eks. en ny UI eller en hurtigere rapport).

Risiko: Undervurdering af omkostninger

Mitigering: Discovery (1-2 uger) før projektprissætning. 2-3 ugers iterationer med konkrete leverancer — lettere at justere kursen end i et langt „alt på én gang"-projekt. Budget med 20-30% buffer til det uforudsete.

Ofte stillede spørgsmål

Hvad er et legacy-system?
Et legacy-system er software, der stadig kører i organisationen, men er baseret på forældet teknologi, har dyb teknisk gæld, mangler test, mangler dokumentation eller mangler den udvikler, der skrev det. Klassiske eksempler: en monolitisk PHP 5.x- eller .NET Framework 4.0-applikation, en database uden migrations, en jQuery-frontend, FTP-deployment. Det virker, men hver ændring er højrisiko og dyr.
Hvorfor modernisere, hvis systemet fungerer?
Tre hovedårsager. For det første: vedligeholdelsesomkostningen vokser eksponentielt med systemets alder — færre udviklere kender teknologien, hver ændring tager længere, hver fejl har et bredere blast radius. For det andet: sikkerhedsrisiko — gamle frameworks har ikke-patchede sårbarheder, ingen leverandørsupport, manglende overensstemmelse med GDPR/ISO 27001. For det tredje: blokerer forretningsvækst — nye krav (mobil, API, integrationer, AI) er svære eller umulige at tilføje.
Er det ikke nemmere at skrive alt om fra bunden?
Det klassiske dilemma „rewrite vs. refactor". Omskrivninger er begrebsmæssigt fristende, men i praksis tager de 2-3 gange længere end planlagt, projektet drukner under vægten af at genskabe usynlig forretningslogik, og i mellemtiden skal det gamle system stadig udvikles (dobbeltarbejde). Fra vores erfaring: 9 ud af 10 vellykkede moderniseringer er inkrementel refaktorering (Strangler Fig-mønster) — gradvis udskiftning af dele af det gamle system, mens forretningskontinuitet bevares. En omskrivning giver kun mening for meget små systemer.
Kræver modernisering nedetid for forretningen?
I langt de fleste projekter, nej. Vi bruger mønstre, der tillader udskiftning af komponenter „live": blue-green deployment, feature flags, dark launches, parallel kørsel af gammel og ny kode med resultatsammenligning (shadow mode). Korte servicevinduer kan være nødvendige for databasemigreringer med betydelige skemaændringer, men vi planlægger dem på forhånd (typisk om natten, i weekender) med en fuld rollback-plan.
Hvor lang tid tager en typisk modernisering?
Det afhænger af skala. Et enkelt monolit-modul udskåret som mikroservice: 1-2 måneder. En større modernisering (5-10 moduler, ny database, ny API): 6-12 måneder i 2-3 ugers iterationer. En fuld enterprise-monolit-transformation: 18-36 måneder, men forretningsværdi dukker op efter den første iteration — hvert udskåret modul leverer straks fordele (hurtigere ændringer, lavere risiko, bedre observabilitet).
Hvilke teknologier migrerer vi oftest fra?
Mest almindelige veje: PHP 5/7 → PHP 8 eller Python (FastAPI) eller Node.js (Express/Fastify). .NET Framework 4.x → .NET 8 eller Java/Spring Boot. Java EE (JBoss/WebSphere) → Spring Boot eller Quarkus. jQuery + monolitiske templates → React/Vue/Astro. Oracle DB → PostgreSQL (betydelige licensbesparelser). On-premise → cloud (AWS, Azure, GCP, lokal privat cloud).
Hvad med eksisterende integrationer med andre systemer?
Hver eksisterende integration kortlægges i discovery-fasen. Migreringsplanen dækker: bevarelse af eksisterende kontrakter (interne og eksterne klienter mærker ingen ændring), indførelse af versionering (v1 gammel kontrakt, v2 ny), gradvis migrering af forbrugere til v2, derefter udfasning af v1. Fuld bagudkompatibilitet under migrering.
Hvordan reducerer I forretningsrisikoen?
Fem lag: 1) inkrementalitet — vi udskifter ét modul ad gangen, ikke alt på én gang; 2) karakteristik-test — før refaktorering registrerer vi systemets nuværende adfærd (capture tests), som derefter verificerer, at intet er ødelagt; 3) feature flags — ny funktionalitet udrulles gradvist (1% af brugerne → 10% → 50% → 100%); 4) rollback-plan for hver deployment (<5 min); 5) hypercare efter udrulning (intensiv monitoring i 2-4 uger).
Hvad med systemdokumentation, der ikke findes?
Et almindeligt legacy-problem. Første projekttrin: reverse engineering af dokumentation. AI-agenter analyserer kode, databaseskema, produktionslogs og genererer: arkitekturdiagram, endpoint-liste, afhængighedskort, beskrivelser af forretningsprocesser. Denne dokumentation verificeres derefter med forretningspersoner (ser processen ud, som vi forstod den fra koden). Resultat: komplet dokumentation, før refaktorering starter, nyttig ikke kun til moderniseringsprojektet, men også til produktteamet.
Hvordan ser moderniseringsomkostningen ud sammenlignet med vedligeholdelse af det gamle system?
På kort sigt er modernisering dyrere end vedligeholdelse (investering i refaktorering + parallel vedligeholdelse af det gamle system). Break-even-punktet (hvor det nye system bliver billigere at vedligeholde end det gamle) ligger typisk efter 12-18 måneder. Derefter: det nye system koster mindre at vedligeholde (færre udviklere, mere automatisering), tillader hurtigere ændringer (kortere time-to-market), reducerer risiko (bedre observabilitet, flere test, isolerede fejl).

Lad os starte med en audit

En teknisk audit på en uge: kortlægning af den aktuelle tilstand, identifikation af de mest presserende moderniseringsområder, en faseopdelt plan med konkrete forretningsmæssige resultater i den første iteration.