# DevOps

## Hvad det er

DevOps er en måde at organisere softwarearbejde på, hvor de, der skriver et
system, også står for, hvordan det bygges, udgives og holdes kørende, og hvor
trinene mellem at skrive kode og at køre den er automatiseret i stedet for at
blive sendt fra ét team til det næste. Navnet er sat sammen af development og
operations, altså udvikling og drift, de to grupper, det skulle bringe sammen.

NIST, det amerikanske National Institute of Standards and Technology,
definerer det som praksis, der automatiserer processerne mellem udviklings- og
driftsteams, så de kan bygge, teste og udgive software hurtigere og mere
pålideligt. Definitionen er nyttig, fordi den peger på det, der betyder noget:
processerne imellem. En virksomhed kan have fremragende udviklere og
fremragende driftsfolk og alligevel tabe dage på det sted, hvor den ene
overdrager en release til den anden.

I praksis viser DevOps sig som en håndfuld vaner, der støtter hinanden:

- **Fælles ejerskab af produktionen.** Den, der ændrer koden, ser, hvad
  ændringen gør, når den kører, gennem monitorering, logs og alarmer, og står
  til ansvar for den.
- **En automatiseret vej til release.** Build, test og udrulning kører som en
  pipeline, på samme måde hver gang, som regel oven på
  [CI](https://martinfowler.com/articles/continuousIntegration.html).
- **Infrastruktur skrevet som filer.** Servere, netværk og databaser beskrives
  i templates eller playbooks, der ligger ved siden af koden, så et miljø kan
  genopbygges i stedet for at blive husket.
- **Ét build, mange miljøer.** Det artefakt, der bestod sine tests i staging,
  er det samme, der når produktion; kun dets indstillinger er ændret.
- **Små, hyppige releases.** Hver enkelt indeholder få ændringer, så en fejl er
  let at finde og let at rulle tilbage.

DevOps er ikke et produkt og kun løst en jobtitel. Leverandører sælger
værktøjer under navnet, og virksomheder ansætter »DevOps-ingeniører«, men
hverken værktøjet eller titlen er selve tingen. En DevOps-ingeniør bygger og
passer typisk de pipelines og den infrastruktur, der lader andre udviklere
udgive på egen hånd, og det er en rolle inden for praksissen, ikke en
erstatning for den.

## Hvorfor det betyder noget

Hver overdragelse mellem teams taber noget undervejs. Udvikleren ved, hvorfor
en ændring blev lavet, og hvad den afhænger af; driftsfolkene ved, hvordan
serverne ser ud, og hvad der gik i stykker i sidste måned. Når en release
krydser fra den ene til den anden som en sag og en pakke, når begge halvdele af
den viden frem ufuldstændige, og hullerne viser sig under udrulningen, hvor de
er dyrest at finde.

[The Twelve-Factor App](https://12factor.net/), en metode til at bygge software-as-a-service-apps,
navngiver tre af de huller præcist. Der er et hul i tid, når kode skrevet i dag
først når produktion uger senere. Der er et hul i personer, når én gruppe
skriver koden og en anden udruller den. Og der er et hul i værktøjer, når en
bærbar kører én database og produktion en anden. DevOps er i høj grad et
projekt for at lukke alle tre: udrul timer efter, at koden er skrevet, lad
forfatterne selv udrulle, og hold alle miljøer så ens som muligt.

Release-størrelse er det andet argument. Googles bog om site reliability
engineering siger det ligeud: hyppige releases giver færre ændringer mellem
versionerne. En release med tre ændringer er let at ræsonnere om, når den går
galt. En release med tre hundrede er en eftersøgning.

Det tredje er det, samme bog kalder toil: arbejde knyttet til at drive en
tjeneste, som er manuelt, gentaget og muligt at automatisere, som er uden varig
værdi, og som vokser i takt med tjenesten. Et team, der genstarter en proces i
hånden hver tirsdag, fornyer certifikater efter en kalenderpåmindelse og
udvider diske, når en alarm går, bruger sin tid på arbejde, som et script ville
gøre mere pålideligt. At automatisere det arbejde er den måde, et lille team
holder trit med et voksende system på.

Sikkerhedsvejledningerne er landet på samme form.
[NIST's vejledning om DevSecOps for cloud-native applikationer](https://csrc.nist.gov/pubs/sp/800/204/c/final)
tager udgangspunkt i en pipeline med trin for build, test, pakning, udrulning
og drift, og regner infrastruktur, runtime-politikker og monitorering blandt de
slags kode, pipelinen beskriver.

## Sådan ser det ud i praksis

Siderne på dette site viser DevOps mindre som en titel end som et
ansvarsområde: den samme ingeniør designer et system, får det i produktion og
holder det der.

Hos en green energy-startup i en tidlig fase uden et infrastrukturteam
[omfattede arbejdet platform- og dataingeniørarbejde, DevOps og site reliability i to år](/da/portfolio/architected-developed-implemented-supported-infrastructure-data-processing-and-55/).
Siden siger klart, at det betød at eje produktionsmiljøet og ikke kun at
skrive softwaren: at provisionere og hærde infrastrukturen, automatisere
provisionering, monitorering og alarmering, så problemer blev opdaget og løst
hurtigt, og udrulle releases trinvist. Det er DevOps i sin mest bogstavelige
form, med udvikling og drift samlet hos én person.

På en databasepark med 10 PostgreSQL- og MS SQL Server-instanser på Ubuntu
Linux VPS blev driftssiden automatiseret stykke for stykke:
[backups med `pg_dump` og SQL Server Agent-jobs, overvågning i Prometheus og Grafana](/da/portfolio/designed-deployed-and-maintained-10-postgresql-and-ms-13/),
regelmæssig patching, UFW-firewalls, rollebaseret adgangskontrol og
dokumenteret disaster recovery. Siden melder 99,9 % oppetid på tværs af alle
ti servere og manuelt vedligeholdelsesarbejde reduceret med 50 % gennem
automatisering, hvilket er toil-argumentet målt på én databasepark.

På en Azure-platform med udviklings-, staging- og produktionsmiljøer
[blev udrulningen ejet fra ende til anden ad en fast rute](/da/portfolio/owned-end-to-end-deployments-of-the-platform-71/).
Udrulningspipelinen bygger images, Bicep-templates giver hvert miljø den samme
infrastruktur, og den konfiguration, der skifter mellem miljøerne, ligger
adskilt fra secrets. Det lader det samme byggede artefakt blive promoveret
gennem miljøerne i stedet for at blive bygget om for hvert, og siden melder
releases uden ad hoc-manuelle deploys i blandingen.

## Hvor det går galt

DevOps svigter stille, som regel ved at beholde ordforrådet og miste vanerne.

**Titlen kommer, og muren bliver stående.** Et driftsteam får et nyt navn, eller
et »DevOps-team« ansættes til at sidde mellem udviklerne og produktionen.
Releases krydser stadig en overdragelse; den har bare fået et nyt navn på den
anden side. Testen er enkel: spørg, hvem der kan udgive en ændring, og hvem der
bliver vækket, når den går i stykker. Er det forskellige personer med
forskellig viden, er praksissen ikke på plads.

**Udrulning er stadig en person med en tjekliste.** Pipelinen bygger og tester,
og så logger nogen ind på en server og kører de sidste fem trin efter
hukommelsen, en smule forskelligt hver gang. Læg også de sidste trin i
pipelinen, giv releases én rute gennem miljøerne, og behandl et manuelt push
til produktion som en hændelse, der skal forklares.

**Hvert miljø får sit eget build.** At bygge om til staging og igen til
produktion betyder, at det, der blev testet, ikke er det, der blev udgivet. En
afhængighed, der blev løst anderledes ved andet build, dukker op som en fejl,
som ingen kan genskabe. Byg én gang, mærk artefaktet med det commit, det kom
fra, og promovér netop det artefakt, med indstillingerne hentet fra miljøet:

```sh
tag="$(git rev-parse --short HEAD)"
docker build -t "registry.example.com/app:$tag" .
docker push "registry.example.com/app:$tag"
# staging og produktion kører præcis dette tag;
# kun indstillingerne, det startes med, er forskellige
docker run --env-file staging.env "registry.example.com/app:$tag"
```

**Staging glider væk fra produktion.** En indstilling ændret i hånden på én
server, en database opgraderet i produktion først, en biblioteksversion låst ét
sted og flydende et andet: hver af dem gør staging en smule mindre brugbar som
generalprøve. Beskriv infrastrukturen i templates, anvend de samme templates
overalt, og kør de samme bagvedliggende tjenester i udvikling, som produktion
kører.

**Toil vokser med systemet.** Manuelle opgaver, der tog ti minutter om ugen for
én server, tager timer for tyve. Uden et bevidst budget til at automatisere dem
ender teamet med at bruge dagene på at holde lyset tændt. Tæl det
tilbagevendende manuelle arbejde, og sæt et loft over, hvor stor en andel af
tiden det må tage.

## Læs mere

- [DevOps](https://csrc.nist.gov/glossary/term/development_operations) — NIST's
  definition med de publikationer, den er hentet fra.
- [Build, release, run](https://12factor.net/build-release-run) — hvorfor et
  build laves én gang og kombineres med konfiguration til en release.
- [Dev/prod parity](https://12factor.net/dev-prod-parity) — hullerne i tid,
  personer og værktøjer mellem udvikling og produktion, og hvordan de lukkes.
- [Config](https://12factor.net/config) — alt, der varierer mellem deploys,
  holdt ude af koden og placeret i miljøet.
- [Eliminating Toil](https://sre.google/sre-book/eliminating-toil/) — Googles
  definition af toil og argumentet for at sætte et loft over den.
- [Release Engineering](https://sre.google/sre-book/release-engineering/) —
  hermetiske builds, selvbetjente releases og politikker, som
  release-værktøjerne håndhæver.

<https://engineer.company/da/glossary/devops/>
