# Ansible

## Hva det er

Ansible er automatiseringsprogramvare med åpen kildekode som kobler seg til maskiner over SSH og
bringer hver av dem til konfigurasjonen som er beskrevet i et sett YAML-filer: hvilke
programvarepakker som er installert, hvilke brukere og filer som finnes, hvilke tjenester som
kjører, og hvordan de er satt opp. Maskinen Ansible kjøres fra, heter kontrollnoden (control node),
og maskinene den konfigurerer, er administrerte noder (managed nodes). På dem trenger du ingen
agent, fordi Ansible logger inn med operativsystemets egne påloggingsdetaljer og gjør jobben over
den forbindelsen. Filene beskriver resultatet, og Ansible finner ut på hver vert om det resultatet
allerede er på plass.

Delene har enkle navn. Et inventar (inventory) lister opp de administrerte nodene og sorterer dem i
grupper som `web` eller `db`, med variabler som gjelder en hel gruppe eller én enkelt vert. En
playbook inneholder ett eller flere play, og hvert play kobler en gruppe verter til en liste med
oppgaver (tasks). Hver oppgave kaller en modul, et lite program som vet hvordan én type ting skal
forvaltes: en programvarepakke, en fil, en tjeneste, en bruker, en brannmurregel. Prosjektets egen
dokumentasjon beskriver playbooks som et gjentakbart, gjenbrukbart og enkelt system for
konfigurasjonsstyring og utrulling til mange maskiner. En rolle samler oppgaver, maler,
standardvariabler og handlers under ett navn, så «en PostgreSQL-server» eller «en herdet SSH-daemon»
skrives én gang og brukes på hver vert som trenger den.

Et kort play viser formen:

```text
- name: Web servers serve the site
  hosts: web
  become: true
  tasks:
    - name: nginx is installed
      ansible.builtin.package:
        name: nginx
        state: present

    - name: nginx runs now and after a reboot
      ansible.builtin.service:
        name: nginx
        state: started
        enabled: true
```

Hver oppgave navngir en tilstand og ikke en handling. De fleste moduler sjekker først om tilstanden
allerede gjelder, og avslutter uten å gjøre noe hvis den gjør det, så den andre kjøringen av dette
playet på en ferdig konfigurert vert endrer ingenting og sier det. Den egenskapen, at oppgaven er
idempotent, er det som gjør det trygt å kjøre den samme playbooken mot hele flåten hver gang, i
stedet for å holde rede på hvilken vert som har fått hvilket skript.

Folk som spør om Ansible, veier det ofte mot tre naboer. Mot et skallskript er forskjellen at
skriptet lister opp steg og kjører dem på nytt enten de trengs eller ikke, mens en modul sjekker før
den handler. Mot Terraform eller Bicep er forskjellen laget: de verktøyene oppretter ressurser i
skyen, som nettverk, databaser og virtuelle maskiner, mens Ansible konfigurerer det som kjører inne
i en maskin når den først finnes. Mange team bruker ett av hver. Mot Puppet og Chef er forskjellen
modellen: de kjører som regel en agent på hver maskin som henter konfigurasjonen sin fra en sentral
server, mens Ansible dytter ut endringene fra der det blir startet, og trenger bare SSH i den andre
enden.

## Hvorfor det er viktig

En server som er satt opp for hånd, er bare så reproduserbar som hukommelsen til den som satte den
opp. Et halvt år senere kan ingen si sikkert hvorfor en parameter i systemkjernen har verdien sin,
hvilken pakke som ble låst til en bestemt versjon og hvorfor, eller hva som må skje først når
maskinen bygges på nytt. Skriver du oppsettet ned som playbooks, blir den hukommelsen til filer som
kan leses, gjennomgås i en pull request og kjøres på nytt på en fersk maskin med samme resultat.

Den skrevne formen endrer også hva avvik (drift) betyr. Når playbooken er beskrivelsen av verten,
rapporterer en kjøring i check mode mot en levende maskin hvert sted der de to er uenige. Med
flagget `--diff` viser rapporten linjene i hver fil som ville blitt endret. En flåte som konvergeres
jevnlig, holder seg nær beskrivelsen sin, og en vert som er redigert for hånd, dukker opp som en
endring neste gang playbooken kjøres.

Modellen har sine kostnader. Ansible handler bare når det kjøres, så avvik mellom to kjøringer blir
stående til den neste. Oppgavene kjører i rekkefølge, én om gangen på tvers av alle verter som
matcher, og en stor playbook mot mange maskiner er tregere enn et skript som gjør én ting. Logikk
skrevet i YAML og Jinja2-maler blir vanskelig å følge når en rolle samler mange betingelser. Og en
kjøring som stopper halvveis, etterlater vertene sine delvis endret, fordi Ansible ikke har noen
transaksjon å rulle tilbake.

## Slik ser det ut i praksis

Flere prosjekter på dette nettstedet viser hvordan et nedskrevet driftsmiljø ser ut over tid, og hva
som skal til for å holde det ærlig.

Selskapets egne verter er beskrevet i sin helhet i Ansible.
[Driftsmiljøet vokste til 19 playbooks og 34 roller](/nb/portfolio/built-the-companys-infrastructure-as-code-108/)
fordelt på 12 065 linjer YAML. En vert ligger i en nivågruppe der variablene deklarerer hvilke
roller den kjører, slik at klargjøring uten argumenter konvergerer hver vert til sin deklarerte
tilstand. At hver oppgave er idempotent, behandles som en kontrakt: en konvergert vert rapporterer
null endringer, og et play som ikke kan si det, er ikke ferdig. Fire kommandonavnerom holder løftene
fra hverandre, fra en kvalitetsport som ikke berører noen vert, til verifisering som endrer en vert
med vilje og returnerer en dom. Siden er åpen om kostnaden: hver endring tar lengre tid enn å
redigere en fil på serveren, og en konvergering som blir halvveis gjennomført, er verre enn en som
nekter.

Tilgangskontroll er et annet område der en skrevet beskrivelse lønner seg.
[Over 1 000 RBAC-regler ble konfigurert med Ansible](/nb/portfolio/enhanced-data-security-by-implementing-1-000-rbac-14/)
på tvers av utviklermiljøer, applikasjonsinstanser, PostgreSQL, MS SQL og Linux-servere, og hver
regel var knyttet til én rolle og ett system. Siden melder at risikoen for uautorisert tilgang ble
redusert med 85 %, og at oppsettstiden ble kuttet med 60 % sammenlignet med manuelle metoder.
Teamene fikk et rammeverk de raskt kunne revidere eller endre, fordi det fantes som kode.

Å holde tørrkjøringen sannferdig krevde et eget arbeid.
[Check mode ble gjort ærlig på hele plattformen](/nb/portfolio/made-ansible-check-mode-tell-the-truth-116/)
etter at en tørrkjøring i september 2026 stoppet på en assert som tok feil om verten, og rådet
operatøren til å sette et flagg som ville ha lempet på en sikkerhetssandkasse. En gjennomgang fant
seks prober som avgjorde ut fra verdier verten aldri hadde gitt. Prober som leser tilstand kjøringen
ikke har rørt, kjører nå også i check mode. Resten hoppes over med en melding som navngir hva som
gikk uverifisert, og regelen gikk inn i utviklingsveiledningen.

## Hvor det går galt

Det meste av trøbbelet med Ansible kommer av å stole mer på en rapport enn på mekanismen bak den.

**En tørrkjøring melder et rent resultat for kommandoer den aldri kjørte.** Check mode er en
simulering. Moduler som støtter den, forutsier endringen sin, og ifølge dokumentasjonen rapporterer
moduler som mangler støtte, ingenting og gjør ingenting. Modulene `command` og `shell` støtter den
bare delvis: med mindre `creates` eller `removes` er angitt, hopper de over kommandoen og
registrerer et resultat med tom utdata. En senere `when:` som leser det resultatet, avgjør ut fra en
verdi ingen har målt. En probe som bare leser verten, kan få beskjed om å kjøre likevel, og en probe
som ikke kan kjøre, bør si det:

```text
- name: Read the firewall state, even in check mode
  ansible.builtin.command: ufw status
  register: fw
  check_mode: false
  changed_when: false

- name: Say what this dry run did not verify
  ansible.builtin.debug:
    msg: "check mode: the service restart was not exercised"
  when: ansible_check_mode
```

**En kjøring stopper på den niende oppgaven med de åtte første allerede utført.** Når en oppgave
feiler på en vert, tar Ansible den verten ut av resten av kjøringen og lar det som allerede er
endret, bli stående. Sjekker som kan kjøres før noe berører en vert, hører hjemme foran
konvergeringen. Det var akkurat det som skjedde etter en endring av driftshemmelighetene i
driftsmiljøet bak dette nettstedet:
[et preflight-play validerer nå vaulten lokalt først](/nb/portfolio/added-a-preflight-play-for-secrets-117/),
med de samme oppgavefilene som den virkelige konvergeringen og på omtrent et sekund. En hemmelighet
som ikke lar seg slå opp, koster dermed en nektelse på to sekunder på en bærbar maskin i stedet for
en halvveis gjennomført endring på en levende server. Den samme siden peker på en felle: facts som
settes i løpet av et play, lever lenger enn playet, så en sjekk og en konvergering som er lenket
sammen i én kommando, kan dele en verdi sjekken burde ha lest på nytt.

**En vert ingen har rørt, melder endringer ved hver kjøring.** Modulene `command` og `shell` melder
en endring hver gang de kjører, fordi de ikke kan vite hva kommandoen faktisk gjorde. En playbook
full av dem konvergerer aldri til null, og ekte endringer drukner i støyen. Velg heller en modul som
forvalter tingen direkte, legg til `creates` eller `removes`, eller fortell Ansible med
`changed_when` når utdata betyr en endring.

**Et passord dukker opp i en logg eller i repoet.** Variabler er ren tekst til noe krypterer dem.
Ansible Vault krypterer variabelfiler eller enkeltverdier så de kan ligge i repoet, og
`no_log: true` på en oppgave holder argumentene og resultatene ute av utdataene. Kjør playbooken én
gang med høy detaljgrad i et testmiljø, og les hva den skriver ut, før du stoler på noen av delene.

## Les mer

- [Ansible Community Documentation](https://docs.ansible.com/ansible/latest/index.html)
  — prosjektets egen inngang til installasjon, begreper og hver eneste veiledning.
- [Ansible playbooks](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html)
  — play, oppgaver, moduler, kjørerekkefølge og hva det betyr i praksis at noe er idempotent.
- [Validating tasks: check mode and diff mode](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_checkmode.html)
  — hva en tørrkjøring kan og ikke kan se, og bryterne som finnes per oppgave.
- [How to build your inventory](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html)
  — verter, grupper og variablene som hører til dem.
- [Protecting sensitive data with Ansible Vault](https://docs.ansible.com/ansible/latest/vault_guide/index.html)
  — kryptering av filer og enkeltverdier som ligger ved siden av playbookene.
- [ansible.builtin.command](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html)
  — modulreferansen, med den delvise støtten for check mode.

<https://engineer.company/nb/glossary/ansible/>
