私たちが銀行や大企業と仕事をするとき、Kafka が更地(グリーンフィールド)であることはほとんどありません。

多くの場合、Kafka はすでに何年も稼働しています。チームはそれに依存し、重要なデータがそこを流れ、プラットフォームには運用上の判断、命名規則、サービスアカウント、トピックパターン、アクセスルールといった長い歴史が蓄積されています。組織が Confluent Platform への移行を決断するころには、Kafka はもはや単なるメッセージングシステムではありません。本番環境を支える基盤の一部になっているのです。

この文脈は重要です。なぜなら、そのような環境での移行は技術的なプロジェクトであるだけではないからです。それはリスク管理の取り組みなのです。

Confluent 移行の最初のフェーズでは、最も安全なアプローチは通常、変更を可能な限り少なくすることです。目標は、プラットフォームの基盤を移し、それを安定させ、その後にようやくより大きな改善を導入することです。認証と認可もその一部です。既存の Kafka インストールは、しばしば Apache Kafka ACL に依存しています。なぜなら、ACL はオープンソース版 Kafka で利用できる組み込みの認可モデルだからです。

しかし Confluent Platform は、RBAC(ロールベースアクセス制御)も提供しています。RBAC は通常、組織規模で考えやすく、プラットフォームガバナンスとの相性がよく、Metadata Service、Control Center、Confluent for Kubernetes といった他の Confluent コンポーネントとも自然に統合できます。

そこで問題はこうなります。既存の ACL ベースの Kafka 環境から Confluent RBAC へ、アクセス制御を高リスクな手作業の移行に変えることなく、どうやって移行するのか?

これこそが、私たちが monedula-acl-rbac-converter を構築した理由です。

ACL から RBAC への移行が見た目より難しい理由

ごくわずかなトピックとユーザーしかない小さな Kafka クラスターは、手作業で移行できます。ACL を調べ、それに相当する RBAC ロールを決め、バインディングを作成し、アクセスを検証し、古い ACL を削除します。

しかし、成熟したエンタープライズ環境のほとんどは、そのような姿をしていません。

実際のデプロイでは、数百から数千もの ACL ルールが見つかることがあります。プラットフォームチームが作成したものもあれば、アプリケーションチームが作成したものもあります。自動化によって生まれたものもあります。古いけれど今も使われているものもあります。プレフィックス付きのトピックパターンを使うものもあります。すでに名前が変わってしまったサービスユーザーを参照しているものもあります。何年も誰も触れていないスクリプトからエクスポートされたものもあります。

その文脈での手作業の移行には、いくつかの問題があります。

  • 遅い、
  • ミスを起こしやすい、
  • レビューしづらい、
  • 繰り返しづらい、
  • 監査が難しい、
  • そしてクリーンアップを始めると危険になる。

新しい RBAC バインディングを作成することは、移行の半分にすぎません。より繊細な部分は、新しいバインディングが古い ACL と同じ実効アクセスを提供することを証明し、そのうえでようやく元の ACL を削除することです。

だからこそ私たちは、単に「ファイルを変換する」だけのツールは望みませんでした。私たちが望んだのは、移行ワークフローです。

このコンバーターが行うこと

monedula-acl-rbac-converter は、既存の Kafka ACL を読み取り、それを Confluent RBAC のロールバインディング計画に変換し、運用担当者が制御された監査可能な方法で移行を実行できるよう支援するコマンドラインツールです。

次のような、現実世界のさまざまなソースから ACL を読み取ることができます。

  • 稼働中の Kafka クラスター、
  • エクスポートされた kafka-acls.sh --list の出力、
  • JSON、YAML、または CSV のダンプ、
  • Strimzi の KafkaUser マニフェスト、
  • Confluent for Kubernetes のマニフェスト、
  • 稼働中の Kubernetes クラスター、
  • あるいは kafka-acls --add ... コマンドを含むシェルスクリプト。

この最後のケースは、ブラウンフィールド環境で特に役立ちます。多くのチームは、クリーンなエクスポートから始めるわけではありません。代わりに、そもそも ACL を作成した古いセットアップスクリプトを持っているのです。

たとえば、入力スクリプトには次のようなコマンドが含まれているかもしれません。

kafka-acls.sh \
  --bootstrap-server kafka.example.com:9093 \
  --command-config admin.properties \
  --add \
  --allow-principal User:svc-billing \
  --operation Read \
  --topic billing.events \
  --group billing-consumer

kafka-acls.sh \
  --bootstrap-server kafka.example.com:9093 \
  --command-config admin.properties \
  --add \
  --allow-principal User:svc-billing \
  --operation Describe \
  --topic billing.events

このコンバーターは、それらの ACL 定義を正規化された acls.json ファイルに抽出できます。そこから、レビュー済みの移行計画を作成し、スクリプトやマニフェストを出力し、Confluent MDS にバインディングを直接適用し、結果を検証し、古い ACL のクリーンアップスクリプトを生成できます。

高リスクな変更のために設計されたワークフロー

アクセス制御の移行にはガードレールが必要です。誤った権限は本番ワークロードを壊しかねません。広すぎる権限はセキュリティインシデントを引き起こしかねません。早すぎるクリーンアップステップは障害を招きかねません。

そのため、本番のワークフローは明示的でステップベースになっています。

1. extract       -> 正規化された ACL スナップショットを作成する
2. plan          -> ACL を RBAC 移行計画に変換する
3. apply dry-run -> MDS の変更をプレビューする
4. apply         -> RBAC ロールバインディングを作成する
5. verify        -> 実効アクセスを確認する
6. wait          -> ユーザーに新しい経路を使わせる
7. delete-acls   -> 古い ACL の削除スクリプトを生成する
8. review + run  -> クリーンアップを手作業で実行する

各ステップは、検査、レビュー、バージョン管理、あるいは変更要求への添付ができる成果物を生成します。

このツールは、計画と適用、適用と検証、検証と削除を意図的に分離しています。これにより、移行が考えやすくなり、規制された環境でも安全に実行できるようになります。

例:ACL セットアップスクリプトからの移行

出発点が kafka-acls.sh --add コマンドを含むシェルスクリプトであると仮定しましょう。

1. ACL を抽出する

まず、ACL を正規化された JSON 表現に抽出します。

monedula-acl-rbac extract \
  --from script \
  --input setup-acls.sh \
  --vars vars.yaml \
  --out runs/billing-batch-1/acls.json

オプションの vars.yaml ファイルは、スクリプトに変数が含まれている場合に役立ちます。ツールは未解決の値を推測しません。変数が存在する場合は、明示的に指定するか、移行前にスクリプトを事前展開しておくべきです。

この段階では、出力はまだスナップショットにすぎません。外部の状態は何も変更されていません。

2. 移行計画を作成する

次に、抽出した ACL をロールバインディング計画に変換します。

monedula-acl-rbac plan \
  --acls runs/billing-batch-1/acls.json \
  --scopes scopes.yaml \
  --rules rules.yaml \
  --principals principals.yaml \
  --out runs/billing-batch-1/plan.json

scopes.yaml ファイルは、RBAC バインディングの対象とすべき Confluent クラスターを特定します。オプションの rules.yaml および principals.yaml ファイルを使えば、運用担当者は変換を自分たちの環境に合わせて調整できます。たとえば、ソースのプリンシパルを MDS が期待するプリンシパル形式にマッピングできます。

計画ステップはレポートも生成します。これはワークフローの中で最も重要なレビューポイントの一つです。各ソース ACL が何になったかを示し、自動的にマッピングできなかったもの、あるいは自動変換すべきでないものにフラグを立てます。

3. レポートを読む

何かを適用する前に、運用担当者は生成されたレポートを読むべきです。

ここで移行作業が可視化されます。ブラックボックスの変換に頼る代わりに、チームは生成されたバインディングをレビューし、マッピングされなかった ACL を調査し、カスタムのマッピングルールが必要かどうかを判断できます。

DENY ACL は特別な注意に値します。Confluent RBAC には同等の拒否(deny)セマンティクスがないため、DENY ACL は黙って変換されることはありません。それらはレポートされ、別途処理されます。

4. 適用ステップをドライランする

MDS でロールバインディングを作成する前に、ドライランを実行します。

monedula-acl-rbac apply \
  --plan runs/billing-batch-1/plan.json \
  --mds-url https://mds.example.com \
  --mds-token-file ~/.confluent/token \
  --dry-run

ドライランは、実行されるであろう MDS 呼び出しをプレビューします。また、読み取りチェックも行い、既存のバインディングを冪等にスキップできるようにします。

これにより、運用担当者は最初の本当の変更の前に、もう一つのチェックポイントを得られます。

5. RBAC バインディングを適用する

ドライランの出力をレビューしたら、計画を適用します。

monedula-acl-rbac apply \
  --plan runs/billing-batch-1/plan.json \
  --mds-url https://mds.example.com \
  --mds-token-file ~/.confluent/token \
  --confirm

適用ステップは、Confluent MDS に RBAC バインディングを作成します。これは再実行可能なように設計されています。バインディングがすでに存在する場合は、スキップされます。

6. 実効アクセスを検証する

RBAC バインディングを適用したあと、それらが元々 ACL によって提供されていたアクセスを実際に付与しているかを検証します。

monedula-acl-rbac verify \
  --plan runs/billing-batch-1/plan.json \
  --mds-url https://mds.example.com \
  --mds-token-file ~/.confluent/token

これは、バインディングが存在するかどうかを確認するよりも強力です。目標は、元のプリンシパル、操作、リソースに対する実効アクセスを確認することです。

その区別は、アイデンティティの伝播、グループメンバーシップ、LDAP 連携、あるいはスコープの不一致によって、バインディングは存在するのに期待どおりに振る舞わない、といったことが起こり得るエンタープライズ環境で重要になります。

7. ACL 削除スクリプトを生成する

検証が成功したあと、そして運用担当者が定めたクールダウン期間を経たあとにのみ、ソースの ACL を削除すべきです。

このツールは ACL を直接削除しません。代わりに、運用担当者が検査して自分で実行するスクリプトを生成します。

monedula-acl-rbac delete-acls \
  --plan runs/billing-batch-1/plan.json \
  --verify runs/billing-batch-1/verify.json \
  --bootstrap-server kafka.example.com:9093 \
  --command-config admin.properties \
  --principal User:svc-billing \
  --confirm \
  --i-understand-this-is-destructive

生成される成果物には次のものが含まれます。

delete-acls.sh
deleted-acls.json
rollback.sh

これは意図的な人間によるチェックポイントです。運用担当者はスクリプトを開き、すべての kafka-acls --remove コマンドをレビューし、プリンシパルごとに一つずつ実行し、移行が安定するまでロールバックスクリプトを保持できます。

運用モデルごとに異なる出力

すべての組織が同じ適用モデルを望むわけではありません。

直接 MDS に適用することに抵抗のないチームもあります。一方、すべての変更を変更管理プロセス、GitOps フロー、または外部の CD パイプラインを通す必要があるチームもあります。

このコンバーターは、異なる種類の成果物を出力することで、それらのシナリオをサポートします。

# Confluent CLI のロールバインディングコマンドを含むシェルスクリプト
monedula-acl-rbac emit \
  --plan runs/billing-batch-1/plan.json \
  --format script \
  --out-dir emit/

# Confluent for Kubernetes のマニフェスト
monedula-acl-rbac emit \
  --plan runs/billing-batch-1/plan.json \
  --format cfk \
  --out-dir emit/

# MDS REST API に対する curl コマンド
monedula-acl-rbac emit \
  --plan runs/billing-batch-1/plan.json \
  --format mds-curl \
  --out-dir emit/

これにより、このツールは実地の移行作業にも、インフラの変更が別途の承認とデプロイのシステムを通らなければならない環境にも役立つものになります。

現実の移行の煩雑さに合わせて構築

私たちは、きれいなデモケースだけでなく、実際の Kafka 環境に現れる種類の入力や制約をサポートしようとしました。

それには次のものが含まれます。

  • 稼働中の Kafka からの抽出、
  • テキストエクスポート、
  • 構造化ファイル、
  • Kubernetes ネイティブのリソース、
  • 既存の Confluent for Kubernetes マニフェスト、
  • 古いセットアップスクリプト、
  • プリンシパルの再マッピング、
  • カスタム変換ルール、
  • ドライラン実行、
  • MDS への直接適用、
  • 出力されるスクリプトとマニフェスト、
  • 実効アクセスの検証、
  • 削除スクリプトの生成、
  • ロールバック成果物、
  • そして、再現可能な移行バッチのためのステータス/差分コマンド。

その結果が、探索にも本番グレードの移行にも使えるツールです。

小さな実験用には、ワンショットの convert コマンドが抽出、計画、スクリプト出力を単一のステップで実行できます。

monedula-acl-rbac convert \
  --from yaml \
  --input acls.yaml \
  --scopes scopes.yaml \
  --rules rules.yaml \
  --principals principals.yaml \
  > bindings.sh

本番では、監査成果物とレビューポイントを保持できるため、明示的なパイプラインが推奨される道筋です。

最後に

Kafka ACL から Confluent RBAC への移行は、単なる構文変換の問題ではありません。

それは、稼働中のデータプラットフォームの認可モデルに対する制御された変更です。大組織、とりわけ銀行や規制対象の業界では、その変更はレビュー可能で、再現可能で、監査可能で、可能なところでは元に戻せるものである必要があります。

私たちが monedula-acl-rbac-converter を構築したのは、同じパターンを繰り返し目にしてきたからです。Kafka はすでにそこにあり、ACL もすでにそこにあり、チームは移行の重圧の中で数百ものルールを手作業で翻訳することなく Confluent RBAC を採用したいと考えていました。

このツールは、移行プロセスを隠すためのものではありません。それを可視化するためのものです。

現在の状態を抽出する。目標とする状態を計画する。レポートをレビューする。変更をドライランする。慎重に適用する。実効アクセスを検証する。クリーンアップスクリプトを生成する。それらをレビューする。そして準備ができたときにのみ、古い ACL を削除する。

それが、私たちがアクセス制御の移行に望むワークフローのあり方です。

私たちは自分たちにとって役立つからこれを構築しました。他の人たちにとっても役立つことを願っています。

monedula-acl-rbac-converter は GitHub で見つけられます。バグを見つけたり改善の提案があれば、ぜひ issue を開いてください。