KeycloakからAWS SecretsManagerの認証情報を使ってDBに接続する
AWS RDSの接続情報をSecretsManagerで管理していて、定期的な認証情報のローテーションを行うというのは割とベタ?な構成かと思います。
そんな構成の中にKeycloakをECSに載せて動かしたい場合に、Keycloakは標準ではSecretsManagerから認証情報を取得することはできないので、
AWS Secrets Manager JDBC LibraryをKeycloakに組み込んでSecretsManagerから認証情報を取得できるようにしてみたいと思います。
- 1. Keycloakのコンテナを用意
- 2. AWS Secrets Manager JDBC Libraryと依存jarを用意
- 3. コンテナにjarを配置
- 4. コンテナ起動のためのパラメーター、環境変数の用意
- 5. デプロイしてコンテナを起動する
- まとめ
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を読み込んでくれるようになるとのこと(超ざっくり解釈ですが...)
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
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ってパラメーターがふんだんにあってドキュメントもそれなりに充実はしているんですが、 今回みたいな個々のケースでどう設定すべきなのか調べるとあまり出てこないんですよね。