YAML is everywhere in DevOps β Kubernetes manifests, Ansible playbooks, Docker Compose, GitHub Actions, Terraform configs. Learning its quirks saves hours of debugging.
Basic Syntax
# Scalars
name: my-app
version: "2.1"
port: 3000
debug: true
nothing: nullIndentation matters. Spaces only β never tabs. Two spaces is the convention.
Strings
# Plain (usually works)
name: my-app
# Quoted (when values look like other types)
version: "1.0" # Without quotes: parsed as float
enabled: "true" # Without quotes: parsed as boolean
port: "8080" # Without quotes: parsed as integer
empty: ""
# Special characters need quotes
message: "Line 1\nLine 2" # \n is literal (no escape)
message: 'It''s a test' # Single quote escape
path: "C:\\Users\\admin"
colon: "key: value" # Colon followed by spaceMulti-Line Strings
# Literal block (preserves newlines)
script: |
#!/bin/bash
echo "Hello"
echo "World"
# Result: "#!/bin/bash\necho \"Hello\"\necho \"World\"\n"
# Literal block, strip trailing newline
script: |-
#!/bin/bash
echo "Hello"
echo "World"
# Result: "#!/bin/bash\necho \"Hello\"\necho \"World\""
# Folded (newlines become spaces)
description: >
This is a long
description that
wraps multiple lines.
# Result: "This is a long description that wraps multiple lines.\n"
# Folded, strip trailing newline
description: >-
This is a long
description.
# Result: "This is a long description."| Indicator | Newlines | Trailing | |
|---|---|---|---|
| `\ | ` | Preserved | Keeps final \n |
| `\ | -` | Preserved | Strips final \n |
> | Folded to spaces | Keeps final \n | |
>- | Folded to spaces | Strips final \n |
Lists
# Block style
fruits:
- apple
- banana
- cherry
# Inline style
fruits: [apple, banana, cherry]
# List of maps
users:
- name: Alice
role: admin
- name: Bob
role: developerMaps (Dictionaries)
# Block style
database:
host: localhost
port: 5432
name: myapp
# Inline style
database: {host: localhost, port: 5432, name: myapp}
# Nested
app:
server:
host: 0.0.0.0
port: 3000
database:
host: db.internal
port: 5432Master this topic with hands-on labs
Go beyond reading β build real projects in sandboxed environments with expert video guidance.
Browse Courses βAnchors and Aliases
Avoid repetition:
# Define anchor
defaults: &defaults
cpu: 200m
memory: 256Mi
# Use alias
web:
resources:
requests:
<<: *defaults # Merge
limits:
cpu: "1"
memory: 512Mi
api:
resources:
requests:
<<: *defaults # Same defaults
cpu: 500m # Override one valueDocker Compose Example
x-common: &common
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
services:
web:
<<: *common
image: my-web:latest
ports:
- "3000:3000"
api:
<<: *common
image: my-api:latest
ports:
- "8080:8080"Boolean Gotchas
YAML 1.1 (used by many tools) interprets many values as booleans:
# All of these are boolean true
enabled: true
enabled: True
enabled: TRUE
enabled: yes
enabled: Yes
enabled: on
enabled: On
# All of these are boolean false
enabled: false
enabled: no
enabled: off
# Country codes that become booleans!
country: NO # Norway β false!
country: "NO" # String "NO" β
Always quote values that look like booleans but aren't.
Number Gotchas
# Integer
count: 42
hex: 0xFF
octal: 0o755 # YAML 1.2
octal: 0755 # YAML 1.1 (careful!)
# Float
ratio: 3.14
scientific: 1.0e-3
# Version numbers need quotes!
version: 1.0 # Float: 1
version: "1.0" # String: "1.0"
version: 1.2.3 # String (has two dots)Null Values
value: null
value: ~
value: # Empty value = nullGet weekly IT automation tips
Docker, Ansible, Terraform, MLOps β curated insights delivered to your inbox. No spam.
Subscribe Free βCommon Mistakes
| Mistake | Wrong | Right |
|---|---|---|
| Tabs instead of spaces | βport: 3000 | port: 3000 |
| Inconsistent indentation | Mix 2/4 spaces | Stick to 2 |
| Unquoted special chars | name: app: v2 | name: "app: v2" |
| Version as number | version: 1.0 | version: "1.0" |
| Boolean country code | country: NO | country: "NO" |
| Missing space after colon | port:3000 | port: 3000 |
Validation
# Python
python -c "import yaml; yaml.safe_load(open('config.yml'))"
# yamllint
pip install yamllint
yamllint config.yml
# yq (query YAML like jq for JSON)
yq '.services.web.image' docker-compose.ymlWhat's Next?
Our Ansible Automation in 30 Minutes course uses YAML throughout for playbooks and configuration. Terraform for Beginners covers HCL (similar concepts, different syntax). First lessons are free. -e ---
Ready to go deeper? Explore our hands-on DevOps courses β practical labs covering Docker, Ansible, Terraform, and more.
Related guide
Related reading: Ansible for Kubernetes by Example covers this in real-world detail.
Ready to learn by doing?
Stop reading tutorials β start building. Expert video courses with hands-on labs in real sandboxed environments.
Related Articles
YAML Syntax Guide for DevOps
Master YAML syntax for DevOps tools. Scalars, lists, maps, anchors, multi-line strings, and common gotchas with pipeline examples.
Terraform Ansible Kubernetes Stack
Combine Terraform, Ansible, and Kubernetes for complete DevOps infrastructure. Provision, configure, and deploy end to end.
Ansible Inventory Management Guide
Master Ansible inventory management with static and dynamic inventories, host groups, variables, patterns, and seamless cloud provider integration.
10 Things to Do After Installing OpenClaw
Just installed OpenClaw? Here are 10 essential setup steps to get the most out of your AI agent β from personality to automation.
Agentic AI for DevOps Teams
Learn how agentic AI transforms DevOps workflows with autonomous agents that handle deployments, incident response, and infrastructure management.
AI Governance and Compliance
Implement AI governance frameworks with model registries, bias monitoring, explainability tools, and regulatory compliance for the EU AI Act and beyond.
Explore topics
Browse more articles on the topics covered here.