English version: https://librelab.eu/a-products-farewell-to-bigtech/
🕓

Librelab har hjulpet en lille, dansk virksomhed, Meewee, med at flytte hosting af deres produkt ud af Amazon AWS og til europæiske servere.
Resultatet er:
- 100% frihed til at drifte deres produkt hvor de har lyst
- En besparelse er på hele fem sjettedele – 83%!
- Flere tekniske ressourcer til rådighed end tidligere
Det følgende er en beskrivelse af hvordan vi overordnet set greb opgaven an.
Beskrivelsen viderebringes efter aftale med Meewee, og du er velkommen til at bruge den som inspiration til hvordan du kan gribe en lignende opgave an i din organisation.
Du er naturligvis også velkommen til at kontakte os, hvis du er interesseret i at få vores bud på en strategi for, hvordan jeres web-baserede produkt kan migreres til egne servere, eller servere ejet af europæiske udbydere.
Analyse er altid et godt sted at starte:
Trin 1: Identificér bindinger
Vi startede med at analysere hvilke tætte bindinger produktet havde til AWS. Nogle af dem er svære at løsne, andre er lette, og nogle kan helt vente.
Herunder ses de AWS-specifikke komponenter der blev benyttet. Tryk på overskrifterne, eller plusset til højre for en overskrift, hvis du er interesseret i lidt flere detaljer.
Meewee benyttede DynamoDB, som er en såkaldt NoSQL-database, der i dette tilfælde blev brugt som an key-value-database. DynamoDB er billig så længe datamængderne ikke er enorme, og samtidig hurtig og stabil.
Produktet benyttede allerede det man kalder Docker-containers, som er en måde at indpakke softwareløsninger på, så det er lettere at flytte dem fra en cloud-udbyder til en anden, eller sågar til egne servere. Men specifikt benyttede produktet den AWS-variant der hedder ECS Fargate, og konfigurationen der beskriver hvordan produktet skal køre og skalere var specifik til denne variant.
ECR blev benyttet til at opbevare de skabeloner som de kørende containere skulle baseres på. Læs om hvordan vi erstattede ECR under Trin 7: Deployment.
Forskellige opgaver kørte på forskellige tidspunkter i løbet af dagen. Eksempelvis udsendelse af emails, men også andre former for oprydningsopgaver. Lambda var den AWS-service der benyttedes hertil.
Foran de kørende applikationer benyttede produktet en såkaldt Application Load Balancer, der også er AWS-specifik. De SSL/TLS-certifikater som var foran produktets services blev konfigureret i denne Load Balancer. Certifikaterne blev genereret af AWS ACM, der udsteder og fornyer disse certifikater.
Al applikationslogning og udsendelse af alarmer via e-mail, blev foretaget fra CloudWatch, der samler alle applikationslogs i et visuelt dashboard både giver overblik og detaljer.
Al brugerstyring, det vil sige adgang ikke til selve produktet, men til at administrere det i forskellige niveauer baseret på roller, blev foretaget ved hjælp af AWS IAM.
AWS SES blev benyttet til udsendelse af e-mails. For at få dette til at fungerere korrekt, krævedes specifik konfiguration af forskellige værdier i produktets DNS (Domain Name Service).
Da Meewee er et webbaseret system, der primært tilgås via en webbrowser, er det en fordel at benytte et såkaldt CDN (Content Delivery Network), der gør de statiske filer (primært HTML, CSS og JavaScript) tilgængelig så fysisk tæt på brugeren som muligt. Meewee benyttede CloudFront for at gøre de statiske filer tilgængelige i hele verden.
Den primære afhængighed der ikke var AWS-specifik, var Github, som blev benyttet til opbevaring, samarbejde om og versionering af kildekode, men også til at sikre at produktet blev testet og bygget korrekt efter ændringer, og flyttet til produktionsmiljøet via Github Actions.
Trin 2: Find alternativer
For at få flyttet Meewees produkt hurtigt ud af AWS, lød den initielle opgave på at få foretaget flytningen med ingen eller så få ændringer til produktets kode som muligt.
Vi tog naturligvis udfordringen op, og endte med at kunne flytte Meewee til en europæisk udbyder, udelukkende ved at ændre i diverse konfigurationsfiler – med andre ord uden ændringer til selve produktets kildekode.
Overskrifterne herunder vise hvad Meewee er migreret fra og til, og igen kan du trykke på overskriften for at få flere detaljer.
Hos Librelab har vi mange års god erfaring med den tyske udbyder Hetzner, der ikke kan sammenlignes med hverken AWS eller Azure hvad features angår, men som tilbyder lige nøjagtigt det man har brug for, hvis man skal hoste en løsning ved hjælp af Open Source-komponenter. Hetzner tilbyder simple tilføjelser som Load Balancers og Firewalls, og da det ofte er det som er sværest selv at konfigurere og opsætte, passede det perfekt til denne opgave.
Vi kunne også have valgt danske udbydere, men da vi havde travlt, og i forvejen kendte Hetzner, blev det vores anbefaling og Meewees endelige valg. Hetzner er samtidig en af de billigste udbydere, så vi havde en forventning om at kunne opnå en stor besparelse for Meewee.
Der tages backup af hele installationen én gang pr. time, med hvilken hele systemet kan genskabes. Data tages der ydermere backup af selvstændigt.
Skulle Meewee senere vælge en dansk udbyder, er deres produkt nu, i modsætning til tidligere, let at migrere.
NB: Librelab har i skrivende stund ingen form for kommerciel eller anden form for samarbejdsaftale med Hetzner!
Det viste sig hurtigt at det som bandt Meewee hårdest til AWS var brugen af databasen AWS DynamoDB, der er hurtig, billig og utroligt stabil. Efter noget research faldt valget på ScyllaDB som alternativ, der er en Open Source-database af tilsvarende hurtighed og stabilitet, og som med et par enkle greb kan gøres fuldt kompatibel med DynamoDB.
Eneste ulempe med ScyllaDB i forhold til DynamoDB er, at man selv skal opsætte backup af data og sikre at gendannelse fungerer som det skal. Backup og gendannelse af data foregår via simple shell-scripts.
Meewee benyttede i forvejen docker containere til kørsel af produktet under ECS Fargate. I stedet for ECS-konfigurationsfiler, valgte vi derfor at lave en Docker Compose-fil, der beskrev de enkelte services, knyttede dem sammen, og gjorde dem tilgængelige for omverdenen.
Vi besluttede at undlade at finde et alternativ til AWS ECR, da det faktisk ikke var nødvendigt i Meewees tilfælde. Mere herom senere.
Da vi valgte at benytte Linux som underliggende operativsystem til de kørende services, havde vi automatisk cron tilgængelig. Cron er utroligt simpelt og stabilt system til at afvikle opgaver efter faste intervaller. Hetzner tilbyder også cron på et mere overordnet niveau end de enkelte services. En kombination af disse to niveauer af cron kunne let erstatte Meewees tidligere brug af Lambda.
Når man har et webbaseret produkt, kommer man ikke ud over behovet for en load balancer. En load balancer sørger for at distribuere brugernes forespørgsler over de tilgængelige kørende services, og sikrer at kun services der “har det godt” bliver kaldt. Hvis en service er “syg”, fordi den eksempelvis kører på en fysisk maskine der er defekt, på grund af netværksproblemer eller fordi den er ved at genstarte efter en opdatering, sørger en load balancer for kun at sende brugernes forespørgsler videre til de “raske” services.
Ydermere konfigureres SSL/TLS-certifikater som oftest i disse load balancers. Det er disse certifikater der sikrer en krypteret forbindelse mellem serveren og brugerens webbrowser.
Hetzner tilbyder alle disse funktionaliteter, til en beskeden merpris. Load balancere er ofte et ret dyrt komponent, da det er meget kritisk. I Meewee’s tilfælde er det næsten 20% af den samlede pris for hosting, der går til load balancer, men det inkluderer så også udstedelse og fornyelse af certifikaterne.
Behovet for at undersøge logfiler er generelt meget lavt i Meewee. Det er et meget stabilt produkt, der har kørt i produktion siden 2012, og uden nedbrud i AWS siden 2016.
CloudWatch’s visuelle værktøjer er der derfor ikke behov for på den korte bane. Simpel tekst-baseret overvågning er fint, og e-mails udsendt direkte fra serveren til udvalgte modtagere når serverfejl opstår er tilstrækkeligt. De teknikere der skal kigge på og eventuelt læse en fejl, kan efterfølgende finde de relevante logfiler fra den kørende service.
De potentielt set meget komplekse opsætninger af roller og brugergrupper, der kan opsættes i AWS IAM, er der slet ikke behov for hos det lille team bag Meewee.
Linux har rigeligt med muligheder for tildeling af adgange til specifikke ressourcer og filsystemer. I forvejen har kun en yderst begrænset personkreds adgang til de kørende miljøer i Meewees produkt.
E-mails udsendt fra Meewee, udsendes stadig via AWS SES. Det er et komponent der er relativt let at udskifte, men som der dog ikke blev tid til at udskifte i første omgang.
At SES endnu ikke er udskiftet, udgør ikke et stort problem. For det første udsendes der ganske få emails fra Meewee-applikationen. Et eksempel er når en bruger ønsker at ændre sin adgangskode. For det andet indeholder disse e-mails ikke kritisk brugerinformation.
Ikke desto mindre er det dog et komponent der står til snarlig udskiftning. Når tiden kommer har vi anbefalet Meewee at benytte Hetzners mail-service, for at samle så meget som muligt ét sted.
Vi har fundet flere gode, hurtige og budgetvenlige europæiske alternativer til AWS CloudFront. Vi har valgt at pege på Bunny CDN, da den får gode anmeldelser, er hurtig, let at komme i gang med og rimeligt prissat.
Trin 3: Test lokalt
Først lavede vi en lokal version af Meewee der med en lille testdatabase kom op at køre med ScyllaDB og individuelt kørende docker-containere (uden docker compose).
Da det virkede satte vi disse services sammen med docker compose, og testede at det stadig virkede lokalt.
Trin 4: Github til egen Gitea
Vi anbefalede Meewee at skifte fra Github til egen Gitea-installation. Mange der hoster noget github-lignende selv, vælger at bruge Gitlab. Vores erfaring er dog, at Gitlab i forhold til Gitea er temmelig ressourcekrævende, og Meewees behov for de ekstra ting Gitlab kan, er på nuværende tidspunkt ikke-eksisterende.
Selve kildekoden er let at flytte ud af Github og til lignende systemer. De deployment pipelines Meewee havde liggende i Github var meget omfattende og komplekse, hvilket var årsagen til at langt de fleste var deaktiverede eller aldrig taget i brug.
Gitea har lignende “Actions” som Github, og dækker fint Meewees behov.
Trin 5: Pakketér
Meewee-produktet blev i første omgang bygget med den nye docker-compose baserede opsætning, og en simpel testdatabase, efter en manuel proces.
Én af fordelene ved at benytte ikke-proprietære komponenter er, at man let kan teste produktet på egne computere, inden man tester på en leverandørs servere.
Efter en sidste runde med ændringer til konfigurationen, virkede hele det samlede produkt med de nye komponenter lokalt.
Trin 6: Test hos udbyder
Samme pakke, som blev testet lokalt, blev efterfølgende kopieret til et testmiljø hos Hetzner, og gjort tilgængelig via midlertidige IP-adresser og DNS-navne.
Da også dette virkede efter hensigten, var det nu tid til at definere hvordan deployment af ændringer i fremtiden skulle håndteres.
Trin 7: Deployment
Tidligere benyttedes et komplekst system af Github Actions til at flytte ændringer i Meewees produkt fra Github til AWS. Dette er nu erstattet af et simpelt og pragmatisk system:
- Ændringer testes først og fremmest lokalt af udviklerne
- Når udviklerne er klar med deres ændringer, sendes de til Gitea der via Gitea Actions tester hele kodebasen inklusive de nye ændringer.
- Efterfølgende udføres integrationstests, der blandt andet starter et midlertidigt lokalt miljø og laver såkaldte “smoke tests” der blandt andet tester at en bruger kan logge ind.
- Hvis alt virker efter hensigten, merges de nye ændringer til kildekodens main branch.
- Et cron-job hos Hetzner lytter hvert 5. minut til ændringer i denne main branch. Er der ændringer hentes de, og en ny version af den pågældende service bygges på serveren (hvilket erstatter behovet for brug af ECR)
- Brugen af watchtower i docker compose opsnapper efterfølgende ændringerne, og genstarter den pågældende service når der er ændringer.
Denne simple opsætning betyder, at der kan forekomme nedetid af den service der opdateres. I praksis betyder det meget lidt, da det tager ganske få sekunder at genstarte Meewees services gennem docker.
Selvom det er et lille problem, er det dog et problem der er værd at være opmærksom på – nogle services er længere om at genstarte end andre, og i perioder med mange brugere er det ikke praktisk at have selv korte perioder med nedetid.
En løsning kan være at opdatere cron-jobbet til kun at tjekke for ændringer, hvis der er lavt load på den pågældende service. En bedre løsning vil være et at sørge for der altid kører mindst én service på den gamle version, indtil den nye service er oppe at køre, og opdatere de gamle service efterfølgende (såkaldt blue-green deployment). Man kan også vælge den “dyrere” model – Kubernetes – eller den lidt simplere Docker Swarm.
Vi har anbefalet Meewee i første omgang at kigge på serverens load inden der opdateres. Og senere kigge på Kubernetes.
Trin 8: AWS i vedligeholdelses-modus
Vi satte den kørende applikation i vedligeholdeses-modus (også kaldet read-only mode). Det betød at man som bruger kunne logge på Meewee, men ikke oprette eller opdatere data.
Dette var nødvendigt for at kunne stabilisere databasens tilstand.
Trin 9: Sæt nyt system i drift
Det nye produktionsmiljø blev startet med en tom ScyllaDB-database, klar til at modtage en kopi af data.
Trin 10: Backup & Restore
Data blev kopieret fra DynamoDB til den nye kørende ScyllaDB-produktionsdatabase.
Det nye produktionsmiljø blev derefter genstartet, og det blev tjekket at det var klar til at modtage brugeraktivitet.
Ydermere blev det sikret at der var automatisk backup af alle nye services og databaser.
Trin 11: Flyt DNS
Meewees DNS blev nu opdateret til at pege på det nye kørende produkt hos Hetzner, mens det tidligere produktionsmiljø hos AWS forblev i vedligeholdelses-modus.
Trin 12: Overvåg og monitorér
De næste 24 timer overvågede vi, sammen med Meewee, nøje det nye produktionsmiljø, og var klar til at lave ændringer i konfigurationen hvis det skulle vise sig at være nødvendigt.
I praksis tog det langt under 24 timer at migrere de aktive brugere fra AWS til Hetzner, da vi nogle dage inden havde modificeret relevante DNS-records til at udløbe efter 10 minutter. Virkningen var at langt de fleste DNS-servere rundt omkring var korrekt opdateret til det nye produktionsmiljø på under 10 minutter. I lægmandssprog betyder det, at de fleste brugere loggede på det nye produktionsmiljø i stedet for det gamle, indenfor en periode af 10 minutter efter flytningen.
⏭ Næste trin
CDN og Email
Meewee benytter stadig AWS CloudFront til CDN og AWS SES til udsendelse af e-mail. Som nævnt tidligere vil Meewee i den nærmeste fremtid skifte fra CloudFront til Bunny CDN, og fra SES til Hetzner mail-service.
Den nuværende omkostning til de to udestående services i AWS koster 1/180 af det tidligere samlede beløb, hvilket er et acceptabelt lavt niveau. Men vigtigst udfører ingen af de to services processering eller opbevaring af data.
Docker til Podman
Podman nævnes ofte som det bedre Open Source-alternativ til Docker. Vi testede Meewees nye opsætning med podman, men fik nogle fejl vi ikke var stødt på tidligere, og var på grund af tidsrammen nødt til at droppe brugen af Podman i første omgang.
Det er på Meewees ønskeliste snarest at få genbesøgt dette og fundet en løsning.
Kubernetes
For lettere at skalere og sikre oppetid, også når nogle af de tungere services opdateres, har vi anbefalet Meewee at kigge i retning af Kubernetes (K8S).
Kubernetes benytter docker, og det er relativt trivielt at migrere den nuværende opsætning til K8S.
Drift-dashboard
Den sidste ting Meewee ønsker sig i det nye miljø er et dashboard der giver dem det fulde realtids-overblik over deres produktionsmiljø, eksempelvis:
- Antal aktive brugere
- Load på services (hukommelse, processorkraft, diskplads, netværk)
- Potentielle angreb på sikkerhed
- Forældede komponenter i drift
- Underliggende operativsystemer
- Komponenter brugt af produktets kode
- Adgang til logfiler
Vores anbefaling er at basere dette dashboard på Elastics Open Source-systemer, såsom Kibana der er relativt let at hoste på egne miljøer.
🥇Resultat: Frihed, besparelse og bedre ydelse
Meewee har nu frihed til at køre deres SaaS-produkt hvor de har lyst til, uden specifikke bindinger til specifikke udbydere.
Efter at benyttet det nye produktionmiljø i 4 uger, er det tydeligt at besparelsen i kroner og øre er betydelig. For hver 1000 kroner der tidligere blev betalt til AWS, betales der nu 170 kroner til Hetzner:
Det er en massiv besparelse på hele 83%!
Læg dertil at Meewee her flere ressourcer til rådighed, i form af mere RAM, mere CPU-kraft og mere diskplads, og at deres opbygning af viden fremadrettet vil blive rettet mod åbne løsninger, fremfor leverandør-specifikke løsninger, hvilket er noget de kan få gavn af uanset hvilke leverandører de måtte vælge i fremtiden.
Hvor lang tid tog migreringen? Forberedelsen beskrevet i trin 1 til 7 blev overstået indenfor få uger, og selve den tekniske migrering beskrevet i trin 8 til 11 var overstået på under 2 timer.
Resultatet viser en tydelig og på alle parametre meningsfuld business case.
Dig og din virksomhed?
Hvis du gerne vil vide hvordan Librelab også kan hjælpe dig med at blive digitalt suveræn med dine eksisterende eller fremtidige digitale produkter, så send os en mail på 📨 hej@librelab.eu.
Vi vil med glæde invitere dig til en uforpligtende kaffe og snak om mulighederne!
Husk at du kan abonnere på nye indlæg fra vores blog!
Nyhedsbrevet udkommer hver fredag morgen, og opsamler nyhederne fra ugen der gik, så aldrig du går glip af relevante tips, tricks, nyheder og artikler fra Librelab:
📰 Tilmeld dig vores nyhedsbrev 📰.
Læs en anden lignende inspirerende historie på Pernille Tranbergs blog, dataethics.eu.
NB: Direktionen hos Librelab og Meewee er overlappende, hvilket vi ikke mener ændrer på relevansen eller gyldigheden af denne artikel.

Skriv et svar