Wenn Sie jemals einen Kubernetes-Cluster verwaltet, einen GitHub Actions-Workflow eingerichtet oder eine Docker Compose-Datei geschrieben haben, haben Sie bereits YAML geschrieben — wahrscheinlich jede Menge davon. YAML ist das Konfigurationsformat, das den Großteil der modernen DevOps-Tools antreibt. Aber obwohl es überall ist, ist es ein Format, das Menschen ständig überrascht. Ich habe mehr als meinen Anteil an YAML-Einrückungsfehlern um 23 Uhr debuggt, während ein Deployment blockiert war. Lassen Sie uns sicherstellen, dass Ihnen das nicht passiert.
YAML steht für YAML Ain't Markup Language — ja, es ist ein rekursives Akronym. Ursprünglich war es "Yet Another Markup Language", wurde aber umbenannt, um zu betonen, dass es ein Datenserialisierungsformat ist, keine Dokumenten-Markup-Sprache. Die YAML 1.2-Spezifikation ist der aktuelle Standard, obwohl viele Tools noch YAML 1.1 implementieren, das einige wirklich gefährliche Unterschiede hat, die wir weiter unten behandeln.
Die Grundlagen: YAML-Syntax auf einen Blick
YAML verwendet Einrückung (nur Leerzeichen — niemals Tabs), um Struktur auszudrücken. Ein YAML-Dokument ist ein Mapping (Schlüssel-Wert-Paare), eine Sequenz (eine Liste) oder ein Skalar (ein einzelner Wert). Hier ist eine echte Kubernetes-artige Konfiguration, die alle Grundlagen abdeckt:
# 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 valueKeine geschweiften Klammern, keine Anführungszeichen bei den meisten Strings, keine Kommas. Für eine Datei, die Menschen täglich bearbeiten, summiert sich diese Klarheit schnell. Aber YAML bezahlt diese Lesbarkeit mit Komplexität — unter der Haube passiert viel.
Skalartypen: Strings, Zahlen, Booleans, Null
YAML leitet Typen aus dem Erscheinungsbild des Werts ab. Das ist meistens praktisch und in einigen spezifischen Fällen still katastrophal.
# 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 YAMLyes, no, on, off, true, false,
y, n, Y, N — und ihre Großschreibvarianten —
alle als Booleans geparst. Das bedeutet, dass der ISO-Ländercode NO (Norwegen) zu Boolean
false wird. YAML 1.2 hat das behoben. Setzen Sie immer Anführungszeichen bei Strings, die wie Booleans aussehen. Siehe den
Wikipedia-Eintrag zum Norwegen-Problem
für die vollständige Hintergrundgeschichte.# 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 floatSequenzen: Listen in YAML
Listen verwenden ein Bindestrich-Leerzeichen-Präfix. Jedes Element kann ein Skalar, ein Mapping oder eine andere Sequenz sein:
# 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]Mehrzeilige Strings: Literal-Block vs. Gefalteter Block
Hier übertrifft YAML JSON bei Konfigurationsdateien. Zwei spezielle Operatoren behandeln mehrzeilige Strings elegant:
# 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 twoDer |-Operator macht die mehrzeiligen run:-Skripte von GitHub Actions
lesbar. Das yaml-multiline.info-Cheatsheet
ist der schnellste Weg, sich zu merken, welcher Chomp-Modifikator was tut. Ohne diese Block-Skalare müssten Sie
escapte Zeilenumbrüche in einen einzelnen String schreiben — was JSON von Ihnen verlangt.
Tabs vs. Leerzeichen — Die Kardinalregel
.yml- und .yaml-Dateien verwendet. Zwei Leerzeichen ist die
nahezu universelle Konvention.Dies ist die häufigste Ursache für kryptische YAML-Fehler. Ein Tab sieht in den meisten Editoren identisch wie Leerzeichen aus. Aktivieren Sie "Leerzeichen anzeigen" in Ihrem Editor beim Debuggen von YAML, oder fügen Sie Ihre Datei in den YAML-Validator ein, um eine klare Fehlermeldung zu erhalten, die auf die genaue Zeile zeigt.
Echtes Beispiel: GitHub Actions-Workflow
Hier ist ein echter GitHub Actions-Workflow-Ausschnitt. Beachten Sie, wie der mehrzeilige run:-Block
den Literal-Block-Skalar verwendet und wie Einrückung die Struktur bestimmt:
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 buildEchtes Beispiel: Kubernetes-Deployment-Manifest
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"YAML in Python und JavaScript parsen
In Python ist die PyYAML-Bibliothek
die Standardwahl. Verwenden Sie immer safe_load(), nicht load() — die unsichere Version
kann beliebigen Python-Code aus einer YAML-Datei ausführen:
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)In JavaScript/Node.js ist js-yaml die am weitesten verbreitete Bibliothek:
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);Fazit
YAMLs einrückungsbasierte Syntax, Unterstützung für Kommentare und lesbare mehrzeilige Strings machen es zur richtigen Wahl für Konfigurationsdateien, die Menschen schreiben und pflegen. Aber es hat echte Fallstricke: das Norwegen-Problem, Tab/Leerzeichen-Verwirrung und implizite Typumwandlung durch YAML 1.1-Parser. Lernen Sie die Regeln, setzen Sie alles Mehrdeutige in Anführungszeichen, konfigurieren Sie Ihren Editor so, dass er Leerzeichen anzeigt, und verwenden Sie einen YAML-Formatierer, um Dateien konsistent zu halten. YAML ist ein mächtiges Werkzeug, wenn Sie verstehen, wo es zubeißt.