yq — Infrastructure

systemd Unit Files (YAML-adjacent)

systemd units are INI, not YAML — but systemd overrides and drop-ins often ship as YAML in configuration management. These patterns parse YAML inventories of systemd configurations.

Parse a service inventory
cat <<'YAML' > /tmp/services.yml
services:
  - name: vault
    unit: vault.service
    enabled: true
    port: 8200
  - name: consul
    unit: consul.service
    enabled: true
    port: 8500
  - name: nomad
    unit: nomad.service
    enabled: false
    port: 4646
YAML
yq -r '.services[] | select(.enabled == true) | "\(.name): \(.unit) (port \(.port))"' /tmp/services.yml
# Output:
# vault: vault.service (port 8200)
# consul: consul.service (port 8500)
Generate systemctl commands from inventory
cat <<'YAML' > /tmp/services.yml
services:
  - name: vault
    unit: vault.service
    enabled: true
  - name: nomad
    unit: nomad.service
    enabled: false
YAML
yq -r '.services[] | select(.enabled == true) | "sudo systemctl enable --now \(.unit)"' /tmp/services.yml
# Output:
# sudo systemctl enable --now vault.service

Docker Compose

List all services in a compose file
cat <<'YAML' > /tmp/docker-compose.yml
version: "3.8"
services:
  kroki:
    image: yuzutech/kroki
    ports:
      - "8000:8000"
    environment:
      KROKI_SAFE_MODE: unsafe
  kroki-mermaid:
    image: yuzutech/kroki-mermaid
    expose:
      - "8002"
YAML
yq -r '.services | keys | .[]' /tmp/docker-compose.yml
# Output:
# kroki
# kroki-mermaid
Extract image names and tags
cat <<'YAML' > /tmp/docker-compose.yml
version: "3.8"
services:
  kroki:
    image: yuzutech/kroki
  kroki-mermaid:
    image: yuzutech/kroki-mermaid
  kroki-bpmn:
    image: yuzutech/kroki-bpmn
YAML
yq -r '.services | to_entries[] | "\(.key): \(.value.image)"' /tmp/docker-compose.yml
# Output:
# kroki: yuzutech/kroki
# kroki-mermaid: yuzutech/kroki-mermaid
# kroki-bpmn: yuzutech/kroki-bpmn
Find services exposing specific ports
cat <<'YAML' > /tmp/docker-compose.yml
version: "3.8"
services:
  web:
    image: nginx
    ports:
      - "80:80"
      - "443:443"
  api:
    image: api-server
    ports:
      - "8080:8080"
  db:
    image: postgres
    expose:
      - "5432"
YAML
yq -r '.services | to_entries[] | select(.value.ports != null) | "\(.key): \(.value.ports[])"' /tmp/docker-compose.yml
# Output:
# web: 80:80
# web: 443:443
# api: 8080:8080
List environment variables across all services
cat <<'YAML' > /tmp/docker-compose.yml
version: "3.8"
services:
  app:
    image: myapp
    environment:
      DB_HOST: db
      DB_PORT: "5432"
      LOG_LEVEL: info
  db:
    image: postgres
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: admin
YAML
yq -r '.services | to_entries[] | .key as $svc | .value.environment // {} | to_entries[] | "\($svc): \(.key)=\(.value)"' /tmp/docker-compose.yml
# Output:
# app: DB_HOST=db
# app: DB_PORT=5432
# app: LOG_LEVEL=info
# db: POSTGRES_DB=mydb
# db: POSTGRES_USER=admin

Kubernetes Manifests

Extract metadata from a deployment
cat <<'YAML' > /tmp/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: monad-api
  namespace: monad
  labels:
    app: monad
    tier: backend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: monad
YAML
yq '{name: .metadata.name, namespace: .metadata.namespace, replicas: .spec.replicas}' /tmp/deployment.yml
# Output:
# name: monad-api
# namespace: monad
# replicas: 3
List container images in a pod spec
cat <<'YAML' > /tmp/pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: debug-pod
spec:
  containers:
    - name: app
      image: myapp:v1.2.3
      ports:
        - containerPort: 8080
    - name: sidecar
      image: envoyproxy/envoy:v1.28
      ports:
        - containerPort: 9901
YAML
yq -r '.spec.containers[] | "\(.name): \(.image)"' /tmp/pod.yml
# Output:
# app: myapp:v1.2.3
# sidecar: envoyproxy/envoy:v1.28
Decode a Kubernetes secret value
cat <<'YAML' > /tmp/secret.yml
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  username: YWRtaW4=
  password: cDRzc3cwcmQ=
YAML
yq -r '.data.username | @base64d' /tmp/secret.yml
# Output: admin

Kubernetes secrets store values in base64. yq’s @base64d decodes inline — no need for a separate base64 -d command.

Helm Values

Override specific Helm values
cat <<'YAML' > /tmp/values.yml
replicaCount: 1
image:
  repository: nginx
  tag: "1.25"
  pullPolicy: IfNotPresent
service:
  type: ClusterIP
  port: 80
ingress:
  enabled: false
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
YAML
yq -i '.replicaCount = 3 | .service.type = "LoadBalancer" | .ingress.enabled = true' /tmp/values.yml
yq '{replicas: .replicaCount, svcType: .service.type, ingress: .ingress.enabled}' /tmp/values.yml
# Output:
# replicas: 3
# svcType: LoadBalancer
# ingress: true
Extract all non-default values (values that are not empty/false/null)
cat <<'YAML' > /tmp/values.yml
replicaCount: 3
image:
  repository: nginx
  tag: "1.25"
resources: {}
nodeSelector: {}
tolerations: []
affinity: {}
YAML
yq 'with_entries(select(.value | (type == "!!map" and length > 0) or (type == "!!seq" and length > 0) or (type != "!!map" and type != "!!seq")))' /tmp/values.yml
# Output: only keys with actual values, filtering out empty maps/arrays

Cloud-Init

Parse cloud-init user data
cat <<'YAML' > /tmp/cloud-init.yml
#cloud-config
hostname: k3s-worker-01
fqdn: k3s-worker-01.inside.domusdigitalis.dev
manage_etc_hosts: true
users:
  - name: evan
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: wheel, docker
    shell: /bin/zsh
    ssh_authorized_keys:
      - ssh-ed25519 AAAA... evan@modestus-razer
packages:
  - curl
  - vim
  - htop
runcmd:
  - systemctl enable --now docker
YAML
yq -r '.users[].name' /tmp/cloud-init.yml
# Output: evan
List packages to install
cat <<'YAML' > /tmp/cloud-init.yml
#cloud-config
packages:
  - curl
  - vim
  - htop
  - jq
  - yq
YAML
yq -r '.packages[]' /tmp/cloud-init.yml
# Output:
# curl
# vim
# htop
# jq
# yq
Extract runcmd as a shell script
cat <<'YAML' > /tmp/cloud-init.yml
#cloud-config
runcmd:
  - systemctl enable --now docker
  - curl -sfL https://get.k3s.io | sh -
  - kubectl apply -f /tmp/manifests/
YAML
yq -r '.runcmd[]' /tmp/cloud-init.yml
# Output:
# systemctl enable --now docker
# curl -sfL https://get.k3s.io | sh -
# kubectl apply -f /tmp/manifests/

Each runcmd entry becomes a runnable shell command — yq extracts them for review or execution.