コンテンツにスキップ

YAMLの変更点を見落とさない!diffより強力なYAML差分確認ツール『dyff』のすすめ

チェック

  • [ ] 本文を確認した
  • [ ] 概要を確認した
  • [ ] タグを確認した
  • [ ] inbox/ 直下へ移行した

概要

YAML の差分確認を、行単位の diff ではなく構造単位で見やすく表示するツール dyff の紹介記事。 Kubernetes マニフェストや Helm values のように、キーの順序、インデント、長いネスト構造が多い YAML では、通常の diff だけでは本質的な変更点を見落としやすい。 dyff betweenkubectl diff との連携、Git の外部 diff として使う方法まで、実運用での使い方がまとまっている。

本文

YAML は Kubernetes や CI/CD 設定、Helm values などで広く使われる。 しかし、通常の diff では YAML の構造を理解せず、単なるテキスト行の違いとして表示する。 そのため、インデント、キー順序、複数行の移動、ネストの深い設定では、何が変わったのかを読み取りにくい。

dyff は YAML を構造として比較し、変更されたパスと値を分かりやすく表示するツール。 Kubernetes の Deployment であれば、metadata.labelsspec.replicasspec.template.spec.containers[0].image のように、どのフィールドが変わったのかを追いやすい。

2つのYAMLファイルを比較する

基本的な使い方は dyff between

dyff between deployment-A.yaml deployment-B.yaml

これにより、2つの YAML ファイルの差分が構造単位で表示される。 通常の diff では変更行の前後を見ながら読み解く必要があるが、dyff ではどのキーの値がどう変わったかを中心に表示する。

ヘッダーやロゴ表示を省きたい場合は、--omit-header または短縮形の -b を使う。

dyff between --omit-header deployment-A.yaml deployment-B.yaml

記事の例では、Deployment の差分として次のような観点が見やすくなる。

  • metadata.labels の追加・変更
  • spec.replicas の変更
  • spec.template.metadata.labels の変更
  • コンテナイメージ、たとえば nginx-container.image の変更

Kubernetes マニフェストでは、同じラベルが metadata.labelsspec.selector.matchLabelsspec.template.metadata.labels に出てくることがある。 通常の diff では似た行が並ぶだけで紛らわしいが、dyff なら YAML パスとして見えるため、どの階層の変更かを確認しやすい。

kubectl diff と組み合わせる

Kubernetes には kubectl diff -f がある。 これはローカルのマニフェストとクラスタ上のリソースとの差分を表示できる便利なコマンドだが、標準では行単位の diff になる。

kubectl diff -f deployment-B.yaml

YAML が大きくなると、通常の出力では本当に重要な差分が埋もれやすい。 そこで、KUBECTL_EXTERNAL_DIFF に dyff を指定する。

KUBECTL_EXTERNAL_DIFF="dyff between --omit-header --set-exit-code" \
  kubectl diff -f deployment-B.yaml

--set-exit-code を付けると、差分がある場合に終了コード 1、差分がない場合に 0 を返す。 これは CI/CD に組み込むときに重要。 差分があるかどうかをジョブの結果として扱える。

Kubernetes 1.20 以降では KUBECTL_EXTERNAL_DIFF による外部 diff が使えるため、dyff をクラスタ適用前のレビューに組み込める。 特に Helm template の出力や Kustomize のビルド結果を比較するときに効果がある。

Git の diff として使う

Git の YAML 差分にも dyff を使える。 リポジトリローカルの Git 設定で外部 diff コマンドを定義し、.gitattributes で YAML ファイルに適用する。

git config --local diff.dyff.command \
  'dyff_between() { dyff --color on between --omit-header "$2" "$5"; }; dyff_between'

echo '*.yaml diff=dyff' >> .gitattributes

そのうえで、外部 diff を有効にしてログや差分を見る。

git log --ext-diff -u

--ext-diff を付けたときだけ dyff が使われる。 通常の git diff をそのまま使えば、従来どおりの行単位 diff も見られる。 この切り替えができるため、レビュー対象や好みに応じて使い分けられる。

どこで効くか

Service や小さな Deployment のような短い YAML では、通常の diff でも十分な場合がある。 しかし Helm values や複数環境の設定ファイルは、数百行から数千行になる。 その中で 1 つの値だけが変わる、あるいは同じ名前のキーが複数階層に出てくる場合、行単位 diff では見落としが起きやすい。

dyff は YAML の構造を前提に差分を見るため、「このフィールドが変わった」という確認に向く。 設定レビュー、環境差分の確認、CI での適用前チェック、Kubernetes マニフェストのレビューで使いやすい。

読み替え

この記事は、差分確認を「テキスト行」ではなく「設定の意味」に近づけるための道具として dyff を紹介している。 Kubernetes の設定ミスは、1 行の見落としで障害につながることがある。 特にラベル、セレクタ、イメージタグ、レプリカ数、リソース制限、環境変数、Ingress 設定などは、差分レビューで確実に見たい。

dyff はマニフェストを直接変えるツールではない。 変更内容を人間が理解しやすくするレビュー補助として使うのがよい。

要点

  • dyff は YAML を構造として比較し、変更されたパスと値を見やすく表示する。
  • Kubernetes マニフェストや Helm values の差分確認に向いている。
  • dyff between --omit-header old.yaml new.yaml でファイル比較できる。
  • KUBECTL_EXTERNAL_DIFF に指定すると kubectl diff の出力を dyff 化できる。
  • --set-exit-code は CI/CD で差分有無を判定するのに使える。
  • Git の外部 diff として設定すれば、リポジトリ内の YAML レビューにも使える。

タグ

yaml #kubernetes #dyff #diff #ci-cd