Claude Code Masterkurs – KI-gestuetztes Programmieren lernen mit Anthropics Coding-Agent

. yq - YAML Processor

Tool-Lektion | 35 Minuten

yq ist ein leichtgewichtiges Command-Line-Tool zum Verarbeiten von YAML-Files, ähnlich wie jq für JSON. Es ermöglicht Querying, Filtering, Updating und Transformation von YAML-Daten direkt in de

Lernziele

. yq - YAML Processor

Berechtigung

yq ist ein leichtgewichtiges Command-Line-Tool zum Verarbeiten von YAML-Files, ähnlich wie jq für JSON. Es ermöglicht Querying, Filtering, Updating und Transformation von YAML-Daten direkt in der Shell.

Warum yq seine Berechtigung hat:

Statistiken:

🚀 Claude Code Relevanz: yq ist unverzichtbar, um YAML-Konfigurationen (Docker-Compose, K8s, CI/CD) direkt aus Claude Code Workflows heraus zu lesen, zu validieren und automatisiert zu aktualisieren.

Zwecke

Haupteinsatzgebiete:

Verwendung

Dieser Abschnitt fuehrt dich durch Installation, grundlegende Queries und fortgeschrittene YAML-Operationen mit yq.

Installation

yq kann auf allen gaengigen Plattformen installiert werden. Stelle sicher, dass du die Go-Version von mikefarah installierst, nicht die aeltere Python-Version.

macOS (Homebrew)

Die einfachste Installation auf macOS ist ueber Homebrew:

brew install yq

Ubuntu/Debian

Unter Ubuntu/Debian laedt man die Binary direkt von GitHub herunter:

wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/local/bin/yq
chmod +x /usr/local/bin/yq

Arch Linux

Auf Arch Linux ist yq als go-yq im Community-Repository verfuegbar:

pacman -S go-yq

Go Install

Wenn du Go installiert hast, kannst du yq direkt ueber go install bauen:

go install github.com/mikefarah/yq/v4@latest

Verifizierung

Pruefe nach der Installation, ob yq korrekt installiert ist und die Go-Version (mikefarah) verwendet wird:

yq --version
# Output: yq version v4.40.5

which yq
# Output: /usr/local/bin/yq

Quick Start

Die grundlegenden yq-Queries folgen einer aehnlichen Syntax wie jq. Du navigierst mit Punkt-Notation durch die YAML-Struktur.

Basis-Queries

Mit dem Punkt-Operator greifst du auf verschachtelte Werte zu, und mit eckigen Klammern auf Array-Elemente:

# File lesen
yq '.' config.yaml

# Specific Value
yq '.database.host' config.yaml

# Nested Values
yq '.server.ports[0]' config.yaml

# Multiple Values
yq '.name, .version' package.yaml

Array-Operations

yq bietet umfangreiche Array-Funktionen -- von der Laengenabfrage ueber Filterung bis zur Iteration ueber alle Elemente:

# Array-Length
yq '.items | length' data.yaml

# Select Array-Element
yq '.items[2]' data.yaml

# Alle Array-Elements
yq '.items[]' data.yaml

# Filter Array
yq '.items[] | select(.active == true)' data.yaml
⚠️ Warnung: Verwende bei In-Place-Edits (-i) immer zuerst einen Test ohne -i, um sicherzustellen, dass der Ausdruck korrekt ist. Ein fehlerhafter yq-Befehl kann die gesamte YAML-Datei zerstoeren.

Update Values

Mit dem -i Flag aenderst du Werte direkt in der Datei. Du kannst Werte setzen, neue Keys hinzufuegen oder bestehende loeschen:

# Simple Update
yq '.version = "2.0.0"' -i config.yaml

# Nested Update
yq '.database.port = 5433' -i config.yaml

# Add New Key
yq '.new_field = "value"' -i config.yaml

# Delete Key
yq 'del(.old_field)' -i config.yaml

Advanced Usage

Fortgeschrittene Techniken wie das Zusammenfuehren mehrerer Dateien, Format-Konvertierung und komplexe Filterausdruecke.

Merge YAML-Files

Das Zusammenfuehren von YAML-Dateien ist besonders nuetzlich fuer Environment-spezifische Configs, bei denen eine Basis-Config mit Overrides kombiniert wird:

# Merge two files
yq eval-all '. as $item ireduce ({}; . * $item)' file1.yaml file2.yaml

# Merge mit Priority (file2 overwrites)
yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' file1.yaml file2.yaml

# Merge Multiple
yq eval-all '. as $item ireduce ({}; . * $item)' *.yaml

Multi-Document YAML

Kubernetes-Manifeste enthalten oft mehrere YAML-Dokumente in einer Datei, getrennt durch ---. yq kann gezielt auf einzelne Dokumente zugreifen:

# Read Kubernetes Multi-Doc
yq -N '.' k8s-resources.yaml

# Select Specific Document
yq 'select(document_index == 0)' k8s-resources.yaml

# Filter by Kind
yq 'select(.kind == "Deployment")' k8s-resources.yaml

# Update Specific Document
yq '(select(.kind == "Service") | .metadata.name) = "new-service"' -i resources.yaml
🚀 Beispiel: Mit yq -o json '.' config.yaml | jq '.' kannst du YAML-Dateien in JSON konvertieren und direkt mit jq weiterverarbeiten -- ideal fuer API-Integration und Scripting.

Format-Conversion

yq kann nahtlos zwischen YAML, JSON, XML und Properties-Format konvertieren -- besonders nuetzlich bei der Integration verschiedener Systeme:

# YAML → JSON
yq -o json '.' config.yaml

# JSON → YAML
yq -P '.' config.json

# YAML → XML
yq -o xml '.' data.yaml

# YAML → Properties
yq -o props '.' application.yaml

Complex Filtering

Komplexe Filter ermoeglichen das Extrahieren und Transformieren von Daten mit Bedingungen, Map-Operationen und rekursiver Suche:

# Filter mit Conditions
yq '.items[] | select(.price < 100 and .stock > 0)' products.yaml

# Map-Operation
yq '.items[] | {name: .name, total: (.price * .quantity)}' orders.yaml

# Group-By
yq '[.items[] | group_by(.category)]' catalog.yaml

# Recursive Descent
yq '.. | select(. == "production")' config.yaml

Scripting & Loops

yq laesst sich hervorragend in Shell-Scripts einbetten, um YAML-Werte als Variablen zu extrahieren oder Batch-Updates durchzufuehren:

# Loop über Files
for file in *.yaml; do
  yq '.version = "2.0"' -i "$file"
done

# Conditional Update
if yq -e '.debug == true' config.yaml > /dev/null; then
  yq '.log_level = "debug"' -i config.yaml
fi

# Extract & Use
VERSION=$(yq '.version' chart.yaml)
echo "Deploying version: $VERSION"

Integration in Claude Code Workflows

. K8s-Config mit AI-Analysis

Kubernetes-Deployments enthalten oft hunderte Zeilen YAML-Konfiguration, in denen sich leicht Sicherheitsluecken oder Fehlkonfigurationen verstecken. Mit yq extrahierst du gezielt die relevanten Abschnitte und laesst sie von Claude analysieren. Der erste Befehl extrahiert die Container-Konfiguration aus einem Deployment und piped sie direkt an Claude fuer ein Security-Review. Der zweite Befehl sucht in allen Containern nach Environment-Variablen und prueft, ob sensible Daten wie Passwoerter oder API-Keys hartcodiert statt als Secrets referenziert sind. Stell dir vor, du hast ein Deployment mit drei Containern und moechtest sichergehen, dass keiner von ihnen ein Datenbank-Passwort im Klartext enthaelt -- diese Kombination aus yq und Claude findet solche Probleme in Sekunden.

# Extract K8s Deployment-Config
yq '.spec.template.spec.containers[0]' deployment.yaml | \
  claude "Review container config for security best practices"

# Alle Environment-Variables analysieren
yq '.spec.template.spec.containers[].env[]' deployment.yaml | \
  claude "Check for hardcoded secrets or sensitive data"

. Automated Config-Updates

Automatisierte Config-Updates sind ein Kernbestandteil moderner CI/CD-Pipelines. Mit yq kannst du Image-Tags, Resource-Limits und andere Deployment-Parameter direkt aus Skripten heraus aendern, ohne YAML-Dateien manuell zu bearbeiten. Im ersten Beispiel generiert Claude einen semantischen Versionstag, der dann direkt in das Deployment geschrieben wird. Im zweiten Beispiel empfiehlt Claude basierend auf Metriken ein passendes Memory-Limit, das ebenfalls automatisch gesetzt wird. Stell dir vor, du hast ein Release-Script, das bei jedem Merge auf main automatisch einen neuen Tag generiert und das Deployment aktualisiert -- das spart dir manuelle Arbeit und reduziert menschliche Fehler. Achte darauf, bei In-Place-Edits immer vorher ein Backup zu erstellen oder die Aenderungen in einem Git-Branch zu machen.

# Update Image-Tag via Claude
NEW_TAG=$(claude "Generate semantic version tag for production release")
yq ".spec.template.spec.containers[0].image = \"myapp:$NEW_TAG\"" -i deployment.yaml

# Update Resource-Limits basierend auf Metrics
MEMORY=$(claude "Recommend memory limit based on these metrics: ..." | jq -r '.memory')
yq ".spec.template.spec.containers[0].resources.limits.memory = \"$MEMORY\"" -i deployment.yaml

. CI/CD Pipeline-Generation

CI/CD-Pipelines muessen regelmaessig angepasst werden, wenn neue Schritte hinzukommen oder bestehende optimiert werden sollen. Mit yq kannst du Pipeline-Konfigurationen programmatisch erweitern und anschliessend von Claude optimieren lassen. In diesem Beispiel wird ein Test-Schritt zur GitLab-CI-Konfiguration hinzugefuegt, das Ergebnis an Claude zur Optimierung gepiped, und die optimierte Version als neue Datei gespeichert. Stell dir vor, du hast eine GitLab-CI-Pipeline, die langsam geworden ist und 20 Minuten dauert -- Claude kann Parallelisierung vorschlagen, unnoetige Schritte identifizieren und die Pipeline so umstrukturieren, dass sie in 8 Minuten laeuft. Das Ergebnis ist eine neue, optimierte Pipeline-Datei, die du reviewen und dann uebernehmen kannst.

# Generate GitLab-CI from Template
yq '.jobs.build.script += ["npm test"]' .gitlab-ci.yml | \
  claude "Optimize this CI pipeline for faster builds" | \
  yq -P '.' > .gitlab-ci-optimized.yml

. Config-Validation & Linting

YAML-Syntaxfehler koennen dazu fuehren, dass ein Deployment fehlschlaegt oder eine CI/CD-Pipeline nicht startet. Diese Befehle pruefen alle YAML-Dateien im Projekt auf syntaktische Korrektheit und validieren Kubernetes-Manifeste gegen Best Practices. Der erste Befehl iteriert ueber alle YAML-Dateien und meldet diejenigen mit ungueltigem YAML. Der zweite Befehl konvertiert ein Kubernetes-Deployment nach JSON und laesst es von Claude gegen Best Practices validieren. Stell dir vor, du hast 50 YAML-Dateien in deinem Projekt und ein Kollege hat versehentlich ein Tab statt Spaces in einer Datei verwendet -- dieser Batch-Check findet den Fehler sofort, bevor er in der CI/CD-Pipeline zu einem kryptischen Fehler fuehrt. Das spart dir lange Debugging-Sessions und stellt sicher, dass alle YAML-Dateien valide sind.

# Check alle YAML-Files
find . -name "*.yaml" -o -name "*.yml" | while read file; do
  yq '.' "$file" > /dev/null 2>&1 || echo "Invalid YAML: $file"
done

# Kubernetes-Schema Validation
yq '.' deployment.yaml | \
  claude "Validate this Kubernetes deployment against best practices"

Best Practices

Bewaeaehrte Praktiken fuer den sicheren und effizienten Umgang mit yq in Projekten und CI/CD-Pipelines.

. Aliase für häufige Operationen

Shell-Aliase sparen Tipparbeit bei den gaengigsten yq-Operationen:

# ~/.bashrc oder ~/.zshrc
alias yqp='yq -P'           # Pretty-print YAML
alias yqj='yq -o json'      # Convert to JSON
alias yqi='yq -i'           # In-place edit
alias yqv='yq eval'         # Eval expression
alias yqm='yq eval-all'     # Multi-file eval
💡 Tipp: Stelle sicher, dass du die Go-Version von yq (mikefarah/yq) verwendest, nicht die Python-Version. Pruefe mit yq --version | grep mikefarah. Die Syntax unterscheidet sich erheblich zwischen den Versionen.

. Validate vor Update

Bei In-Place-Edits ist es wichtig, vorher ein Backup zu erstellen. Diese Funktion sichert die Datei und stellt sie bei Fehlern automatisch wieder her:

# Function: Safe-Update
yq_update() {
  local file=$1
  local expression=$2

  # Backup
  cp "$file" "$file.backup"

  # Update
  if yq "$expression" -i "$file"; then
    echo "✓ Updated $file"
    rm "$file.backup"
  else
    echo "✗ Error updating $file, restoring backup"
    mv "$file.backup" "$file"
  fi
}

# Usage: yq_update config.yaml '.version = "2.0"'
💡 Tipp: Erstelle Aliase wie alias yqp='yq -P' und alias yqj='yq -o json' in deiner Shell-Config, um haeufige yq-Operationen drastisch zu beschleunigen.

. Schema-Validation mit JSON-Schema

Fuer Kubernetes-YAML-Dateien kannst du yq mit kubeval kombinieren, um gegen das offizielle Schema zu validieren:

# Validate Kubernetes-YAML
validate_k8s() {
  local file=$1
  yq -o json '.' "$file" | \
    kubeval --strict || \
    echo "❌ Validation failed for $file"
}

. Atomic Updates in Scripts

Mehrere Aenderungen koennen in einem einzigen yq-Aufruf zusammengefasst werden, sodass die Datei nur einmal geschrieben wird:

# Multi-Step Update mit Rollback
update_config() {
  local config="config.yaml"

  # Transaction-like
  yq eval '
    .version = "2.0" |
    .database.port = 5433 |
    .features.beta = true
  ' -i "$config"
}

. Logging bei Batch-Operations

Bei Massenaktualisierungen ist es wichtig, den Fortschritt und eventuelle Fehler zu protokollieren:

# Batch-Update mit Logging
for file in configs/*.yaml; do
  echo "Processing: $file"
  yq '.updated_at = now' -i "$file" && \
    echo "✓ Updated" || \
    echo "✗ Failed"
done | tee update.log

Beispiele

. Kubernetes: Image-Tag Update

Das Aktualisieren von Container-Image-Tags ist einer der haeufigsten Anwendungsfaelle von yq in Kubernetes-Workflows. Bei jedem Release muss der Image-Tag in den Deployment-Dateien aktualisiert werden, idealerweise automatisiert und ueber alle betroffenen Dateien hinweg. Der erste Befehl aktualisiert einen einzelnen Deployment, der zweite findet und aktualisiert alle Deployment-Dateien im gesamten Verzeichnisbaum. Der dritte Befehl fuehrt zusaetzlich eine Dry-Run-Validierung mit kubectl durch, um sicherzustellen, dass die aktualisierte Datei syntaktisch korrekt ist. Stell dir vor, du machst ein Release von v1.9.0 auf v2.0.0 und hast 5 verschiedene Deployments -- mit dem find-Befehl werden alle auf einmal aktualisiert. Das --dry-run=client-Flag am Ende stellt sicher, dass Kubernetes die Datei akzeptieren wuerde, ohne sie tatsaechlich zu deployen.

# Single Deployment
yq '.spec.template.spec.containers[0].image = "myapp:v2.0.0"' -i deployment.yaml

# Alle Deployments im Directory
find . -name "*deployment*.yaml" | xargs -I {} \
  yq '.spec.template.spec.containers[0].image = "myapp:v2.0.0"' -i {}

# Mit Validation
TAG="v2.0.0"
yq ".spec.template.spec.containers[0].image = \"myapp:$TAG\"" -i deployment.yaml
kubectl apply --dry-run=client -f deployment.yaml

. Docker-Compose: Service-Ports ändern

Port-Aenderungen in Docker-Compose-Dateien sind ein haeufiger Vorgang, etwa wenn ein Port-Konflikt mit einem anderen Service besteht oder du auf einen Standard-Port wechseln willst. Dieser Workflow zeigt, wie du den aktuellen Port ausliest, ihn aenderst und die Aenderung verifizierst. Der cut-Befehl extrahiert die Host-Port-Nummer aus dem Port-Mapping (z.B. "3000" aus "3000:80"). Nach der Aktualisierung zeigt der letzte Befehl alle konfigurierten Ports an, damit du die Aenderung ueberpruefen kannst. Stell dir vor, dein Web-Service laeuft auf Port 3000, aber ein anderer Dienst blockiert diesen Port bereits -- mit zwei Befehlen wechselst du auf Port 8080, ohne die Datei manuell zu oeffnen. Das ist besonders in Entwicklungsumgebungen nuetzlich, wo Port-Konflikte haeufig auftreten.

# Read Current Port
CURRENT_PORT=$(yq '.services.web.ports[0]' docker-compose.yml | cut -d: -f1)
echo "Current port: $CURRENT_PORT"

# Update Port
NEW_PORT=8080
yq ".services.web.ports[0] = \"$NEW_PORT:80\"" -i docker-compose.yml

# Verify
yq '.services.web.ports[]' docker-compose.yml

. Helm-Values: Environment-Specific

Helm-Charts verwenden Values-Dateien, um Konfigurationen fuer verschiedene Umgebungen zu definieren. Dieses Beispiel zeigt, wie du aus einer Basis-Values-Datei umgebungsspezifische Varianten fuer Production und Development erzeugst. Der yq eval-Befehl nimmt die Basis als Input und ueberschreibt gezielt die Werte, die sich zwischen den Umgebungen unterscheiden. In Production werden z.B. mehr Ressourcen und ein fester Versions-Tag gesetzt, waehrend in Development der Debug-Modus aktiviert und der "dev"-Tag verwendet wird. Stell dir vor, du verwaltest eine Microservice-Architektur mit 10 Services, die jeweils in 3 Umgebungen deployed werden -- ohne dieses Pattern muesstest du 30 verschiedene Values-Dateien manuell pflegen. Mit diesem Ansatz hast du 10 Basis-Dateien und erzeugst die Varianten automatisch.

# Base values.yaml
cat > values-base.yaml << EOF
image:
  repository: myapp
  tag: latest

resources:
  requests:
    memory: "128Mi"
    cpu: "100m"
EOF

# Production Override
yq eval '
  .image.tag = "v1.0.0" |
  .resources.requests.memory = "512Mi" |
  .resources.requests.cpu = "500m" |
  .replicas = 3
' values-base.yaml > values-prod.yaml

# Development Override
yq eval '
  .image.tag = "dev" |
  .debug = true
' values-base.yaml > values-dev.yaml

. GitLab-CI: Add Test-Stage

Dieser Workflow zeigt, wie du eine neue Test-Stage und den zugehoerigen Job programmatisch zu einer GitLab-CI-Konfiguration hinzufuegst. Der erste Befehl fuegt "test" zur Liste der Stages hinzu, und der zweite erstellt den vollstaendigen Test-Job mit Script und Coverage-Regex. Das ist besonders nuetzlich in Automatisierungsszenarien, wo CI/CD-Pipelines dynamisch erweitert werden muessen. Stell dir vor, du hast ein Script, das bei der Einrichtung neuer Projekte automatisch eine Standard-CI/CD-Pipeline konfiguriert -- mit yq kannst du die notwendigen Stages und Jobs hinzufuegen, ohne YAML-Templates manuell zu kopieren. Der yq -P-Befehl am Ende formatiert das Ergebnis huebsch, damit du die Aenderungen leicht ueberpruefen kannst.

# Add test stage
yq '.stages += ["test"]' -i .gitlab-ci.yml

# Add test job
yq '.test = {
  "stage": "test",
  "script": ["npm test"],
  "coverage": "/Coverage: \\d+\\.\\d+/"
}' -i .gitlab-ci.yml

# Pretty-print result
yq -P '.' .gitlab-ci.yml

. Merge Configurations

Das Zusammenfuehren von YAML-Konfigurationen ist ein Kernmuster fuer environment-spezifische Setups. Hier wird eine Basis-Config mit einer Production-Config gemerged, wobei Werte aus der Production-Config die Basis ueberschreiben. Der ireduce-Ausdruck sorgt dafuer, dass die Dateien in der angegebenen Reihenfolge gemerged werden -- die letzte Datei hat die hoechste Prioritaet. Neue Keys aus der Production-Config (wie database.url) werden hinzugefuegt, waehrend bestehende Keys (wie server.port) ueberschrieben werden. Stell dir vor, du hast eine Basis-Config mit allgemeinen Einstellungen und brauchst fuer jede Umgebung nur die Abweichungen zu definieren -- das reduziert Duplikation und macht die Konfiguration uebersichtlicher. Das Ergebnis wird in config-final.yaml geschrieben und kann mit dem letzten Befehl angezeigt werden.

# config-base.yaml
cat > config-base.yaml << EOF
app:
  name: MyApp
  version: 1.0.0
server:
  port: 3000
EOF

# config-prod.yaml
cat > config-prod.yaml << EOF
server:
  port: 8080
  host: prod.example.com
database:
  url: postgres://prod-db
EOF

# Merge (prod overwrites base)
yq eval-all '. as $item ireduce ({}; . * $item)' \
  config-base.yaml config-prod.yaml > config-final.yaml

# Result
yq '.' config-final.yaml

. Extract Environment-Variables

Environment-Variablen aus YAML-Konfigurationen zu extrahieren ist ein haeufiger Vorgang, etwa wenn du Kubernetes-ConfigMaps oder Docker-Compose-Configs in .env-Dateien umwandeln willst. Der erste Befehl extrahiert alle Key-Value-Paare aus einer ConfigMap und schreibt sie im KEY=VALUE-Format in eine .env-Datei. Der zweite Befehl macht dasselbe fuer Docker-Compose-Environment-Variablen. Der dritte Befehl erzeugt statt einer einfachen .env-Datei ein Shell-Script mit export-Statements, das du direkt sourcen kannst. Stell dir vor, du musst die Konfiguration eines Kubernetes-Services lokal testen -- statt die Variablen einzeln abzutippen, extrahierst du sie automatisch aus der ConfigMap. Das Ergebnis ist eine sofort verwendbare .env-Datei oder ein Shell-Script, das alle notwendigen Umgebungsvariablen setzt.

# From Kubernetes ConfigMap
yq '.data | to_entries | .[] | "\(.key)=\(.value)"' configmap.yaml > .env

# From Docker-Compose
yq '.services.web.environment[]' docker-compose.yml > .env

# Convert to export-statements
yq '.data | to_entries | .[] | "export \(.key)=\(.value)"' configmap.yaml > env.sh
chmod +x env.sh

. Bulk-Update mit Pattern

Bulk-Updates sind notwendig, wenn du eine Aenderung uebergreifend in vielen Dateien durchfuehren musst, z.B. bei einer Datenbank-Migration oder einem Registry-Wechsel. Der erste Befehl sucht rekursiv in allen YAML-Dateien nach einem database-Key und aktualisiert den Hostnamen. Der zweite Befehl ersetzt in allen Deployment-Dateien den alten Container-Registry-Namen durch einen neuen. Die sub()-Funktion von yq ermoeglicht dabei String-Ersetzungen innerhalb von Werten. Stell dir vor, euer Team wechselt von einer selbst-gehosteten Container-Registry zu einer Cloud-Registry -- statt 30 Deployment-Dateien manuell zu bearbeiten, erledigt dieser Befehl die Aktualisierung in Sekunden. Teste solche Bulk-Updates immer zuerst mit --diff statt -i, um die Aenderungen zu ueberpruefen, bevor du sie tatsaechlich schreibst.

# Update alle Database-Hosts
find . -name "*.yaml" | xargs -I {} \
  yq '(.. | select(has("database")) | .database.host) = "new-db-host.example.com"' -i {}

# Update alle Image-Registries
find . -name "*deployment*.yaml" | while read file; do
  yq '(.spec.template.spec.containers[].image | select(. == "*/*")) |=
    sub("old-registry", "new-registry")' -i "$file"
done

. Generate Documentation

Aus einer OpenAPI-Spezifikation im YAML-Format kannst du mit yq automatisch Dokumentation generieren, z.B. eine Markdown-Tabelle mit allen API-Endpoints. Der erste Befehl extrahiert alle Endpoint-Pfade und schreibt sie in eine Textdatei. Der zweite Befehl erzeugt eine vollstaendige Markdown-Tabelle mit Pfad, HTTP-Methode und Beschreibung. Das ist besonders nuetzlich, wenn du eine schnelle Uebersicht deiner API haben willst, ohne ein separates Dokumentations-Tool wie Swagger UI aufzusetzen. Stell dir vor, du reviewst eine neue API-Spezifikation und willst schnell alle Endpoints in einer Tabelle sehen -- dieser Befehl generiert sie direkt aus der Source-of-Truth. Das Ergebnis ist eine API.md-Datei, die du in dein Repository einchecken oder im Chat teilen kannst.

# Extract API-Endpoints from OpenAPI
yq '.paths | keys' openapi.yaml > endpoints.txt

# Generate Markdown-Table
{
  echo "| Endpoint | Method | Description |"
  echo "|----------|--------|-------------|"
  yq '.paths | to_entries | .[] |
    .key as $path |
    .value | to_entries | .[] |
    "| \($path) | \(.key | upcase) | \(.value.summary) |"' openapi.yaml
} > API.md

. Config-Diff zwischen Environments

Der Vergleich von Konfigurationen zwischen verschiedenen Umgebungen hilft dir, Abweichungen zu finden und sicherzustellen, dass Production und Development konsistent sind. Der erste Befehl normalisiert beide Dateien (sortiert die Keys) und vergleicht sie mit diff. Der zweite Befehl nutzt delta fuer eine farbige, gut lesbare Darstellung. Der dritte Befehl extrahiert nur die Zeilen, die sich unterscheiden. Stell dir vor, du hast ein Problem in Production, das in Development nicht auftritt -- mit diesem Diff siehst du sofort, welche Konfigurationswerte sich unterscheiden und kannst das Problem einkreisen. Die Key-Sortierung mit sort_keys(..) ist wichtig, damit der Diff nicht durch unterschiedliche Reihenfolgen verfaelscht wird.

# Compare prod vs dev
diff \
  <(yq -P 'sort_keys(..)' config-prod.yaml) \
  <(yq -P 'sort_keys(..)' config-dev.yaml)

# Oder mit delta
delta \
  <(yq -P '.' config-prod.yaml) \
  <(yq -P '.' config-dev.yaml)

# Extract nur Unterschiede
comm -3 \
  <(yq -P '.' config-prod.yaml | sort) \
  <(yq -P '.' config-dev.yaml | sort)

. Secrets-Management (Redacting)

Das Redacting von Secrets aus Konfigurationsdateien ist essentiell, wenn du Config-Dateien teilen, loggen oder in Tickets einfuegen willst, ohne sensitive Daten preiszugeben. Der erste Befehl sucht nach String-Werten, die "password", "secret" oder "token" enthalten, und ersetzt sie durch "*REDACTED*". Der zweite, ausgefeiltere Ansatz nutzt walk() um rekursiv alle Objekte zu durchsuchen und Keys zu redacten, deren Name auf ein sensitives Muster passt. Stell dir vor, du musst eine Config-Datei an den Support schicken, aber sie enthaelt API-Keys und Datenbank-Passwoerter -- mit diesem Befehl erzeugst du eine sichere Kopie, in der alle Secrets maskiert sind. Das Ergebnis ist eine config-safe.yaml, die du bedenkenlos teilen kannst. Verwende immer die Key-basierte Variante (zweiter Befehl), da sie zuverlaessiger ist als die Value-basierte Suche.

# Redact Secrets from Config
yq '
  (.. | select(tag == "!!str") | select(. == "*password*" or . == "*secret*" or . == "*token*")) = "*REDACTED*"
' config.yaml > config-safe.yaml

# Or more sophisticated
yq '
  walk(
    if type == "object" then
      with_entries(
        if .key | test("password|secret|token"; "i") then
          .value = "*REDACTED*"
        else . end
      )
    else . end
  )
' config.yaml

Claude Code Integration

Workflow 1: Docker Compose analysieren

Mit diesem Befehl listest du alle Services auf, die in deiner Docker-Compose-Datei definiert sind. Das gibt dir einen schnellen Ueberblick ueber die Architektur deiner Anwendung, ohne die gesamte Datei durchlesen zu muessen. Besonders bei komplexen Multi-Service-Setups mit Datenbank, Cache, API und Frontend ist das nuetzlich, um den Ueberblick zu behalten. Stell dir vor, du uebernimmst ein neues Projekt und willst verstehen, welche Services es gibt -- mit einem einzigen Befehl siehst du alle Service-Namen. Das Ergebnis ist eine saubere Liste wie web, db, redis, worker.

yq '.services | keys' docker-compose.yml

Workflow 2: Kubernetes Manifeste bearbeiten

Dieser Befehl setzt die Anzahl der Replikas in einem Kubernetes-Deployment direkt auf 3, ohne die Datei manuell oeffnen zu muessen. Das ist besonders nuetzlich, wenn du schnell die Skalierung aendern willst, etwa weil ein Traffic-Spike bevorsteht. Mit dem -i Flag wird die Datei direkt ueberschrieben, sodass du den neuen Wert sofort committen und deployen kannst. Stell dir vor, du bekommst eine Benachrichtigung, dass die Last auf deinem Service steigt -- statt die YAML-Datei im Editor zu oeffnen, den Wert zu suchen und manuell zu aendern, genuegt dieser eine Befehl. Achte darauf, vorher yq '.spec.replicas' deployment.yaml auszufuehren, um den aktuellen Wert zu ueberpruefen.

yq '.spec.replicas = 3' -i deployment.yaml

Workflow 3: CI/CD Config validieren

Dieser Befehl zeigt dir alle definierten Jobs in einer GitHub Actions Workflow-Datei an. So siehst du auf einen Blick, welche CI/CD-Schritte konfiguriert sind, ohne die oft lange und verschachtelte YAML-Datei komplett lesen zu muessen. Das ist besonders hilfreich beim Debugging, wenn ein bestimmter Job fehlschlaegt und du pruefen willst, ob er ueberhaupt definiert ist. Stell dir vor, du fuegest einen neuen Job hinzu und willst sicherstellen, dass er korrekt in der Workflow-Datei registriert ist -- dieser Befehl gibt dir die Antwort in Sekundenbruchteilen. Das Ergebnis ist eine Liste aller Job-Namen wie build, test, deploy.

yq '.jobs | keys' .github/workflows/ci.yml
💡 Tipp: Claude Code kann yq-Befehle generieren um YAML-Configs zu transformieren, ohne die Datei manuell zu bearbeiten.

Troubleshooting

Hier findest du Loesungen fuer die haeufigsten Probleme bei der Arbeit mit yq.

Problem: yq findet File nicht

Symptom: Error: open config.yaml: no such file

yq '.version' config.yaml

Ursache: yq sucht die Datei relativ zum aktuellen Arbeitsverzeichnis. Wenn du dich nicht im richtigen Verzeichnis befindest, wird die Datei nicht gefunden.

Lösung: Path prüfen

# Check File exists
ls -la config.yaml

# Use absolute path
yq '.version' /absolute/path/to/config.yaml

# Or cd to directory
cd "$(dirname config.yaml)"
yq '.version' "$(basename config.yaml)"

Problem: Invalid YAML-Syntax

Symptom: Error: yaml: line X: mapping values are not allowed in this context

yq '.' broken.yaml

Ursache: Die YAML-Datei enthaelt Syntaxfehler wie Tabs statt Spaces, falsche Einrueckung oder fehlende Anfuehrungszeichen bei Sonderzeichen.

Lösung: Validate & Fix

# Find Syntax-Error
yq '.' broken.yaml 2>&1 | grep "line"

# Common Issues:
# - Tabs instead of spaces
# - Incorrect indentation
# - Missing quotes for special chars

# Validate all YAML
yamllint *.yaml

# Or with yq
for file in *.yaml; do
  yq '.' "$file" > /dev/null 2>&1 || echo "Invalid: $file"
done

Problem: In-Place-Edit funktioniert nicht

Symptom: File wird nicht geändert

yq '.version = "2.0"' -i config.yaml
# File unchanged

Ursache: Haeufig liegt es an fehlenden Schreibrechten oder an der falschen yq-Version (Python-yq hat eine andere Syntax als Go-yq).

Lösung: Check Permissions & Syntax

# Check File-Permissions
ls -la config.yaml

# Test without -i first
yq '.version = "2.0"' config.yaml

# Ensure correct yq version (not python-yq)
yq --version | grep "mikefarah"

# If wrong yq:
brew unlink yq
brew install yq

Problem: Complex-Expressions fehlschlagen

Symptom: Expression-Error

yq '.items[] | select(.status == "active") | .name' data.yaml
# Error: ... `

Ursache: Komplexe Ausdruecke scheitern oft an falscher Syntax, fehlenden Anfuehrungszeichen oder Versions-Unterschieden zwischen yq v3 und v4.

Lösung: Debug-Expressions

Step-by-Step

yq '.items' data.yaml # Step 1 yq '.items[]' data.yaml # Step 2 yq '.items[] | .status' data.yaml # Step 3

Use eval-explizit

yq eval '.items[] | select(.status == "active")' data.yaml

Check yq Version (v4 Syntax unterschiedlich zu v3)

yq --version


---

### Problem: Multi-Document YAML nicht erkannt

Symptom: Nur erstes Document wird verarbeitet

yq '.' multi-doc.yaml

Zeigt nur erstes ---


Ursache: Standardmaessig verarbeitet yq nur das erste Dokument in einer Multi-Document-YAML-Datei. Die weiteren Dokumente (nach ---) werden ignoriert.

Lösung: Multi-Doc Flag

Alle Documents

yq -N '.' multi-doc.yaml

Oder eval-all

yq eval-all '.' multi-doc.yaml

Select specific

yq 'select(document_index == 1)' multi-doc.yaml


---

## Vergleich: yq vs. Alternativen

| Feature | yq | jq | yj | yaml-cli |
|---------|----|----|-----|----------|
| Primary-Format | YAML | JSON | Both | YAML |
| Performance | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| Syntax | jq-like | jq | jq-like | Custom |
| Multi-Format | ✅ YAML/JSON/XML | ❌ | ✅ | ⚠️ |
| In-Place Edit | ✅ | ❌ | ✅ | ✅ |
| Multi-Document | ✅ | ❌ | ⚠️ | ✅ |
| Merge-Support | ✅ | ⚠️ Manual | ⚠️ | ✅ |
| Schema-Validation | ⚠️ External | ⚠️ External | ❌ | ⚠️ |
| Maintenance | ✅ Active | ✅ Active | ⚠️ Less | ⚠️ Less |

### Wann welches Tool?

yq:
- YAML als Primary-Format
- Kubernetes/Docker/CI-CD
- In-Place File-Editing
- Multi-Document YAML

jq:
- JSON als Primary-Format
- APIs & Web-Services
- Maximum Performance
- Complex Transformations

yj:
- Wenn YAML ↔ JSON Conversion häufig
- Legacy-Support
- Simple Use-Cases

yaml-cli:
- Simple YAML-Operations
- Wenn jq-Syntax nicht benötigt
- Lightweight-Alternative

---

## Links & Ressourcen

### Offizielle Dokumentation
- GitHub: https://github.com/mikefarah/yq
- Documentation: https://mikefarah.gitbook.io/yq/
- Usage Examples: https://github.com/mikefarah/yq#usage

### Tutorials & Guides
- yq Cookbook: https://mikefarah.gitbook.io/yq/cookbook
- Migration from v3: https://mikefarah.gitbook.io/yq/v/v3.x/upgrading-from-v3

### Tools & Integration
- yamllint: https://github.com/adrienverge/yamllint
- kubeval: https://github.com/instrumenta/kubeval
- VS Code Extension: YAML Language Support

### Cheat Sheets
- tldr yq: tldr yq
- Cheat.sh: curl cheat.sh/yq

---

## Pro-Tipps

### 1. yq in Git-Hooks

Ein Pre-Commit-Hook mit yq-Validierung verhindert, dass ungueltige YAML-Dateien ins Repository gelangen. Jedes Mal, wenn du git commit ausfuehrst, prueft dieses Script automatisch alle geaenderten YAML-Dateien auf syntaktische Korrektheit. Falls eine Datei ungueltig ist, wird der Commit blockiert und du erhaeltst eine klare Fehlermeldung mit dem Dateinamen. Stell dir vor, ein Teammitglied hat versehentlich einen Einrueckungsfehler in der Kubernetes-Konfiguration -- ohne diesen Hook wuerde der Fehler erst in der CI/CD-Pipeline oder schlimmer beim Deployment auffallen. Mit dem Hook wird der Fehler sofort beim Commit erkannt, und der Entwickler kann ihn beheben, bevor er den Code ueberhaupt pusht. Das spart dem gesamten Team Zeit und verhindert gebrochene Deployments.

.git/hooks/pre-commit

echo "Validating YAML files..." for file in $(git diff --cached --name-only | grep -E '\.(yaml|yml) ); do yq '.' "$file" > /dev/null || { echo "❌ Invalid YAML: $file" exit 1 } done

echo "✓ All YAML files valid"


### 2. Dynamic-Config per Environment

Dieses Deploy-Script merged eine Basis-Konfiguration mit einer umgebungsspezifischen Config (dev, staging, production) und deployed das Ergebnis direkt nach Kubernetes. Das ist die Grundlage fuer environment-spezifische Deployments ohne Config-Duplikation -- du hast eine gemeinsame Basis und nur die Abweichungen pro Umgebung. Der eval-all-Befehl merged die Dateien, wobei die zweite Datei die erste ueberschreibt, wo sich Werte ueberlappen. Stell dir vor, du hast eine Basis-Config mit 50 Eintraegen und brauchst fuer Production nur 5 Aenderungen (z.B. Datenbank-Host, Replika-Anzahl, Log-Level) -- statt 50 Eintraege zu duplizieren, definierst du nur die 5 Abweichungen in config-prod.yaml. Das Ergebnis wird direkt an kubectl apply uebergeben, was ein vollstaendig automatisiertes Deployment ergibt.

deploy.sh

ENVIRONMENT=${1:-dev}

yq eval-all ' select(fileIndex == 0) * select(fileIndex == 1) ' config-base.yaml config-${ENVIRONMENT}.yaml | \ kubectl apply -f -


### 3. Template-Rendering

Template-Rendering mit yq ersetzt Platzhalter in YAML-Dateien durch Werte aus Environment-Variablen. Das ist eine leichtgewichtige Alternative zu Helm oder anderen Template-Engines, wenn du einfache Variablenersetzung brauchst. Die env()-Funktion liest den Wert direkt aus der aktuellen Shell-Umgebung, sodass du sensitive Werte wie API-Keys nicht in der Template-Datei speichern musst. Stell dir vor, du hast eine Anwendungskonfiguration, die in drei Umgebungen deployed wird -- du schreibst ein Template mit Platzhaltern und setzt die Werte je nach Umgebung ueber Environment-Variablen. Das Ergebnis ist eine gerenderte YAML-Datei mit den eingesetzten Werten, die du direkt verwenden oder deployen kannst. Diese Methode ist deutlich einfacher als ein vollwertiges Templating-System und reicht fuer viele Anwendungsfaelle aus.

template.yaml mit Placeholders

cat > template.yaml << 'EOF' app: name: __APP_NAME__ version: __VERSION__ EOF

Render Template

APP_NAME="MyApp" VERSION="2.0.0" \ yq eval ' .app.name = env(APP_NAME) | .app.version = env(VERSION) ' template.yaml > rendered.yaml


### 4. Bulk-Rename Keys

Dieses Pattern benennt alle Vorkommen eines bestimmten Keys in einer YAML-Datei rekursiv um, unabhaengig von der Verschachtelungstiefe. Das ist besonders nuetzlich bei Schema-Migrationen, wenn sich ein Feldname aendert und du alle Vorkommen auf einmal aktualisieren willst. Die walk()-Funktion traversiert die gesamte YAML-Struktur, und with_entries() ermoeglicht die Manipulation einzelner Key-Value-Paare. Stell dir vor, dein API-Schema aendert sich und das Feld "name" soll ueberall zu "title" werden -- statt manuell jede Stelle zu finden und zu aendern, erledigt dieser Befehl das in einem Durchlauf. Das Ergebnis ist eine neue YAML-Datei, in der alle "name"-Keys durch "title" ersetzt wurden, waehrend der Rest der Struktur unveraendert bleibt. Teste den Befehl immer zuerst ohne -i Flag, um die Ausgabe zu ueberpruefen.

Rename all "name" to "title"

yq ' walk( if type == "object" then with_entries( if .key == "name" then .key = "title" else . end ) else . end ) ' data.yaml


### 5. Config-Backup vor Bulk-Updates

Diese Funktion erstellt vor jedem Bulk-Update automatisch ein Backup aller betroffenen Dateien in einem zeitgestempelten Verzeichnis. Das ist eine wichtige Sicherheitsmassnahme, wenn du Massenaktualisierungen an YAML-Dateien durchfuehrst -- falls etwas schiefgeht, kannst du jederzeit zum vorherigen Zustand zurueckkehren. Die Funktion nimmt ein Glob-Pattern und einen yq-Ausdruck entgegen, findet alle passenden Dateien, sichert sie und fuehrt dann das Update durch. Stell dir vor, du musst in 30 Config-Dateien den Datenbank-Host aendern -- ohne Backup riskierst du, bei einem Fehler alle Dateien kaputt zu haben. Mit dieser Funktion werden alle Originale in .backups/20260213_143022/ gesichert, und du kannst sie bei Bedarf wiederherstellen. Verwende diese Funktion besonders bei produktionskritischen Konfigurationen, wo ein Fehler direkten Einfluss auf laufende Services hat.

Safe-Bulk-Update Function

bulk_update() { local pattern=$1 local expression=$2

# Create Backup-Directory mkdir -p .backups/$(date +%Y%m%d_%H%M%S)

# Find & Update find . -name "$pattern" | while read file; do cp "$file" ".backups/$(date +%Y%m%d_%H%M%S)/" yq "$expression" -i "$file" done }

Usage: bulk_update "*.yaml" '.version = "2.0"'


---

## Zusammenfassung

yq ist ein unverzichtbares Tool für YAML-Processing in modernen DevOps-Workflows:

### Kern-Vorteile:
✅ YAML-Native: Keine JSON-Conversion nötig
✅ jq-Syntax: Vertraute Query-Language
✅ Multi-Format: YAML, JSON, XML, TOML
✅ In-Place-Edit: Direct File-Modification
✅ CI/CD-Essential: Standard in K8s/Docker/GitOps

### Typische Use Cases:
- ⎈ Kubernetes-Config Management
- 🐳 Docker-Compose Manipulation
- 🔄 CI/CD Pipeline-Configuration
- 📝 Config-File Processing
- 🔀 YAML-Merging & Transformation

### Ergänzt perfekt:
- kubectl: Kubernetes-Deployments
- jq: JSON-Processing
- helm: Chart-Values Management
- Claude Code: AI-powered Config-Analysis

### Nächste Schritte:
1. Installiere yq: brew install yq
2. Teste Basic-Queries: yq '.' config.yaml
3. Lerne jq-Syntax für Complex-Queries
4. Integriere in CI/CD-Pipelines
5. Nutze mit Claude Code für Smart-Config

Bottom Line: yq ist der Standard für YAML-Processing. Essential für K8s, Docker, CI/CD - jq für YAML-Fans.

---

Weiter zu: [19. entr - File Watcher](./19-entr.md)
Zurück zu: [17. starship - Prompt Customization](./17-starship.md)
Übersicht: [Tools & Extensions](../TOOLS-EXTENSIONS-INDEX.md)