CI/CD-pipeline: att designa sin egen deploymentsrobot

Automatisering är inget främmande

Förra gången lärde jag mig en smärtsam läxa genom 10 minuters downtime och en incidentrapport. Deployment är inte magi, utan måste vara en följd av strikta säkerhetsmekanismer: “Git, dokumentation – Test, verifiering – Build, paketering – Deploy, leverans”.

Nu har målet blivit tydligt. Jag kan inte fortsätta kontrollera de här komplexa och irriterande säkerhetsmekanismerna med mina egna händer varje gång. Jag behöver en “flitig robot” som arbetar åt mig även efter att jag har gått hem eller när jag är på semester.

“Automatisering? Är inte det lite väl storslaget?”

Först blev jag rädd, men ju mer jag tänkte på det, desto tydligare blev det att jag redan hade upplevt något liknande. Det var “Docker”, som vi pratade om i den förra serien.

När vi skriver “installera Ubuntu, installera Java, kopiera koden” i en Dockerfile läser Docker det och bygger servermiljön på egen hand. Tack vare det blev vi befriade från det manuella slitet med att skriva kommandon för hand.

En “CI/CD-pipeline” fungerar på exakt samma sätt. Om Docker automatiserade “serveruppsättningen”, så automatiserar pipelinen “hela deploymentsprocessen”. Det enda som har förändrats är att scenen har blivit större: från min dator till en större värld som heter “GitLab och produktionsservern”.

Om Dockerfilen är monteringsmanualen för servern, så är pipelinen driftmanualen för fabriken.

CI/CD: det automatiserade transportbandet

Låt oss nu installera en “automationslinje” i vårt “digitala logistikcenter”. Det låter stort, men principen är enkel.

1. CI (Continuous Integration, kontinuerlig integration)

  • Betydelse: “Utvecklarnas kod slås hela tiden ihop till en helhet och kontrolleras.”
  • Roll: [build + test]. Det är steget där maskinen, så fort jag laddar upp kod, kontrollerar åt mig: “Är syntaxen rätt?”, “Har någon befintlig funktion gått sönder?” Defekta produkter sorteras bort här.

2. CD (Continuous Delivery/Deployment, kontinuerlig leverans/deployment)

  • Betydelse: “Kod som har klarat kontrollen levereras till kunden.”
  • Roll: [skapa image + deployment till servern]. Det är steget där den godkända, felfria produkten (Docker Image) lastas på lastbilen, skickas till produktionsservern och dessutom startas där.

Pipelinens ritning: .gitlab-ci.yml

“Så hur får man den där roboten att jobba?” I GitLab räcker det att skapa en fil som heter .gitlab-ci.yml längst upp i projektet. Det är precis den “arbetsinstruktion” som man ger till roboten.

Kommer du ihåg smärtan från den manuella deploymenten som jag gick igenom förra gången? Låt oss flytta just den processen till kod. Precis som när man skriver en Dockerfile är det bara att skriva ner allt rad för rad.

# .gitlab-ci.yml (arbetsbeskrivningen)

stages:          # 1. Definiera ordningen for hela jobbet
  - test         #   (Steg 1: kontroll)
  - build        #   (Steg 2: paketera)
  - deploy       #   (Steg 3: leverans)

# [Steg 1] Test: maskin, kolla om min kod ar ok (CI)
unit_test_job:
  stage: test
  image: openjdk:17-alpine # Kor i en miljo med Java installerat
  script:
    - ./gradlew test       # "Kor testerna!" (forhindrar tidigare misstag)

# [Steg 2] Build: om testerna gar igenom, bygg en image (CI)
build_image_job:
  stage: build
  image: docker:latest     # Kor i en miljo med Docker installerat
  script:
    - docker build -t my-app:v1 .  # "Bygg image!"
    - docker push my-regisry/my-app:v1 # "Pusha till registry!" (rollback-tagg kravs)

# [Steg 3] Deploy: lagg det pa produktionsservern (CD)
deploy_job:
  stage: deploy
  script:
    - ssh user@server "docker service update my-app" # "Uppdatera servern!"

Den här enda filen räcker. I samma ögonblick som jag gör en git push, alltså vid triggern, läser GitLab arbetsinstruktionen och väcker en arbetsrobot som heter “GitLab Runner” för att sätta den i arbete.

[Check] Säkerhetsmekanismerna vi måste ha med

I den här pipelinen finns alla tre säkerhetsmekanismer som jag så smärtsamt lärde mig förra gången inbyggda.

  1. Git (Trigger):
    • Själva handlingen att jag lokalt gör en push av koden blir pipelinens “startknapp”. Lämnas ingen historik (Commit) efter sig startar heller ingen deployment.
  2. Unit Test (Quality Gate):
    • Om testet misslyckas i unit_test_job? Då “stannar (Fail)” pipelinen omedelbart. Defekta produkter stoppas redan vid källan från att gå vidare till nästa steg (build/deployment). (Nu går det inte längre att hoppa över testerna bara för att man har bråttom!)
  3. Docker Image (Artifact):
    • Imagen som skapas i build-steget lagras säkert på Docker Hub. Även om servern skulle krascha senare kan allt återställas på en sekund, så länge den här imagen finns.
Kod som inte klarar testerna får aldrig lastas på deploymentslastbilen.

Praktiskt råd: en pipeline är en levande varelse

Försök inte skriva en perfekt pipeline från början. Jag själv skapade till en början bara två steg, build och deploy, och först efter att ha orsakat en incident lade jag till test-steget framför dem.

  • Tidigt skede: build -> deploy (huvudsaken var att överhuvudtaget få till automatiseringen)
  • Mellanskede: test -> build -> deploy (säkerhetsmekanism tillagd)
  • Vidareutvecklat: test -> statisk analys (SonarQube) -> build -> deploy till utvecklingsservern -> (godkännande) -> deploy till produktionsservern

En pipeline är ett “levande system” som fortsätter att utvecklas i takt med att vårt team växer.

Avslutningsvis: instruktionen är skriven, men vem gör egentligen jobbet?

Nu är den perfekta ritningen, .gitlab-ci.yml, klar. Men en instruktion som står på papper rör sig inte av sig själv. Precis som en Dockerfile ändå kräver att Docker Daemon är installerad för att kunna köras, behöver också pipelineinstruktionen en “robot på verkstadsgolvet” som faktiskt svettas och bygger samt kör koden.

Den här roboten heter “GitLab Runner”. Fabrikschefen, alltså GitLab Server, ger bara instruktioner. Det verkliga arbetet utförs av den här runnern.

Nästa gång installerar vi den här runnern på min dator eller på en separat server, kopplar ihop den med GitLab och kör pipelinen på riktigt. Det är äntligen ögonblicket då automatiseringens första knapp knäpps igen.

Lämna en kommentar