Quick Answer: YAML uses indentation (spaces, not tabs) to define structure. Key-value:
name: Sam. List: items starting with-. Nested: indent by 2 spaces. Strings don't need quotes unless they contain special characters. Comments start with#.
Basic Syntax
# This is a comment
# Key-value pairs
name: Sam
age: 30
email: [email protected]
# Indentation matters (use spaces, NEVER tabs)
# Standard: 2 spaces per level
Data Types
Strings
# Plain (no quotes needed usually)
name: SamNet
title: Senior Engineer
# Quoted (use when value has special chars)
message: "Hello: World" # Double quotes — supports escape sequences
path: 'C:\Users\Sam' # Single quotes — literal (no escapes)
colon_value: "key: value" # Quotes needed because of :
hash_value: "#not a comment" # Quotes needed because of #
# Escape sequences (double quotes only)
newline: "line1\nline2"
tab: "col1\tcol2"
Numbers
integer: 42
negative: -17
float: 3.14
scientific: 6.022e23
hex: 0xFF
octal: 0o77
infinity: .inf
not_a_number: .nan
# Careful — these are numbers, not strings:
version: 1.0 # Float! Use "1.0" for string
zip: 010 # Octal in YAML 1.1 (= decimal 8), string in YAML 1.2
Booleans
# All of these are true:
enabled: true
enabled: True
enabled: yes
enabled: on
# All of these are false:
disabled: false
disabled: False
disabled: no
disabled: off
# Common gotcha: "yes" and "no" are booleans!
# Use quotes if you mean the string:
answer: "yes" # String "yes"
country: "no" # String "no" (not false!)
Null
value: null
value: ~
value: # Empty value is also null
Lists (Arrays/Sequences)
# Block style (most common)
fruits:
- apple
- banana
- cherry
# Inline style
fruits: [apple, banana, cherry]
# List of maps
users:
- name: Alice
age: 30
- name: Bob
age: 25
# Nested lists
matrix:
- [1, 2, 3]
- [4, 5, 6]
- [7, 8, 9]
Maps (Objects/Dictionaries)
# Block style
person:
name: Sam
age: 30
email: [email protected]
# Inline style
person: {name: Sam, age: 30, email: [email protected]}
# Nested maps
database:
host: localhost
port: 5432
credentials:
username: admin
password: secret
Multiline Strings
Literal Block (|) — Preserves Newlines
# Keeps line breaks exactly as written
description: |
This is line 1.
This is line 2.
This is line 4 (blank line above preserved).
# Result: "This is line 1.\nThis is line 2.\n\nThis is line 4...\n"
Folded Block (>) — Joins Lines
# Joins lines with spaces (like HTML)
description: >
This is a long paragraph
that spans multiple lines
but becomes a single line.
# Result: "This is a long paragraph that spans multiple lines but becomes a single line.\n"
Strip/Keep Trailing Newline
# Default: one trailing newline
text: |
hello
# Strip trailing newline
text: |-
hello
# Keep all trailing newlines
text: |+
hello
Anchors and Aliases (Reuse Values)
# Define an anchor with &
defaults: &defaults
adapter: postgres
host: localhost
port: 5432
# Reference with *
development:
<<: *defaults # Merge all defaults
database: dev_db
production:
<<: *defaults # Same defaults
database: prod_db
host: db.example.com # Override specific values
# Simple value anchor
max_connections: &max 100
pool_size: *max # Gets value 100
Common Patterns
Docker Compose
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
environment:
- NGINX_HOST=example.com
restart: unless-stopped
depends_on:
- api
api:
build:
context: ./api
dockerfile: Dockerfile
env_file:
- .env
deploy:
resources:
limits:
memory: 512M
cpus: "1.0"
volumes:
data:
driver: local
networks:
frontend:
driver: bridge
GitHub Actions
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm test
Kubernetes Pod
apiVersion: v1
kind: Pod
metadata:
name: myapp
labels:
app: myapp
tier: frontend
spec:
containers:
- name: web
image: nginx:alpine
ports:
- containerPort: 80
resources:
limits:
memory: "128Mi"
cpu: "500m"
env:
- name: NODE_ENV
value: production
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
Ansible Playbook
---
- name: Configure web servers
hosts: webservers
become: yes
vars:
http_port: 80
max_clients: 200
tasks:
- name: Install nginx
apt:
name: nginx
state: present
- name: Start nginx
service:
name: nginx
state: started
enabled: yes
- name: Copy config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Reload nginx
handlers:
- name: Reload nginx
service:
name: nginx
state: reloaded
Common Gotchas
Tabs vs Spaces
# WRONG — tabs will cause errors
name: Sam # This is a tab!
# CORRECT — always use spaces
name: Sam
Colon in Values
# This breaks — colon+space in the middle of a value
description: Note: this will cause a parse error
# Fix — quote the value
description: "Note: this works fine"
Special Values
# These are NOT strings:
yes: true # Boolean true
no: false # Boolean false
1.0: 1.0 # Float
null: null # Null
# Force them to be strings:
yes: "yes"
no: "no"
version: "1.0"
value: "null"
Indentation Errors
# WRONG — inconsistent indentation
person:
name: Sam
age: 30 # Error: extra indentation
# CORRECT
person:
name: Sam
age: 30
Validate YAML
# Python (built-in)
python3 -c "import yaml; yaml.safe_load(open('file.yml'))"
# yamllint (install: pip install yamllint)
yamllint file.yml
# Online: use any YAML validator