✍️blog

技術系のこととか

KeycloakからAWS SecretsManagerの認証情報を使ってDBに接続する

AWS RDSの接続情報をSecretsManagerで管理していて、定期的な認証情報のローテーションを行うというのは割とベタ?な構成かと思います。

そんな構成の中にKeycloakをECSに載せて動かしたい場合に、Keycloakは標準ではSecretsManagerから認証情報を取得することはできないので、

AWS Secrets Manager JDBC LibraryをKeycloakに組み込んでSecretsManagerから認証情報を取得できるようにしてみたいと思います。

github.com

1. Keycloakのコンテナを用意

今回の方針としてはKeycloakの公式dockerイメージに手を加えてSecretsManagerへ対応をしたいので
とりあえず、公式イメージを指定したDockerfileを用意します。

FROM quay.io/keycloak/keycloak:21.1

# SecretsManagerに対応するために何かをする...

ENTRYPOINT /opt/keycloak/bin/kc.sh start-dev

2. AWS Secrets Manager JDBC Libraryと依存jarを用意

AWS Secrets Manager JDBC Libraryと依存するライブラリのjarを用意します。
やり方はいろいろあると思いますが、私はMaven Reoisitoryから直接jarをダウンロードしました。

https://mvnrepository.com/mvnrepository.com

ダウンロードしたjarは以下です。

  • aws-secretsmanager-jdbc-1.0.11.jar
  • aws-secretsmanager-caching-java-1.0.2.jar
  • aws-java-sdk-core-1.12.252.jar
  • aws-java-sdk-secretsmanager-1.12.252.jar
  • commons-logging-1.2.jar
  • ion-java-1.0.2.jar
  • jmespath-java-1.12.252.jar
  • joda-time-2.8.1.jar
  • org.jacoco.agent-0.8.8.jar

3. コンテナにjarを配置

公式ドキュメントに書いてありますが providersディレクトリにjarを入れて keycloakのbuildコマンドを実行すると
そのjarを読み込んでくれるようになるとのこと(超ざっくり解釈ですが...)

www.keycloak.org

Keycloakはコンテナ起動時にbuildコマンドを実行してくれるようなので(もしかするとstart-devの時だけかもですが。。。)
COPYコマンドで2.で用意したjarをprovidersディレクトリに入れておきます。

FROM quay.io/keycloak/keycloak:21.1

# libs以下にjarを入れておく
COPY ./libs/* /opt/keycloak/providers/.

ENTRYPOINT /opt/keycloak/bin/kc.sh start-dev

4. コンテナ起動のためのパラメーター、環境変数の用意

事前準備は基本的には以上でOKなので、あとはSecretsManagerを参照、AWS Secrets Manager JDBC Library用のJDBCドライバを
使用するための設定をしていきます。

起動時パラメーターの追加

XA transactionはサポートしていないようなので、OFFにしておきます。

FROM quay.io/keycloak/keycloak:21.1

# libs以下にjarを入れておく
COPY ./libs/* /opt/keycloak/providers/.

# XA Transactionの使用をOFFにする
ENTRYPOINT /opt/keycloak/bin/kc.sh start-dev --transaction-xa-enabled=false

www.keycloak.org

providers以外のjarが入っているフォルダに格納しても読み込んでくれた気がします。。。

DB接続情報を環境変数に設定

起動時パラメーターでもよいですが、環境変数に以下を設定します。

変数名 コメント
KC_DB mysql RDS for MySQLの場合。 未指定だとKC_DB_DRIVERのドライバを参照してくれません。。。
KC_DB_DRIVER com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver
KC_DB_URL jdbc-secretsmanager:mysql://${RDS_HOST}:3306
KC_DB_PASSWORD SecretsManagerのSecretId
KC_DB_USERNAME SecretsManagerのSecretId

5. デプロイしてコンテナを起動する

上記の設定を持ってしてコンテナを起動させればおそらくKeycloakがRDSを参照し、
RDSの接続情報としてSecretsManagerの値を使用してくれます。
また、SecretsManagerでローテーションが発生しても追従してくれます。

まとめ

私の場合はKeycloakをまじめに運用という訳ではなく、開発用に用意したかったのでおそらく、
運用を考えると微妙な箇所があるはずですが、providersディレクトリにjarを配置して読み込ませるという流れと、
各パラメーターの設定は変わらないのかなと思います。

Keycloakってパラメーターがふんだんにあってドキュメントもそれなりに充実はしているんですが、 今回みたいな個々のケースでどう設定すべきなのか調べるとあまり出てこないんですよね。

via GIPHY