DevOps
YAML to JSON

YAML to JSON in 3 Clicks — Kubernetes, GitHub Actions, docker-compose

Kubernetes accepts JSON. So does Terraform, Pulumi, and most infrastructure APIs. Sometimes you have a YAML manifest and need the JSON equivalent — for programmatic processing, API calls, or tooling that doesn't parse YAML. Here's how to convert the most common DevOps config formats, with real examples.

April 29, 2026
8 min read
PDF Mavericks Team

Why Convert YAML to JSON?

YAML is a superset of JSON — every valid JSON document is valid YAML, but not vice versa. This means converting YAML to JSON is always lossless, provided the YAML doesn't use advanced features like anchors, multi-document streams, or binary data.

Common reasons to convert

  • kubectl apply with JSON via REST API
  • Terraform CDK and Pulumi accept JSON
  • Datadog, Grafana API payloads require JSON
  • Testing config parsing with jq
  • Language SDKs that lack YAML parsers
  • Storing configs in JSON-only databases

What gets preserved

  • All key-value pairs
  • Nested object structure
  • Arrays and lists
  • String, number, boolean types
  • Null values
  • Multi-line strings (become single-line in JSON)

Kubernetes Deployment Manifest

Kubernetes natively accepts JSON via its REST API. The kubectl apply command converts YAML to JSON internally before sending it to the API server. You can skip that step by sending JSON directly, which is useful for programmatic deployments.

YAML input (deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
  namespace: production
  labels:
    app: api-server
    version: "2.1"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-server
  template:
    metadata:
      labels:
        app: api-server
    spec:
      containers:
      - name: api
        image: myregistry/api-server:2.1
        ports:
        - containerPort: 8080
        env:
        - name: NODE_ENV
          value: production
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"

JSON output:

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": {
    "name": "api-server",
    "namespace": "production",
    "labels": {
      "app": "api-server",
      "version": "2.1"
    }
  },
  "spec": {
    "replicas": 3,
    "selector": {
      "matchLabels": {
        "app": "api-server"
      }
    },
    "template": {
      "metadata": {
        "labels": {
          "app": "api-server"
        }
      },
      "spec": {
        "containers": [
          {
            "name": "api",
            "image": "myregistry/api-server:2.1",
            "ports": [{"containerPort": 8080}],
            "env": [
              {"name": "NODE_ENV", "value": "production"}
            ],
            "resources": {
              "requests": {"memory": "256Mi", "cpu": "250m"},
              "limits": {"memory": "512Mi", "cpu": "500m"}
            }
          }
        ]
      }
    }
  }
}

To apply JSON directly via kubectl: kubectl apply -f deployment.json. Or via the API: curl -X POST -H "Content-Type: application/json" -d @deployment.json $APISERVER/apis/apps/v1/namespaces/production/deployments

GitHub Actions Workflow

GitHub Actions workflows are YAML-only in the repository, but the GitHub API exposes workflow run data and allows programmatic workflow triggering via JSON payloads. Converting a workflow to JSON is also useful for:

  • Validating workflow structure with JSON Schema
  • Parsing and modifying workflow configs programmatically
  • Auditing job dependencies across multiple workflows

YAML input (.github/workflows/ci.yml):

name: CI

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm test

JSON output:

{
  "name": "CI",
  "on": {
    "push": {"branches": ["main"]},
    "pull_request": {"branches": ["main"]}
  },
  "jobs": {
    "test": {
      "runs-on": "ubuntu-latest",
      "steps": [
        {"uses": "actions/checkout@v4"},
        {
          "name": "Setup Node.js",
          "uses": "actions/setup-node@v4",
          "with": {
            "node-version": "20",
            "cache": "npm"
          }
        },
        {"run": "npm ci"},
        {"run": "npm test"}
      ]
    }
  }
}

docker-compose.yml

Docker Compose files are YAML. Converting to JSON is useful when you want to process them with jq, generate Compose configs programmatically, or store them in configuration management systems that use JSON.

YAML input (docker-compose.yml):

version: '3.9'
services:
  app:
    image: node:20-alpine
    working_dir: /app
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: development
      DATABASE_URL: postgresql://postgres:password@db:5432/mydb
    depends_on:
      - db
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
volumes:
  postgres_data:

Paste this into our YAML to JSON converter and you'll get the equivalent JSON object with version, services, and volumes keys, all properly typed.

One thing to note: the volumes: postgres_data: (null value in YAML) becomes "postgres_data": null in JSON. This is correct behavior per the YAML spec — a key with no value maps to null.

YAML to JSON Conversion Gotchas

YAML anchors and aliases

YAML supports anchors (&anchor) and aliases (*anchor) for DRY config. These get resolved during conversion — the JSON output will contain the full repeated structure. This is correct, but means JSON configs are larger.

Numbers that look like version strings

YAML parses "3.9" as a float (3.9) unless quoted. If your docker-compose version key needs to stay as the string "3.9", ensure your YAML has it quoted or your converter handles version fields specially.

Multi-document YAML streams

YAML supports multiple documents in one file separated by ---. Standard JSON has no equivalent. Our converter processes the first document. For multi-doc YAML, split into separate files first.

YAML 1.1 boolean values

YAML 1.1 treats yes, no, on, off as booleans. YAML 1.2 does not. Most tools (Kubernetes, Compose v3) use YAML 1.1 semantics. If you have a key named "on" or value "yes", check your parser version.

CLI Tools for Batch Conversion

When you need to convert many files or integrate YAML-to-JSON into a pipeline:

Python (one-liner):

python3 -c "import sys, yaml, json; print(json.dumps(yaml.safe_load(sys.stdin), indent=2))" < deployment.yaml

yq (Go-based YAML processor):

# Install: brew install yq (macOS) or snap install yq
yq -o json deployment.yaml

# Batch convert all YAML in a directory
for f in configs/*.yaml; do
  yq -o json "$f" > "${f%.yaml}.json"
done

Node.js:

# Install: npm install -g js-yaml
node -e "
  const yaml = require('js-yaml')
  const fs = require('fs')
  const doc = yaml.load(fs.readFileSync('deployment.yaml', 'utf8'))
  console.log(JSON.stringify(doc, null, 2))
"

Convert YAML to JSON Online

Paste any Kubernetes manifest, GitHub Actions workflow, docker-compose file, or other YAML and get clean JSON output instantly. Runs in your browser — no data sent to servers.