YAML Cheat Sheet
Quick reference for YAML scalars, collections, anchors, block styles, and indentation pitfalls.
YAML (YAML Ain't Markup Language) is a human-friendly data serialization format specified at yaml.org/spec/1.2.2. It is the de facto standard for Kubernetes manifests, GitHub Actions, Docker Compose, Ansible playbooks, and most modern configuration files. YAML is a strict superset of JSON — any valid JSON file is also valid YAML — but it adds indentation-based block syntax, comments, anchors, and rich scalar styles.
Document structure
A YAML stream is one or more documents separated by --- (start) and ... (end). Most files contain a single document.
---
name: devtools
version: 1.2.3
...
Scalars
| Style | Example | Notes |
|---|---|---|
| Plain | hello | No quotes; most flexible, most ambiguous |
| Single-quoted | 'hello world' | Only '' is escaped; no escapes at all |
| Double-quoted | "line1\nline2" | Full backslash-escape support |
| Literal block | | (see below) | Preserves newlines |
| Folded block | > (see below) | Joins lines into spaces |
When quotes are required
Bare scalars work for most cases, but quote a value when it:
- starts with a reserved character (
!,&,*,?,:,-,<,>,[,],{,},|,%,@,`) - looks like a number, boolean, or null (
true,false,yes,no,on,off,null,~) - contains
:or#followed by space - is empty (
"")
port: "8080" # string, not integer
ratio: "1.5" # string, not float
flag: "true" # string, not boolean
password: "p@ss:word" # contains :
The Norway problem
YAML 1.1 (the older default in many parsers) treats no, yes, on, off as booleans. This famously turned the country code NO into the boolean false — the "Norway problem." YAML 1.2 only recognizes true/false (and True/FALSE/TRUE/FALSE), but many tools still default to YAML 1.1. Quote anything that could be ambiguous:
country: "NO" # safe: the string "NO"
debug: true # YAML 1.1 / 1.2 boolean true
shutdown: "off" # safe: the string "off"
Block mappings and sequences
A mapping (key/value) uses key: value with the value indented one level. A sequence (list) uses - item at the same indent as its parent key.
# block mapping
service:
name: api
port: 8080
replicas: 3
# block sequence
tags:
- web
- backend
- prod
# sequence of mappings
items:
- sku: BK-001
qty: 1
- sku: PN-042
qty: 2
Indentation must be consistent within a document. Spaces only — tabs are not allowed.
Flow style
Square brackets for sequences and curly braces for mappings give you a compact, JSON-like inline form.
# flow sequence
tags: [web, backend, prod]
# flow mapping
point: { x: 1, y: 2 }
# nested
matrix: [[1, 2], [3, 4], [5, 6]]
Flow style is useful for small, dense values. Block style is preferred for anything humans read often.
Multi-line strings
| Indicator | Newlines | Trailing newline |
|---|---|---|
| ` | ` | preserved |
| ` | -` | preserved |
| ` | +` | preserved |
> | folded to space | kept |
>- | folded to space | stripped |
>+ | folded to space | kept, plus extra |
# literal block — preserves newlines exactly
description: |
line one
line two
line three
# folded block — joins lines with single spaces
summary: >
This is a single paragraph
that wraps across two lines
in the source file.
# chomping — strip the final newline
commit: |-
fix: handle empty array
Anchors and aliases
&name defines an anchor on a node; *name reuses it elsewhere. Use the merge key <<: to inherit keys from a mapping anchor.
defaults: &defaults
timeout: 30
retries: 3
log: true
prod:
<<: *defaults
host: api.example.com
staging:
<<: *defaults
host: staging.example.com
log: false # override
Anchors work for sequences and mappings; they do not duplicate scalar values (scalars are already cheap to share).
Multi-document streams
Use --- to start a new document and ... to end one. Each document is parsed independently.
---
name: api
port: 8080
---
name: worker
port: 8081
...
Indentation rules and pitfalls
- Spaces only. Tabs are not permitted anywhere in YAML.
- Siblings share an indent. All keys at the same level under a parent must align.
- Children are indented more than their parent. Typically 2 spaces; YAML does not care about the exact number as long as it is consistent within a block.
- A
-is an indent step. In a sequence, the dash counts as the same indent as its key. - Indent matters around
|/>blocks. The block scalar's content indent is determined by the first non-empty line.
A subtle failure mode:
# broken
key:
- a
- b
# works
key:
- a
- b
Both are syntactically legal, but the first is unusual and easy to misread. Keep the dash aligned under its key for clarity.
Comments
Anything after a
#(with a leading space for safety) is a comment and ignored by the parser.# this is a comment name: devtools # inline comment, also ignored