YQ: Wrangling YAML Configs๐
Part of a pathway: Debugging With Nothing But a Terminal
Consult the map
-
Debugging With Nothing But a Terminal โ step 11 of 20
โ Working with YAML ยท you are here ยท Vim Survival Mode โ
Kubernetes manifests, Ansible playbooks, GitHub Actions, Docker Compose โ in modern platform engineering, YAML is everywhere. But YAML's indentation-sensitive nature makes it notoriously difficult to edit with standard text tools like sed or awk.
yq is a portable command-line YAML processor. It's essentially jq for YAML, allowing you to slice, dice, and transform configuration files with precision and safety.
Installation๐
| Install yq on macOS | |
|---|---|
Verify installation and confirm you have the mikefarah/yq implementation (there are several unrelated tools sharing the name):
Quick Start: Get Productive in 5 Minutes๐
yq syntax is intentionally similar to jq. If you know one, you're halfway to knowing the other.

That last one is the pattern worth internalizing โ a base config and an environment-specific overlay merge into one result, the same shape whether you're reconciling two files by hand or reading how a templating tool does it for you:
graph LR
Base["base.yaml"] --> Merge{{"eval-all<br/>select(0) * select(1)"}}
Overlay["overlay.yaml"] --> Merge
Merge --> Result["Merged config"]
style Base fill:#2d3748,stroke:#cbd5e0,stroke-width:2px,color:#fff
style Overlay fill:#2d3748,stroke:#cbd5e0,stroke-width:2px,color:#fff
style Merge fill:#d69e2e,stroke:#cbd5e0,stroke-width:2px,color:#000
style Result fill:#2f855a,stroke:#cbd5e0,stroke-width:2px,color:#fff
Why YQ Matters for Platform Work๐
YAML is the backbone of Infrastructure as Code (IaC). One wrong indentation can break a production deployment. yq removes this friction by treating YAML as a structured data format rather than a text file.
Common Scenarios๐
Find all containers in a Deployment that don't have resource limits defined:
| Audit Resource Limits | |
|---|---|
Update the image tag across multiple GitHub Action workflow files:
| Update Image Tag | |
|---|---|
Extract values from a legacy config and format them for a new system:
| Extract and Format | |
|---|---|
Core Functionality๐
Three behaviors cover most of what you'll reach for day to day:
-
In-place Editing (
-i)
Why it matters: Allows you to modify files directly without temporary files or redirects.
Update Config Key insight: Always verify your filter without
-ifirst โ and treat the edit as step one, not step three. Edit the git-tracked manifest, commit, and let your pipeline or reconciler apply it. Piping straight intokubectl applyagainst a running cluster skips the review and audit trail Git exists to give you. -
Multi-document Handling
Why it matters: Kubernetes files often contain multiple documents separated by
---.Read All Documents Key insight:
yqhandles the stream of documents automatically. -
Format Conversion (
-o)
Why it matters: Sometimes you need JSON for a tool that doesn't speak YAML.
YAML to JSON Key insight: Useful for interoperability between different CLI tools.
Common Pitfalls๐
-
Two Different Tools Share This Name
mikefarah/yq(what this article covers) andkislyuk/yq(a Python wrapper that converts YAML to JSON and pipes it through the realjq) use different filter syntax entirely. A filter that works in one throws a cryptic error in the other โ check which one you actually have. -
Forgetting
-iMeans Nothing Is Saved
Without
-i,yqprints the modified document to your terminal and leaves the file on disk untouched โ easy to mistake for "the edit didn't work."Wrong - Prints to Screen, File Unchanged Correct - Writes Back to the File -
Same Shell-Quoting Trap as
jq
yqfilters starting with.and containing[]are just as vulnerable to shell glob expansion asjq's are. Always quote:Always Quote the Filter
Practice Problems๐
Practice Problem 1: Navigating Lists
In a YAML file like {"items": [{"name": "a", "val": 1}, {"name": "b", "val": 2}]}, how do you get the value (val) for the item named "b"?
Answer
| Select a Field from a Matching List Item | |
|---|---|
Practice Problem 2: Adding a Field
How would you add a labels object with app: my-app to the metadata of a YAML file?
Answer
| Add a Nested Field, Creating Parents as Needed | |
|---|---|
yq will automatically create the parent objects (labels) if they don't exist.
Key Takeaways๐
| Feature | command/Filter |
|---|---|
| Read | yq '.path.to.key' file.yaml |
| Write | yq -i '.key = "value"' file.yaml |
| Filter | select(.key == "match") |
| Convert | -o=json (to JSON), -o=xml (to XML) |
| Delete | del(.key.to.remove) |
What's Next๐
If you're following the Debugging With Nothing But a Terminal pathway, the next step is Vim Survival Mode โ vi/vim is still what you'll find on almost every server when there's no time to install anything else, and it covers the four commands that get you in, fixed, and out.
Further Reading๐
Official Documentation๐
- YQ Documentation - Comprehensive guide for the most popular
yqimplementation (mikefarah). - YQ GitHub Repository - Source code and community discussions.
Related Tools & Alternatives๐
Deep Dives๐
- YAML Specification - For when you really need to understand why your indentation is broken.
- How Parsers Work - The lexing-then-parsing pipeline underneath every
yqcall.