yq で YAML を扱う — k8s / GitHub Actions 用 30+ パターン

yq は YAML/JSON/XML を扱う CLI。kubectl・GitHub Actions YAML・Helm values・docker-compose を編集する時に必須です。本記事は最も普及している mikefarah/yq (Go 製) を前提にします。 jq とほぼ同じ書き方で扱えるのが強み。

2 種類の yq に注意:
  • mikefarah/yq (Go 製、本稿対象) — yq -i '.x.y = "v"' file.yaml 形式。最も普及。
  • kislyuk/yq (Python 製) — jq のラッパで yq '.x.y' のみ、書き換えは別ツール。互換性なし。
ディストリのパッケージマネージャによってはどちらが入るか異なる。yq --version で確認。

目次

  1. 読み取り(jq とほぼ同じ)
  2. in-place 更新 (-i)
  3. multi-document YAML
  4. YAML ↔ JSON 変換
  5. k8s / Compose / Actions レシピ
  6. 用語集

サンプル YAML として下記を仮定:

# app.yaml
apiVersion: v1
kind: Deployment
metadata:
  name: web
  labels:
    app: web
    env: prod
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: web
          image: nginx:1.25
          resources:
            requests:
              cpu: 100m
              memory: 128Mi

1. 読み取り

# 全表示(フォーマット維持)
yq . app.yaml

# 値取得
yq '.spec.replicas' app.yaml             # 3
yq -r '.metadata.name' app.yaml          # web (raw 出力、クォート無し)

# 配列展開
yq '.spec.template.spec.containers[]' app.yaml
yq '.spec.template.spec.containers[].image' app.yaml

# 条件抽出
yq '.spec.template.spec.containers[] | select(.name == "web")' app.yaml

# キー一覧
yq '.metadata | keys' app.yaml

# 型確認
yq '.spec.replicas | type' app.yaml      # !!int

# 長さ
yq '.spec.template.spec.containers | length' app.yaml

2. in-place 更新 (-i)

jq と決定的に違うのが、yq はファイルの直接編集 (-i) ができる点。 YAML のコメントや順序を維持したまま値だけ書き換えられる。

# 値を更新
yq -i '.spec.replicas = 5' app.yaml
yq -i '.metadata.labels.env = "stg"' app.yaml

# 環境変数からの注入
yq -i ".spec.replicas = $REPLICAS" app.yaml
yq -i '.spec.replicas = env(REPLICAS)' app.yaml      # 型推論あり (env())
yq -i '.image = strenv(IMAGE)' app.yaml              # 強制 string (strenv)

# 配列要素の更新( index 指定)
yq -i '.spec.template.spec.containers[0].image = "nginx:1.27"' app.yaml

# 全要素一括変更
yq -i '.spec.template.spec.containers[].imagePullPolicy = "IfNotPresent"' app.yaml

# select で絞ってから更新
yq -i '(.spec.template.spec.containers[] | select(.name == "web") | .image) = "nginx:1.27"' app.yaml

# キー追加
yq -i '.metadata.annotations.maintainer = "iigtn"' app.yaml

# キー削除
yq -i 'del(.metadata.labels.env)' app.yaml

# 配列要素追加
yq -i '.spec.template.spec.containers += [{"name":"sidecar","image":"busybox"}]' app.yaml

# マージ(既存に追記、配列は連結)
yq -i '. *= load("override.yaml")' base.yaml

# 全 file 一括(複数ファイル対象)
yq -i '.metadata.namespace = "prod"' k8s/*.yaml

3. multi-document YAML

k8s manifest は --- で複数ドキュメントを 1 ファイルに含めることが多い。yq は標準対応。

# すべての document を表示
yq 'select(documentIndex >= 0)' multi.yaml

# 特定 document のみ(0 始まり)
yq 'select(documentIndex == 0)' multi.yaml

# kind == Deployment の document だけ
yq 'select(.kind == "Deployment")' multi.yaml

# 全 document の name 一覧
yq '[.metadata.name]' multi.yaml             # 各 document が個別出力
yq -o=json '.metadata.name' multi.yaml | jq -s

# 各 document に共通フィールド追加
yq -i '.metadata.labels.team = "platform"' multi.yaml

# document 結合 (multi → single 配列)
yq ea '[.]' multi.yaml                       # ea = eval-all

# 別ファイルの document を merge
yq ea '. as $item ireduce ({}; . * $item)' base.yaml override.yaml

4. YAML ↔ JSON 変換

# YAML → JSON
yq -o=json '.' app.yaml
yq -o=json '.' app.yaml > app.json

# JSON → YAML
yq -p=json '.' data.json
cat data.json | yq -p=json -o=yaml

# YAML → CSV / TSV / Properties
yq -o=csv '[.users[]]' data.yaml
yq -o=props '.config' app.yaml

# 入力フォーマット指定(拡張子が無い時)
cat foo | yq -p=yaml '.x'
cat foo | yq -p=json '.x'
cat foo | yq -p=xml  '.x'

5. k8s / Compose / Actions レシピ

レシピ 1 — k8s Deployment の image を更新

yq -i '
  (.spec.template.spec.containers[] | select(.name == "web") | .image) = "nginx:1.27"
' k8s/web-deployment.yaml

# ConfigMap の値を更新
yq -i '.data.LOG_LEVEL = "debug"' k8s/configmap.yaml

レシピ 2 — multi-document manifest の特定 kind だけ操作

# すべての Deployment の replicas を 5 に
yq -i 'select(.kind == "Deployment").spec.replicas = 5' k8s/all.yaml

# 特定 namespace を全 document に注入
yq -i '.metadata.namespace = "prod"' k8s/all.yaml

レシピ 3 — docker-compose の image tag を環境変数で書き換え

IMAGE_TAG=v1.2.3 yq -i '.services.web.image = "myapp:" + strenv(IMAGE_TAG)' compose.yaml

レシピ 4 — GitHub Actions YAML から workflow 名一覧

for f in .github/workflows/*.yml; do
  echo "$f: $(yq -r '.name' $f)"
done

レシピ 5 — Helm values.yaml の値を上書き

# 配列内の対象要素を更新
yq -i '
  (.deployments[] | select(.name == "api") | .replicas) = 4
' values.yaml

# 別ファイルとマージ
yq -i '. *= load("values-prod.yaml")' values.yaml

レシピ 6 — kubectl 出力を yq で整形

kubectl get pods -o yaml \
  | yq '.items[] | {name: .metadata.name, status: .status.phase, ip: .status.podIP}'

# JSON 出力経由でもいい (jq でも処理可能)
kubectl get pods -o json | yq -p=json '.items[].metadata.name'

レシピ 7 — env ファイルの自動生成(YAML → .env)

# config.yaml: { app: { port: 8080, log_level: info } }
yq -r '.app | to_entries[] | "\(.key | upcase)=\(.value)"' config.yaml
# 出力: PORT=8080
#       LOG_LEVEL=info

コマンド早見表

# 読取
yq '.x.y' file.yaml
yq -r '.metadata.name' file.yaml

# 更新 (in-place)
yq -i '.spec.replicas = 5' file.yaml
yq -i '.image = strenv(IMG)' file.yaml
yq -i 'del(.metadata.labels.env)' file.yaml

# 条件 + 更新
yq -i '(.spec.template.spec.containers[] | select(.name == "web") | .image) = "..."' file.yaml

# multi-document
yq 'select(.kind == "Deployment")' multi.yaml
yq ea '. as $i ireduce ({}; . * $i)' base.yaml override.yaml

# 変換
yq -o=json '.' file.yaml
yq -p=json '.' file.json

用語集

yq (mikefarah)
Go 製の YAML/JSON/XML 処理 CLI。jq とほぼ互換の式言語、ただし in-place 更新可能。最も普及。
yq (kislyuk)
Python 製、jq のラッパ。読み取り専用。mikefarah 版とは互換性なし。yq --version で見分ける。
in-place 更新 (-i)
ファイルを直接書き換える機能。コメントや書式を維持したまま値だけ更新。
env() vs strenv()
環境変数の取り込み。env() は型推論あり(数値は number 化)、strenv() は強制 string。設定ファイルの version などは strenv 推奨。
multi-document YAML
1 ファイルに --- で区切った複数 YAML ドキュメントを含める書式。k8s manifest の標準形。
documentIndex
multi-doc 時の各 document インデックス。select(documentIndex == 0) で先頭だけ取れる。
eval-all (ea)
全 document を 1 つのストリームとして処理するモード。複数 document 横断の集計に必要。
load("file")
別 YAML/JSON ファイルを式の中で読み込む関数。merge やテンプレ展開に使う。
マージ (*=)
オブジェクトを再帰的にマージ。配列は要素を上書きせず連結する挙動(オプションで変更可)。
-o / -p
-o = output format(yaml/json/csv/props/xml)、-p = input format。拡張子が無い入力で必要。
jq との違い
jq は JSON 専用・read-only、yq は YAML/JSON/XML 対応・in-place 編集可能。jq 構文をほぼ流用できる。
k8s manifest
Kubernetes リソース定義 YAML。Deployment / Service / ConfigMap / Secret 等。multi-document で 1 ファイルにまとめることが多い。
Helm values.yaml
Helm Chart の設定ファイル。yq で環境別オーバーレイを生成・更新する用途で頻出。