はじめに
株式会社日立製作所 OSSソリューションセンタの榎本和史です。普段はKeycloakなどのOSSを対象とした技術支援などを中心に活動しています。
今回はKeycloakの構築に関する小ネタとして、KeycloakのRealmの設定をExportしたjsonファイルの内容を比較する方法について書いてみます。
なぜ比較が必要か
Keycloakを構築する上で「設定したパラメーターが正しく設定されているか」は気になるポイントです。IaC(Infrastructure as Code)など人手を介さないデプロイにより、テスト済みのもの(=パラメーターが正しく設定済みのセット)を本番環境へ反映すればいいのでは、と普通は考えますが、全てのプロジェクトでそれを実現できるかというと難しく、様々な要因により手作業での構築、手作業での設定となるケースも存在します。
そのような場合でも、この「設定したパラメーターが正しく設定されているか」を手軽に確かめたいところです。
Keycloakの設定のうち、Realmなどのアプリケーションの設定は以下で設定できます。
- 管理コンソール(WebUI)
- Admin REST API
- CLI(kc.shなど)
上記のうちよく使われるのはやはり操作が直感的でやりやすい管理コンソールかと思います。ただ、正しく設定できたかのエビデンスを取ろうとすると、管理コンソール画面のスクリーンショットを取ったりして目視で確認となりがちです。ここまでで"設定"も"エビデンス取得"も"確認"も人手による対応となり、オペレーションミスを誘発しやすくなります。
人間の手作業はバグの温床なので、できるだけ避ける方向で考えると、管理コンソールの設定情報をExportして設定前後で比較し、想定通りの設定が全て行えているかをチェックするのが目視よりはベターとなるかと思います。
KeycloakではImporting and exporting realmsにRealmの設定をjson形式でImport/Exportする機能があります。今回はこの機能を利用して設定前後の値を確認してみます。
Realm設定のExport
今回はRealm設定の比較のためなので、管理コンソール上からファイルをExportします。
管理コンソールからExportしたファイルは、Client Secretなどの情報がマスクされて出力されるため、Import目的としては使えないのに注意してください。Import目的の場合には、起動コマンドbin/kc.sh exportを使いましょう。
管理コンソールからRealm設定のjsonをExportするには、"Realm setting"から右上の"Action"->"Partial export"を押下します。
Realm設定のDiff
Exportした設定前と後のjsonファイルのDiffを取って設定を変更した箇所を確認してみます。
まずは設定変更を繰り返した環境で、一部設定を変更した前後のjsonをWinMergeで比較した差分の検出箇所が以下のようになりました。
KeycloakのRealm設定のExportではリストなどの出力順序の出力順序は固定されていないため、設定の変更を繰り返していたりすると、このように設定を変更していない部分も大量に変更箇所として出力され、なかなか確認が大変です。まあ、そもそも構造を持つjson形式のファイルを単なるTextとして比較するのがまずいですね。
では、jsonの構造を意識したDiffを取ってみます。
keyでソートしてjq --sort-keysその結果を見てみます。
jq --sort-keys . sample-realm-before.json > sorted-sample-realm-before.json
jq --sort-keys . sample-realm-after.json > sorted-sample-realm-after.json
keyでソートされていますが、差分が出ている位置は変わりましたが量は変わりません。
Keycloakではjsonのkeyについては出力順序が固定されているようです。
ここの差分の中身を見ると、リストの中身が入れ替わったところが多数の差分として表示されているようです。
文字列で構成されるシンプルなリストであれば、多少の順序入れ替えでも見て分かりますが、KeycloakのRealm設定ではprotocolMappersなどのリストは順序入れ替えにより比較が難しい状況です。
jsonファイル全体で比較していると分かりづらいため、一旦protocolMappersだけを抽出して比較してみます。
jq '[.clients[].protocolMappers[]?]' sample-realm-before.json > pm-sample-realm-before.json
jq '[.clients[].protocolMappers[]?]' sample-realm-after.json > pm-sample-realm-after.json
では、抽出したprotocolMappersをソートしてみます。
ソートキーについては"name"を使用しますが、他にも"id"を使うのも良いかもしれません。
Keycloakではおおむね"id"がユニークキーとして扱えますが、リストによっては別のキーを使ってください。
jq '[.clients[].protocolMappers[]?] | sort_by(.name)' sample-realm-before.json > sorted-pm-sample-realm-before.json
jq '[.clients[].protocolMappers[]?] | sort_by(.name)' sample-realm-after.json > sorted-pm-sample-realm-after.json
protocolMappersの要素がソートされ差分を見るときのノイズが減りました。
具体的な箇所ごとに抽出してソートキーを指定する必要があり、全体を一括でという形にはなりませんが、変更項目がある程度絞れている場合であれば活用できます。
ここまでで素のExportファイルよりはある程度は目視でも見れるDiff結果になったかと思います。
このあたり上記以外にもいくらでも加工パターンや手段はあるかと思います。例えば、クライアントを同名で作りなおした場合のオブジェクトIDの差異を検出するか/無視するか、などです。
ただ、差分を過不足なく100%の精度で検出しようとすると沼にはまるので、設定を変更する部分などを意識して各プロジェクトごとに工夫するのが現実的かと思います。
まとめ
今回はKeycloakの構築の小ネタとして、KeycloakのRealmの設定をExportしたjsonファイルの内容を比較する方法を簡単にまとめました。
今回記載した内容以外にも、RFC6902 JavaScript Object Notion (JSON) Patchの規格で差分情報を生成して、Admin REST APIで差分のパラメーターを適用するなど、ExportしたRealm設定のjsonは活用方法は他にも考えられます。
本記事の内容が皆様のKeycloakの構築の一助となれば幸いです。




