YAML Tools
Convert between YAML and JSON, validate YAML syntax, and format YAML documents
Essential for working with configuration files, Docker Compose, Kubernetes manifests, and CI/CD pipelines. YAML's human-friendly syntax makes it perfect for settings that need to be both machine-readable and easy to edit. Our tools help you convert, validate, and work with YAML files efficiently.
What is YAML?
YAML (YAML Ain't Markup Language) is a human-readable data serialization standard that was first proposed by Clark Evans in 2001, with Ingy döt Net and Oren Ben-Kiki as co-designers. Originally meaning "Yet Another Markup Language," it was renamed to emphasize its data-oriented nature rather than document markup.
History & Creation
YAML 1.0 was released in 2004, with version 1.2 arriving in 2009. It was designed to be a more readable alternative to XML and JSON, drawing inspiration from Python's indentation-based syntax, Perl's data types, and email header format (RFC 822).
Where YAML is Used
- Docker Compose configurations
- Kubernetes manifests and Helm charts
- CI/CD pipelines (GitHub Actions, GitLab CI)
- Ansible playbooks and automation
- Application configuration files
- API specifications (OpenAPI/Swagger)
- Static site generators (Jekyll, Hugo)
Benefits Over Other Formats
- vs JSON: More readable, supports comments, multi-line strings, references
- vs XML: Less verbose, cleaner syntax, easier to write by hand
- vs INI: Supports nested structures, lists, and complex data types
- vs TOML: More widely supported, better for deeply nested data
Working with YAML Across Operating Systems
🪟 Windows
- VS Code with YAML extension
- PowerShell ConvertFrom-Yaml module
- Python with PyYAML:
pip install pyyaml
- yq for command-line processing
🍎 macOS
- Built-in Ruby YAML support
- Install yq via Homebrew:
brew install yq
- Python yaml module pre-installed
- TextMate or Sublime Text for editing
🐧 Linux
- yamllint for validation
- yq and jq for processing
- Python/Ruby YAML libraries
- vim/emacs YAML modes
Convert YAML ↔ JSON
Convert between YAML and JSON formats seamlessly
YAML Structure Examples & Best Practices
YAML's human-friendly syntax makes it ideal for configuration files and data exchange. Here are comprehensive examples demonstrating various YAML patterns and their benefits.
Basic YAML Structures
Simple Key-Value Pairs
Basic YAML structure with scalar values
# User configuration
name: John Doe
email: john.doe@example.com
age: 30
active: true
registered: 2024-01-15
# Inline format also supported
user: {name: Jane Smith, email: jane@example.com, age: 28}
Lists and Arrays
Different ways to represent lists in YAML
# Block style list
fruits:
- apple
- banana
- orange
# Flow style list
vegetables: [carrot, broccoli, spinach]
# List of objects
employees:
- name: Alice Johnson
department: Engineering
skills:
- Python
- JavaScript
- Docker
- name: Bob Smith
department: Marketing
skills: [SEO, Content Writing, Analytics]
Advanced YAML Features
Multi-line Strings
Different ways to handle multi-line text in YAML
# Literal style (preserves newlines)
description: |
This is a multi-line
description that preserves
line breaks and indentation.
This line is indented.
# Folded style (converts newlines to spaces)
summary: >
This is a long paragraph that
will be folded into a single
line with spaces between.
# Chomp indicators
keep_final_newline: |+
This keeps the final newline
strip_final_newline: |-
This strips the final newline
Anchors and References
Reuse data with YAML anchors to avoid duplication
# Define an anchor
default_settings: &defaults
timeout: 30
retries: 3
logging: true
# Reference the anchor
development:
<<: *defaults
debug: true
timeout: 60 # Override specific value
production:
<<: *defaults
debug: false
cache: true
# Anchor for a value
db_host: &dbhost localhost
services:
api:
database: *dbhost
worker:
database: *dbhost
Real-World Configuration Examples
Docker Compose Configuration
Multi-container Docker application setup
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html:ro
depends_on:
- api
networks:
- frontend
api:
build:
context: ./api
dockerfile: Dockerfile
environment:
NODE_ENV: production
DATABASE_URL: postgres://user:pass@db:5432/myapp
ports:
- "3000:3000"
depends_on:
- db
networks:
- frontend
- backend
db:
image: postgres:14
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- backend
volumes:
postgres_data:
networks:
frontend:
backend:
Kubernetes Deployment
Container orchestration configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: myapp:2.0
ports:
- containerPort: 8080
env:
- name: API_URL
value: "http://api-service:3000"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
GitHub Actions Workflow
CI/CD pipeline configuration
name: Deploy Application
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- name: Deploy to production
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
run: |
echo "Deploying to production..."
./scripts/deploy.sh
Ansible Playbook
Infrastructure automation and configuration management
---
- name: Configure web servers
hosts: webservers
become: yes
vars:
http_port: 80
max_clients: 200
tasks:
- name: Install nginx
apt:
name: nginx
state: latest
update_cache: yes
when: ansible_os_family == "Debian"
- name: Copy nginx configuration
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
notify:
- restart nginx
- name: Ensure nginx is running
service:
name: nginx
state: started
enabled: yes
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
Complex Data Structures
Application Configuration
Comprehensive app config with multiple environments
# Application configuration
app:
name: MyApp
version: 2.1.0
description: >
A comprehensive web application
for managing customer data
# Environment-specific settings
environments:
development:
debug: true
database:
host: localhost
port: 5432
name: myapp_dev
pool:
min: 2
max: 5
cache:
enabled: false
production:
debug: false
database:
host: db.production.example.com
port: 5432
name: myapp_prod
pool:
min: 10
max: 50
cache:
enabled: true
ttl: 3600
redis:
host: redis.production.example.com
port: 6379
# Feature flags
features:
- name: new_dashboard
enabled: true
rollout_percentage: 50
excluded_users: []
- name: advanced_analytics
enabled: false
allowed_users:
- admin@example.com
- beta@example.com
# API endpoints
api:
base_url: https://api.example.com
version: v2
endpoints:
users: /users
products: /products
orders: /orders
rate_limiting:
enabled: true
requests_per_minute: 60
OpenAPI/Swagger Specification
API documentation in YAML format
openapi: 3.0.0
info:
title: User Management API
version: 1.0.0
description: API for managing users
servers:
- url: https://api.example.com/v1
description: Production server
- url: https://staging-api.example.com/v1
description: Staging server
paths:
/users:
get:
summary: List all users
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: limit
in: query
schema:
type: integer
default: 20
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
users:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create a new user
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserInput'
responses:
'201':
description: User created
components:
schemas:
User:
type: object
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
createdAt:
type: string
format: date-time
Benefits of YAML Structures
When to Use Different YAML Features
Use Multi-line Strings For:
- Long descriptions or documentation
- SQL queries or scripts
- Template content
- Preserving formatting
Use Anchors & References For:
- Shared configuration values
- Default settings with overrides
- Reducing duplication
- Maintaining consistency
YAML vs Other Formats
Configuration Format Comparison
Same configuration in YAML vs JSON vs TOML
# YAML - Most readable for complex configs
server:
host: localhost
port: 8080
ssl:
enabled: true
cert: /path/to/cert.pem
key: /path/to/key.pem
# JSON equivalent - More verbose
{
"server": {
"host": "localhost",
"port": 8080,
"ssl": {
"enabled": true,
"cert": "/path/to/cert.pem",
"key": "/path/to/key.pem"
}
}
}
# TOML equivalent - Good for simple configs
[server]
host = "localhost"
port = 8080
[server.ssl]
enabled = true
cert = "/path/to/cert.pem"
key = "/path/to/key.pem"
Common YAML Patterns
Environment Variables & Secrets
Best practices for handling sensitive data
# Never hardcode secrets
database:
# Bad - exposed password
# password: mysecretpassword
# Good - reference environment variable
password: ${DB_PASSWORD}
# Alternative - reference from secret manager
password: !secret database_password
# Using environment variables with defaults
app:
port: ${PORT:-3000}
host: ${HOST:-0.0.0.0}
debug: ${DEBUG:-false}
# Reference external files
ssl:
cert: !file /etc/ssl/certs/server.crt
key: !file /etc/ssl/private/server.key
Conditional Configuration
Dynamic configuration based on conditions
# GitLab CI example with conditions
stages:
- test
- build
- deploy
.test_template: &test_definition
stage: test
script:
- npm install
- npm test
test:unit:
<<: *test_definition
only:
- merge_requests
- main
test:integration:
<<: *test_definition
script:
- npm install
- npm run test:integration
only:
- main
deploy:production:
stage: deploy
script:
- ./deploy.sh production
only:
- main
when: manual
environment:
name: production
url: https://example.com