Om du någonsin har hanterat ett Kubernetes-kluster, konfigurerat ett GitHub Actions-arbetsflöde, eller skrivit en Docker Compose-fil, har du redan skrivit YAML — troligen mycket av det. YAML är konfigurationsformatet som driver det mesta av modern DevOps-verktygslåda. Men trots att det finns överallt är det ett format som konstant överraskar folk. Jag har felsökt mer än min del av YAML-indentationsfel klockan 23 med ett blockerat driftsättning. Låt oss se till att du slipper det.

YAML står för YAML Ain't Markup Language — ja, det är ett rekursivt akronym. Det hette ursprungligen "Yet Another Markup Language" men döptes om för att betona att det är ett dataserialiserings-format, inte ett dokumentmarkeringsspråk. YAML 1.2-specifikationen är den nuvarande standarden, även om många verktyg fortfarande implementerar YAML 1.1, som har några genuint farliga skillnader som vi täcker nedan.

Grunderna: YAML-syntax i korthet

YAML använder indragning (bara mellanslag — aldrig tabbar) för att uttrycka struktur. Ett YAML-dokument är en mappning (nyckel-värde-par), en sekvens (en lista) eller ett skalärvärde (ett enstaka värde). Här är en verklig Kubernetes-liknande konfiguration som täcker alla grunderna:

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

Inga klammerparenteser, inga citattecken på de flesta strängar, inga kommatecken. För en fil som människor redigerar varje dag ger den tydligheten snabbt. Men YAML betalar för den läsbarheten med komplexitet — det händer en hel del under huven.

Skalärtyper: Strängar, tal, booleaner, null

YAML härleder typer från värdets utseende. Det är bekvämt det mesta av tiden och tyst katastrofalt i några specifika fall.

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 (används av PyYAML och många äldre verktyg) tolkas de ociterade värdena yes, no, on, off, true, false, y, n, Y, N — och deras versaler — alla som booleaner. Det betyder att ISO-landskoden NO (Norge) blir booleanen false. YAML 1.2 åtgärdade detta. Citera alltid strängar som liknar booleaner. Se Wikipedias artikel om Norge-problemet för hela bakgrunden.
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: Listor i YAML

Listor använder ett bindestreck-mellanslag-prefix. Varje objekt kan vara ett skalärvärde, en mappning eller en annan 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]

Flerlinjesträngar: Litteralt block vs. vikat

Det är här YAML går om JSON för konfigurationsfiler. Två speciella operatorer hanterar flerlinjesträngar 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

Operatorn | är det som gör GitHub Actions' flerlinjiga run:-skript läsbara. Cheat-sheetet yaml-multiline.info är det snabbaste sättet att komma ihåg vilken chomp-modifikator som gör vad. Utan dessa blockskalar skulle du skriva escapade radbrytningar i en enda sträng — vilket är vad JSON tvingar dig att göra.

Tabbar vs mellanslag — Den kardinala regeln

YAML förbjuder tabbar för indragning. Helt och hållet. Om din editor infogar ett tabb-tecken var som helst i en YAML-fils indragning kommer filen antingen att misslyckas med att parsas eller — värre — parsas felaktigt. Konfigurera din editor att använda mellanslag för .yml- och .yaml-filer. Två mellanslag är nästan universell konvention.

Det här är orsak nummer ett till kryptiska YAML-fel. En tabb ser identisk ut som mellanslag i de flesta editorer. Aktivera "visa blankstegstecken" i din editor när du felsöker YAML, eller klistra in filen i YAML-valideraren för att få ett tydligt felmeddelande som pekar på exakt raden.

Verkligt exempel: GitHub Actions-arbetsflöde

Här är ett verkligt GitHub Actions-arbetsflödesutdrag. Lägg märke till hur det flerlinjiga run:-blocket använder den litterala blockskalan och hur indragning bestämmer 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

Verkligt exempel: 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"

Parsning av YAML i Python och JavaScript

I Python är biblioteket PyYAML standardvalet. Använd alltid safe_load(), inte load() — den osäkra versionen kan köra godtycklig Python-kod från 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 är js-yaml det mest använda 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);

Sammanfattning

YAMLs indragningsbaserade syntax, stöd för kommentarer och läsbara flerlinjesträngar gör det till rätt val för konfigurationsfiler som människor skriver och underhåller. Men det kommer med verkliga fallgropar: Norge-problemet, förvirring med tabbar/mellanslag och implicit typkonvertering från YAML 1.1-parsers. Känn till reglerna, citera allt tvetydigt, konfigurera din editor att visa blanksteg, och använd en YAML-formaterare för att hålla filer konsekventa. YAML är ett kraftfullt verktyg när du förstår var det biter.