Keycloak Ver.17でデフォルトとなったQuarkusディストリビューションについて

## はじめに
Keycloak Ver. 17よりQuarkus版のディストリビューションが正式採用されました。
従来のWildFly版のディストリビューションのサポートは2022年9月で終了するとアナウンスされており[^1]、早期の移行が推奨されています。
本記事ではQuarkusへの移行に伴う変更点を、その背景を含めてまとめます。

## なぜWildFlyからQuarkusへ移行したのか
QuarkusはKubernetesやサーバーレス環境に適したJavaアプリケーションを作るためのフレームワークの一種です[^2]。
[デザインドキュメント](https://github.com/keycloak/keycloak-community/tree/main/design/keycloak.x)によると、Quarkusへ移行する理由として起動時間やメモリ消費量の低減が目的とされています。また、QuarkusチームとRedHatのエンジニアであるSebastien Blancさんとの[対談動画](https://youtu.be/qNeDPgrytxE?t=289)で語られているように世の中のクラウドシフトに対応することが背景にあり、Keycloakをイミュータブルなリソースとしてクラウド環境にデプロイし、スケールアップやスケールダウンを容易にしたいと考えていると思われます。

## Keycloak 17への移行における主な変更点
[公式ドキュメント](https://www.keycloak.org/migration/migrating-to-quarkus)によると、Quarkusディストリビューションにおける大きな変更は以下の3つです。
- Keycloakの設定および起動方法の変更
- `/auth`パスの廃止
- カスタムプロバイダーのデプロイ方法の変更

## Keycloakの設定および起動方法の変更について
### 設定方法の変更
従来のKeycloakではWildFlyがXMLファイルから設定を読み取っていたため、`jboss-cli`を使ってファイルの設定を書き換えていました。Keycloak 17では、`keycloak.conf`という設定ファイル、あるいはCLIか環境変数で設定できます。

新しく設定ファイルを作った背景として、従来の設定ファイルはWildFlyが必要とする設定が含まれるため複雑であり、かつ正しく設定するためにWildFlyのドキュメントを読まなければならないといった課題を解決することが理由とされています[^3]。

たとえば、KeycloakのデータベースとしてPostgresを使う場合、以下の2つの方法で設定できます。
#### CLIで設定する場合
CLIで設定する場合は以下のようにビルドオプションとして設定を渡します。
本記事ではLinuxおよびMacでの使用を想定しますが、Windowsでは`kc.sh`を`kc.bat`とすることで同様に実行できます。
```
$ bin/kc.sh build --db=postgres
```
#### 設定ファイルを使う場合
設定ファイルを使う場合は`conf/keycloak.conf`に以下のように設定を記載します。
```
db=postgres
```
その後、後述する起動スクリプトを実行すれば設定が適用されます。

### 起動方法の変更
起動スクリプトは`standalone.sh`が廃止され、`kc.sh`が新しく追加されました。
このスクリプトで実行できるコマンドには`build`、`start`、および`start-dev`があります。

#### `build`コマンド
`build`コマンドは最適化されたKeycloakのサーバイメージを作成するために使います。
アプリケーション自体が再ビルドされるわけではなく、具体的には以下の最適化が実行されて
起動が高速化されます。。
- サーバ起動時にカスタムプロバイダーのレジストリを再作成することなく起動する
- 設定ファイルの内容を事前解析するため起動時の読み込み処理を削減する
- データベース特有のリソースを事前に設定、起動準備しておく
- ビルドオプションをサーバイメージに永続化し設定オプション読み込みの起動ステップを不要とする
  
ビルド時の設定オプションはCLIの引数または`keycloak.conf`に記載して設定できます。両方に記載がある場合、`keycloak.conf`の内容が優先されます。

#### `start`コマンド
`start`コマンドは本番環境としてサーバを起動するために利用します。
`start`コマンドで起動する前には必ず`build`コマンドでサーバイメージを作成することが必要です。また、起動オプションとしてホスト名、サーバ証明書のパス、証明書の秘密鍵のパスは必須となっています。したがって、最低限以下のオプションを付与する必要があります。
```
$ kc.sh start --hostname=your-host-name --https-certificate-file=/path/to/certfile.pem --https-certificate-key-file=/path/to/keyfile.pem
```
上記のオプションは`keycloak.conf`ファイルに記載して設定することもできます。
また、`--auto-build`オプションを付与することでビルドと起動を一連して実行できます。

#### `start-dev`コマンド
`start-dev`コマンドは開発環境としてサーバを起動するために利用します。
本コマンドで起動する場合はホスト名、サーバ証明書のパス、証明書の秘密鍵のパスは必要なく、オプションなしで起動できます。また、`start-dev`コマンドで起動した場合`theme`フォルダーに配置したカスタムテーマをKeycloak稼働中に読み込むホットデプロイが可能です。したがって、従来はカスタムテーマ開発時にキャッシュをOFFにする必要がありましたが、`start-dev`では不要です。`start`コマンドによる起動でもWildFly版と同じく以下のオプションをつけることでカスタムテーマのキャッシュを切ってホットデプロイすることもできますが、実際に本番環境でキャッシュを切るのは性能観点で望ましくありません。誤って設定が残ってしまうリスクを考えると`start-dev`を使えばよいと考えられます。

```
$bin/kc.sh start –spi-theme-static-max-age=-1 –spi-theme-cache-themes=false –spi-theme-cache-templates=false
```

## `/auth`パスの廃止
keycloak Ver.17からデフォルトコンテクストパスが`/auth`でなくルート（`/`）になりました。引き続き`/auth`に設定したい場合はビルドオプションで以下を設定する必要があります。

```
$ bin/kc.sh build --http-relative-path=/auth
```

また、`keycloak.conf`に記載してビルドしても設定できます。例えば、ここまでの説明で出てきたDB、ホストネーム、HTTPS、パスの設定をKeycloak.confにまとめると、以下のようなファイルを作成して`build`すれば設定されます。

```
db=postgres
db-username=your-user-name
db-password=password
db-url=jdbc:postgresql://localhost/keycloak
hostname=your-host-name
https-certificate-file=/path/to/cert.pem
https-certificate-key-file=/path/to/key.pem
http-relative-path=/auth
```

## カスタムプロバイダーのデプロイ方法の変更
WildFlyディストリビューションでは以下の2つの方法でカスタムプロバイダーのデプロイができました。
- `provider`ディレクトリ配下にプロバイダーを配置する
- `standalone/deployments`ディレクトリ配下にプロバイダーを配置する

Quarkusディストリビューションでは`provider`配下にプロバイダーのjarファイルを配置する方法のみとなり、ホットデプロイ機能がなくなったため`build`コマンドもしくは`start`コマンドオプションで`auto-build`を付与することによるビルドが必要となりました。

## おわりに
Keycloakバージョン17ではWildFlyベースからQuarkusベースへと変更するとともに、サーバの起動や設定方法が変更されました。`keycloak.conf`に記載する新たな設定方法は、従来の`jboss-cli`を使って設定しXMLファイルで確認する方法に比べてシンプルになったかと思います。最近出版された[Keycloak入門書](https://www.ric.co.jp/book/new-publication/detail/2081)に記載の内容もQuarkusディストリビューションでは操作に変更があります。今後はWildFly版とQuarkus版の変更点をより深く掘り下げたいと思います。


[^1]: [2023年までのKeycloakロードマップ](https://www.keycloak.org/2022/03/releases)

[^2]: [Quarkus 公式ページ](https://quarkus.io/about/)

[^3]: [Keycloak.X デザインドキュメント](https://github.com/keycloak/keycloak-community/tree/main/design/keycloak.x)