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

はじめに

こんにちは、サイオステクノロジーの小野です。

Kubernetesを利用する中で、yamlファイルの差分を確認することがよくあります。

差分確認コマンドと言えばdiffコマンドが一般的ですが、yamlファイルは行単位ではなく設定単位で比較を行いたいケースが多いので、diffコマンドを使うのが難しいです。

そんな時に役立つdyffというツールをご紹介します。

dyffとは

dyffはテキストの「行」ではなく「データ構造(意味)」に基づいてYAMLやJSONファイルを比較するコマンドラインツールです。

dyffは以下の特徴があります。

  • キーの順序を無視して比較
  • 人間が読みやすい出力形式
  • ツール連携

dyffインストール方法

dyffのインストール方法について詳しくは公式のリポジトリを参照してください。

バイナリファイルを用いてインストールする場合、以下のように実行します。

$ curl -LO https://github.com/homeport/dyff/releases/download/<バージョン>/dyff_<インストール環境>.tar.gz
$ tar -xvzf dyff_<インストール環境>.tar.gz
$ sudo chmod +x dyff
$ sudo mv dyff /usr/local/bin/

Macをお使いの場合はHomebrewでインストールが可能です。

$ brew install homeport/tap/dyff

LinuxやMacにdyffの最新バージョンを手軽にインストールしたい場合は以下のスクリプトを使うことが可能です。

$ curl --silent --location https://git.io/JYfAY | bash

dyff使い方

例として以下の2つのyamlファイルを比較します。

# deployment-A.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-app
  namespace: production
  labels:
    app: frontend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.24.0
        ports:
        - containerPort: 80
        env:
        - name: ENVIRONMENT
          value: "prod"
# deployment-B.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-app
  namespace: production
  labels:
    app: frontend
    team: ui-dev # ラベルが追加されている
spec:
  replicas: 3 # レプリカ数が増えている
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
        team: ui-dev # ラベルが追加されている
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.25.0 # イメージがバージョンアップしている
        env: # 環境変数設定とポート設定の記載が入れ替わっている
        - name: ENVIRONMENT
          value: "prod"
        ports:
        - containerPort: 80

ちなみにdiffコマンドを使って上記のyamlを比較すると以下のようになります。diffでは、ぱっと見でどんな設定差分があるのかわかりません。また、環境変数設定とポート設定の記載が入れ替わっただけだと設定的には差分がないですが、diffは行単位で差分比較するので、差分として出力されてしまいます。

$ diff deployment-A.yaml deployment-B.yaml 
7a8
>     team: ui-dev
9c10
<   replicas: 2
---
>   replicas: 3 
16a18
>         team: ui-dev
20,23c22,23
<         image: nginx:1.24.0
<         ports:
<         - containerPort: 80
<         env:
---
>         image: nginx:1.25.0
>         env: 
25a26,27
>         ports:
>         - containerPort: 80

使い方① yamlファイルの比較

dyffは以下のコマンドを実行することで、yamlファイルAからyamlファイルBはどのように差分があるのかを出力します。dyffはyamlファイルのどこが変更されたか、設定単位で確認することが可能です。したがって、一目で差分を確認することができます。また、記載が変更されても設定が変更されていなければ出力されないようになっています。

$ dyff between deployment-A.yaml deployment-B.yaml 
     _        __  __
   _| |_   _ / _|/ _|  between deployment-A.yaml
 / _' | | | | |_| |_       and deployment-B.yaml
| (_| | |_| |  _|  _|
 \__,_|\__, |_| |_|   returned four differences
        |___/

metadata.labels
  + one map entry added:
    team: ui-dev

spec.replicas
  ± value change
    - 2
    + 3

spec.template.metadata.labels
  + one map entry added:
    team: ui-dev

spec.template.spec.containers.nginx-container.image
  ± value change
    - nginx:1.24.0
    + nginx:1.25.0

dyffのロゴが鬱陶しい場合はオプションで消すことも可能です。

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

metadata.labels
  + one map entry added:
    team: ui-dev

spec.replicas
  ± value change
    - 2
    + 3

spec.template.metadata.labels
  + one map entry added:
    team: ui-dev

spec.template.spec.containers.nginx-container.image
  ± value change
    - nginx:1.24.0
    + nginx:1.25.0

使い方②Kubernetesクラスターにデプロイされているリソースと yamlファイルの比較

Kubernetesにデプロイされているリソースとyamlファイルを比較する際に、以下のコマンドを実行することが良くあります。しかし、こちらもdiffコマンドと同様に行単位での比較を行っているため、どこの設定が変更されたのかわかりづらいです。

# deployment-A.yamlがデプロイされているKubernetesクラスターに対して、以下のコマンドを実行
$ kubectl diff -f deployment-B.yaml 
diff -u -N /tmp/LIVE-2041829305/apps.v1.Deployment.production.frontend-app /tmp/MERGED-4236462828/apps.v1.Deployment.production.frontend-app
--- /tmp/LIVE-2041829305/apps.v1.Deployment.production.frontend-app     2026-03-26 18:24:38.226501887 +0900
+++ /tmp/MERGED-4236462828/apps.v1.Deployment.production.frontend-app   2026-03-26 18:24:38.227501925 +0900
@@ -6,16 +6,17 @@
     kubectl.kubernetes.io/last-applied-configuration: |
       {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"frontend"},"name":"frontend-app","namespace":"production"},"spec":{"replicas":2,"selector":{"matchLabels":{"app":"frontend"}},"template":{"metadata":{"labels":{"app":"frontend"}},"spec":{"containers":[{"env":[{"name":"ENVIRONMENT","value":"prod"}],"image":"nginx:1.24.0","name":"nginx-container","ports":[{"containerPort":80}]}]}}}}
   creationTimestamp: "2026-03-26T09:22:34Z"
-  generation: 1
+  generation: 2
   labels:
     app: frontend
+    team: ui-dev
   name: frontend-app
   namespace: production
   resourceVersion: "3430046"
   uid: 9602c096-6931-4278-ba8d-8dbaf9fd2faa
 spec:
   progressDeadlineSeconds: 600
-  replicas: 2
+  replicas: 3
   revisionHistoryLimit: 10
   selector:
     matchLabels:
@@ -30,12 +31,13 @@
       creationTimestamp: null
       labels:
         app: frontend
+        team: ui-dev
     spec:
       containers:
       - env:
         - name: ENVIRONMENT
           value: prod
-        image: nginx:1.24.0
+        image: nginx:1.25.0
         imagePullPolicy: IfNotPresent
         name: nginx-container
         ports:

kubectl v1.20以降ではdyffを組み込んで、差分比較することが可能です。デフォルトのkubectl diffよりかなり見やすく設定差分を確認することができます。

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

metadata.generation
  ± value change
    - 1
    + 2

metadata.labels
  + one map entry added:
    team: ui-dev

spec.replicas
  ± value change
    - 2
    + 3

spec.template.metadata.labels
  + one map entry added:
    team: ui-dev

spec.template.spec.containers.nginx-container.image
  ± value change
    - nginx:1.24.0
    + nginx:1.25.0

–omit-headerのオプションは上記の-bオプションと同じでロゴを表示しないようにします。–set-exit-codeのオプションは差分が存在した場合は終了コード 1、差分がない場合は 0 を返すようにします。これによって、CI/CDなどの差分確認スクリプトの中に組み込んでも、差分があるかどうかを判定できるようになります。

使い方③Gitリポジトリ内の比較

Gitの過去のコミットを比較する際に、以下のコマンドを使います。Gitでよく見るコミット差分比較の出力です。

$ git log -u
commit ***
Author: ***
Date:  ***

    yamlの更新

diff -git a/deployment.yaml b/deployment.yaml
***
@@ -5,8 +5,9 @@
   namespace: production
   labels:
     app: frontend
+    team: ui-dev
 spec:
-  replicas: 2
+  replicas: 3 
   selector:
     matchLabels:
       app: frontend
@@ -14,12 +15,13 @@
     metadata:
       labels:
         app: frontend
+        team: ui-dev
     spec:
       containers:
       - name: nginx-container
-        image: nginx:1.24.0
-        ports:
-        - containerPort: 80
-        env:
+        image: nginx:1.25.0
+        env: 
         - name: ENVIRONMENT
           value: "prod"
+        ports:
+        - containerPort: 80

Gitのコミット差分比較機能に対してもdyffを組み込むことが可能です。yamlのみですが、見やすく設定差分を確認することができます。

$ git config --local diff.dyff.command 'dyff_between() { dyff --color on between --omit-header "$2" "$5"; }; dyff_between'
echo '*.yaml diff=dyff' >> .gitattributes
$ git log --ext-diff -u
commit ***
Author: ***
Date:  ***

    yamlの更新

diff -git a/deployment.yaml b/deployment.yaml
***

metadata.labels
  + one map entry added:
    team: ui-dev

spec.replicas
  ± value change
    - 2
    + 3

spec.template.metadata.labels
  + one map entry added:
    team: ui-dev

spec.template.spec.containers.nginx-container.image
  ± value change
    - nginx:1.24.0
    + nginx:1.25.0

–ext-diffオプションをつけることで、dyffの差分が確認できます。オプションを外せば従来の差分比較もできるので、使い分けたい方は上記の設定にして、オプションをつけるのがめんどくさい方はGitのエイリアスに登録してもよいかもしれません。

おわりに

yamlの比較の確認がしやすいdyffの紹介をしました。Kubernetesの運用の中で、yamlの設定差分の見落としは危険です。しかし、ServiceやDeploymentといった単純な単体リソースの比較であればdiffでもなんとなく差分比較できますが、HelmアプリケーションのValuesといった数百、数千行あるような設定ファイルをdiffで比較するのはかなりの苦行だと思います。ぜひともdyffをインストールして、その苦行から解放されてください。

参考

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。
エンジニア募集中!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です