Back to Writing

Essay

YAML, JSON & Environment Variables in DevOps

A production-first guide to configuration formats in DevOps — why YAML dominates, where JSON fits, when ENV variables shine, and how real systems actually use all three together.

December 27, 20244 min readDevOpsYAMLJSON

Introduction

Most production outages caused by configuration are not syntax problems

they're design problems.

The issue isn't *how* to write config.

The issue is where config lives, how it's structured, and how it flows across environments.

In modern DevOps, three formats dominate configuration:

  • YAML
  • JSON
  • Environment Variables

This post explains:

  • why YAML dominates DevOps
  • how YAML, JSON, and ENV compare
  • how real production systems use all three together

No theory. Only real-world patterns.

Why YAML Dominates DevOps

YAML didn't win because it's perfect.

It won because it fits human + machine workflows better than alternatives.

Why DevOps Tools Prefer YAML

YAML is:

  • human-readable
  • indentation-based (structure is visible)
  • comment-friendly
  • good for hierarchical config

That makes it ideal for infrastructure and pipelines, where humans constantly review configs.

Where You See YAML in Real Life

  • CI/CD pipelines (GitHub Actions, GitLab CI)
  • Kubernetes manifests
  • Helm charts
  • Ansible playbooks
  • Docker Compose

These are reviewed more than they're written, and YAML optimizes for that.

Example: CI/CD Pipeline (YAML)

stages:
  - build
  - test
  - deploy

deploy:
  stage: deploy
  script:
    - docker build -t app:${CI_COMMIT_SHA} .
    - docker push app:${CI_COMMIT_SHA}

This reads like a plan — not a data structure.

That's YAML's superpower.

JSON vs YAML vs Environment Variables

These formats are not competitors.

They solve different configuration problems.

1. YAML – Declarative & Structured

Best for:

  • Infrastructure definitions
  • Pipelines
  • Declarative systems

Strengths:

  • Easy to scan visually
  • Supports nesting naturally
  • Supports comments

Weaknesses:

  • Indentation-sensitive
  • Easy to break with spacing errors

2. JSON – Strict & Machine-Oriented

Best for:

  • APIs
  • Structured data exchange
  • Programmatic configs

Strengths:

  • Strict schema
  • Easy for machines to parse
  • No ambiguity

Weaknesses:

  • Verbose
  • No comments
  • Harder to read for humans

Example: App Config in JSON

{
  "database": {
    "host": "db.internal",
    "port": 5432,
    "ssl": true
  }
}

JSON shines inside applications, not infrastructure definitions.

3. Environment Variables – Runtime Overrides

Best for:

  • Secrets
  • Environment-specific values
  • Runtime configuration

Strengths:

  • Externalized from code
  • Easy to change per environment
  • Secure when handled properly

Weaknesses:

  • Flat (no structure)
  • Hard to validate
  • Easy to misconfigure

Example: ENV Variables

DATABASE_HOST=db.internal
DATABASE_PASSWORD=secret
NODE_ENV=production

Environment variables are not config files — they are overrides.

The Golden Rule of DevOps Configuration

Structure in files.

Secrets in ENV.

Data contracts in JSON.

Mature systems never rely on a single format.

Real Config Examples (Production Style)

1. CI/CD: YAML + ENV

deploy:
  script:
    - kubectl apply -f deployment.yaml
  variables:
    KUBE_NAMESPACE: production
  • YAML defines the pipeline
  • ENV injects environment-specific values

2. Docker: Dockerfile + ENV

FROM node:20
ENV NODE_ENV=production
CMD ["node", "server.js"]

Runtime values (DB URL, tokens) come from ENV, not baked images.

3. Kubernetes: YAML + ENV + Secrets

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
        - name: app
          image: app:1.2.0
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: url

This is real-world DevOps:

  • YAML → structure
  • ENV → injection
  • Secrets → security

Common Anti-Patterns to Avoid

1. Everything in ENV Variables

❌ Hundreds of ENV vars

❌ No validation

❌ No structure

ENV vars should override, not replace config.

2. Secrets Inside YAML

password: admin123

This is how breaches happen.

Rule:

  • YAML for structure
  • Secrets managers for secrets

3. JSON for Infrastructure

Possible, but painful.

{
  "containers": [
    {
      "name": "app"
    }
  ]
}

Harder to read, harder to review, harder to maintain.

How Mature Teams Use Configuration

A healthy DevOps setup looks like this:

  • YAML → infra & pipelines
  • JSON → application config & APIs
  • ENV → secrets & environment overrides
  • Same code, different config per environment
  • No manual edits on servers

Configuration becomes boring and predictable — which is exactly what you want.

Final Takeaway

YAML dominates DevOps because DevOps is human-driven automation.

But real systems don't choose one format.

They combine:

  • YAML for clarity
  • JSON for contracts
  • ENV for runtime flexibility

If your config strategy is intentional,

your deployments become boring,

your rollbacks become safe,

and your incidents become rare.

And that's the real goal of DevOps.