Hvis du noen gang har administrert et Kubernetes-kluster, konfigurert en GitHub Actions-arbeidsflyt, eller skrevet en Docker Compose-fil, har du allerede skrevet YAML — sannsynligvis mye av det. YAML er konfigurasjonsformatet som driver det meste av moderne DevOps-verktøy. Men til tross for at det er overalt, er det et format som konstant overrasker folk. Jeg har feilsøkt mer enn min andel av YAML-innrykkfeil klokken 23 med en blokkert utrulling. La oss sørge for at du slipper det.

YAML står for YAML Ain't Markup Language — ja, det er et rekursivt akronym. Det het opprinnelig "Yet Another Markup Language", men ble omdøpt for å understreke at det er et dataserialiserings-format, ikke et dokumentmarkeringsspråk. YAML 1.2-spesifikasjonen er den gjeldende standarden, selv om mange verktøy fortsatt implementerer YAML 1.1, som har noen genuint farlige forskjeller vi dekker nedenfor.

Grunnlaget: YAML-syntaks i korte trekk

YAML bruker innrykk (bare mellomrom — aldri tabulatorer) for å uttrykke struktur. Et YAML-dokument er en mapping (nøkkel-verdi-par), en sekvens (en liste) eller en skalar (en enkeltverdi). Her er en virkelig Kubernetes-lignende konfigurasjon som dekker alle det vesentlige:

yaml
# This is a comment — YAML supports them, JSON does not
app:
  name: payment-service
  version: "2.1.0"         # quoted to keep it a string
  port: 8080
  debug: false
  timeout: 30.5
  tags:
    - payments
    - backend
    - critical
  database:
    host: postgres.internal
    port: 5432
    ssl: true
    password: null          # explicitly no value

Ingen krøllparenteser, ingen anførselstegn på de fleste strenger, ingen kommaer. For en fil som mennesker redigerer hver dag, summerer den klarheten seg raskt. Men YAML betaler for den lesbarheten med kompleksitet — det skjer mye under panseret.

Skalærtyper: Strenger, tall, booleanverdier, null

YAML utleder typer fra verdiens utseende. Det er praktisk det meste av tiden og stille katastrofalt i noen spesifikke tilfeller.

yaml
# Strings — quotes are optional unless value is ambiguous
name: Alice
greeting: "Hello, world"
message: 'single quotes work too'
path: /usr/local/bin           # unquoted — still a string

# Numbers
integer: 42
negative: -7
float: 3.14159
scientific: 6.022e23

# Booleans
ssl_enabled: true
verbose: false

# Null
api_key: null
legacy_field: ~               # tilde is also null in YAML
Norge-problemet: I YAML 1.1 (brukt av PyYAML og mange eldre verktøy) tolkes de unoterte verdiene yes, no, on, off, true, false, y, n, Y, N — og deres store varianter — alle som booleanverdier. Det betyr at ISO-landskoden NO (Norge) blir booleanverdien false. YAML 1.2 fikset dette. Sett alltid anførselstegn rundt strenger som ligner booleanverdier. Se Wikipedias artikkel om Norge-problemet for hele historien.
yaml
# YAML 1.1 implicit type coercion — these silently become booleans:
country: NO       # → false  (Norway Problem!)
enabled: yes      # → true
toggle: on        # → true

# The fix: always quote when there's any ambiguity
country: "NO"
enabled: "yes"
version: "1.0"    # also quote version numbers — 1.0 would be a float

Sekvenser: Lister i YAML

Lister bruker et bindestrek-mellomrom-prefiks. Hvert element kan være en skalar, en mapping eller en annen sekvens:

yaml
# Simple list
languages:
  - Python
  - Go
  - TypeScript

# List of objects (common in Kubernetes)
containers:
  - name: api
    image: my-api:latest
    port: 8080
  - name: sidecar
    image: envoy:v1.28
    port: 9901

# Inline flow style (valid YAML, less readable)
tags: [payments, backend, v2]

Flerlinjestrenger: Bokstavelig blokk vs. foldet

Det er her YAML går foran JSON for konfigurasjonsfiler. To spesielle operatorer håndterer flerlinjestrenger elegant:

yaml
# Literal block scalar (|) — preserves newlines exactly
startup_script: |
  #!/bin/bash
  set -e
  echo "Starting service..."
  npm start

# Folded scalar (>) — folds newlines into spaces (good for long descriptions)
description: >
  This service handles payment processing
  for all regions. It connects to Stripe
  and falls back to PayPal.
# Result: "This service handles payment processing for all regions. It connects to Stripe and falls back to PayPal."

# Chomp modifiers
keep_trailing: |+
  line one
  line two

strip_trailing: |-
  line one
  line two

Operatoren | er det som gjør GitHub Actions' flerlinjede run:-skript lesbare. Jukselappen yaml-multiline.info er den raskeste måten å huske hvilken chomp-modifikator som gjør hva. Uten disse blokkskalarene ville du skrive escapede linjeskift i en enkelt streng — noe JSON tvinger deg til.

Tabulatorer vs. mellomrom — Den kardinale regelen

YAML forbyr tabulatorer for innrykk. Fullstendig. Hvis editoren din setter inn et tabulatortegn hvor som helst i innrykket i en YAML-fil, vil filen enten mislykkes å analyseres eller — verre — analyseres feil. Konfigurer editoren din til å bruke mellomrom for .yml- og .yaml-filer. To mellomrom er nesten universell konvensjon.

Dette er årsak nummer én til kryptiske YAML-feil. En tabulator ser identisk ut som mellomrom i de fleste editorer. Aktiver "vis mellomromstegn" i editoren din når du feilsøker YAML, eller lim inn filen i YAML-validatoren for å få en tydelig feilmelding som peker på den nøyaktige linjen.

Virkelig eksempel: GitHub Actions-arbeidsflyt

Her er et virkelig GitHub Actions-arbeidsflyt-utdrag. Legg merke til hvordan den flerlinjede run:-blokken bruker den bokstavelige blokkskalar, og hvordan innrykk bestemmer struktur:

yaml
name: CI

on:
  push:
    branches: [main, develop]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: |
          npm run lint
          npm run test -- --coverage
          npm run build

Virkelig eksempel: Kubernetes Deployment-manifest

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-api
  namespace: production
  labels:
    app: payment-api
    version: "2.1.0"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: payment-api
  template:
    metadata:
      labels:
        app: payment-api
    spec:
      containers:
        - name: api
          image: payment-api:2.1.0
          ports:
            - containerPort: 8080
          env:
            - name: NODE_ENV
              value: production
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: password
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "512Mi"
              cpu: "500m"

Parsing av YAML i Python og JavaScript

I Python er biblioteket PyYAML standardvalget. Bruk alltid safe_load(), ikke load() — den usikre versjonen kan kjøre vilkårlig Python-kode fra en YAML-fil:

python
import yaml

# Reading a YAML config file
with open('config.yaml', 'r') as f:
    config = yaml.safe_load(f)

print(config['app']['name'])        # payment-service
print(config['app']['port'])        # 8080 (integer, not string)
print(config['app']['tags'])        # ['payments', 'backend', 'critical']

# Writing Python data to YAML
data = {
    'service': 'auth-api',
    'replicas': 2,
    'endpoints': ['/login', '/logout', '/refresh']
}
with open('output.yaml', 'w') as f:
    yaml.dump(data, f, default_flow_style=False)

I JavaScript/Node.js er js-yaml det mest brukte biblioteket:

js
import yaml from 'js-yaml';
import fs from 'fs';

// Parse YAML string
const raw = fs.readFileSync('config.yaml', 'utf8');
const config = yaml.load(raw);

console.log(config.app.name);     // payment-service
console.log(config.app.tags);     // ['payments', 'backend', 'critical']

// Dump an object to YAML string
const output = yaml.dump({
  name: 'my-service',
  port: 3000,
  tags: ['api', 'public']
});
console.log(output);

Oppsummering

YAMLs innrykksbaserte syntaks, støtte for kommentarer og lesbare flerlinjestrenger gjør det til det riktige valget for konfigurasjonsfiler som mennesker skriver og vedlikeholder. Men det kommer med virkelige fallgruver: Norge-problemet, forvirring med tabulatorer/mellomrom og implisitt typetvang fra YAML 1.1-parsere. Kjenn reglene, sett anførselstegn rundt alt tvetydig, konfigurer editoren din til å vise mellomromstegn, og bruk en YAML-formatering for å holde filer konsistente. YAML er et kraftig verktøy når du forstår hvor det biter.