yaml-pro
YAML authoring and processing — gotchas, validation, and safe loading — use when writing configs or parsing YAML.
Files1
View on GitHubSKILL.mdskills/yaml-pro/SKILL.md
GitHubOverview
YAML is the config language of the DevOps world — readable, but full of
footguns (the infamous no → false, octal surprises, billion-laughs
attacks). This skill covers writing safe, predictable YAML and parsing it
defensively in code.
When to use
- Authoring configs (CI pipelines, Kubernetes manifests, app settings)
- Designing YAML-based file formats or DSLs
- Parsing YAML safely in applications (avoiding deserialization attacks)
- Templating YAML (anchors, merge keys, and when to avoid them)
- Validating YAML configs with schemas in CI
Core concepts
Quote defensively. YAML's implicit typing converts unquoted yes/no/on/off,
0o17-style numbers, and version-like strings (3.10 → 3.1). Quote strings
that could be misinterpreted — especially versions, identifiers with leading
zeros ("007"), and anything resembling a boolean. Explicit is better than
clever.
Safe loading only. Never use a full YAML loader on untrusted input — it can instantiate arbitrary objects (the classic deserialization attack). Always use the safe loader, which handles only plain scalars, lists, and maps. This is non-negotiable for any YAML from users or networks.
Anchors and merge keys: use sparingly. &anchor / *alias / <<: *merge
reduce duplication in hand-written configs, but they complicate programmatic
processing and confuse newcomers. Fine for small DRY wins; for heavy reuse,
prefer a templating layer or config generation in code.
Schema-validate configs. JSON Schema validates YAML too (YAML is a superset of JSON). Validate CI configs, app settings, and manifests against a schema in CI — catching a typo'd key at commit time beats debugging a silent misconfig in production.
Multi-document files. --- separates documents in one stream; some tools
read only the first. Know whether your consumer handles multi-doc files before
relying on them.
Practical workflow
- Start from a known-good example for the target system; adapt minimally rather than writing from memory.
- Quote aggressively: versions, booleans-as-strings, leading-zero numbers, and any value where the type matters downstream.
- Keep nesting shallow (3–4 levels max); deep nesting is hard to read and easy to mis-indent — refactor into flatter structures or multiple files.
- Validate in CI: schema check + a dry-run/parse of the consuming tool
(e.g.
kubectl --dry-run, CI config linter) on every change. - In code, always safe-load; convert to typed config objects with defaults and validation immediately after parsing — don't pass raw dicts around.
- Document the config: a commented example file or schema with descriptions is worth more than a wiki page nobody updates.
Common pitfalls
- The Norway problem:
no/yes/on/offbecoming booleans — quote country codes and string flags. - Tabs for indentation — forbidden in YAML; use spaces, consistently (2 is the convention).
- Version
3.10parsed as float3.1— quote versions, always. - Merge-key surprises:
<<: *basesilently overrides in non-obvious order with multiple merges; prefer explicit keys for critical settings. - Giant YAML files generated by tools — split into multiple files with clear naming; 2000-line YAML is unreviewable.
- Secrets in YAML committed to git — configs get committed; secrets don't belong in them. Reference secret stores via placeholders resolved at deploy time.