Spring Bootで、AWSパラメータストアから簡単にDBのパスワードを取得する方法

こんにちは。 エキサイト株式会社の三浦です。

いよいよ今年も12月になりました。 「師走」の文字通り、忙しくしている方も多いのではないでしょうか。

この「12月」ですが、我々エンジニアにとっては別の意味も持っています。 すなわち、アドベントカレンダーの時期です!

というわけで、エキサイトホールディングスの今年のアドベントカレンダーの第一回目のブログを作成させていただくことになりました!

第一回目となる今回は、Spring Bootにおける、DBのパスワード管理問題のAWSパラメータストアを使用した簡単な解決方法について書かせていただきます。

DBのパスワード管理問題

アプリケーションでは、特に一定以上の規模になってくれば、多くの場合DBからデータを取得したり書き込んだりする必要が出てくるでしょう。 この時問題になってくるのが、「DBのパスワードをどうやって管理するか」です。

方法自体は以下のようにいくつか考えられますが、DBのデータの改竄はアプリケーションにとって致命的な問題となりうるので、パスワードが漏れてしまうことは絶対に避ける必要があります。

Github等で、その他のコードと一緒にバージョン管理する

Github等でバージョン管理してしまえば管理自体は簡単ですが、何かしらの事情でパスワードが漏れてしまうリスクが増加してしまいます。 可能であれば避けるべきでしょう。

デプロイサーバ等で管理し、デプロイのたびに書き込む形式にする

例えばデプロイサーバの環境変数やどこかのファイルに保存しておき、デプロイ時にアプリケーションコードにそのパスワードを書き込む方法です。 もちろんこれでも可能ですが、何かしらの理由でデプロイサーバのデータが失われたときに、パスワードのデータが消えてしまう可能性があります。 また、デプロイサーバやデプロイ方法が変更となった場合に、移行しなければならないでしょう。

AWS RDSの場合)IAMを使用した認証方法にする

AWS RDSでは、パスワードではなくIAMを使って接続をすることができます。 これができればそもそもパスワード自体が不要ではありますが、RDSでしか使用できないことや、IAMを使用した認証方法だと接続数によっては追加オーバーヘッドが発生してしまう場合があるという問題があります。

AWSパラメータストアを使用する

AWSには、パラメータストアというサービスがあります。 これは、AWS上で様々なデータを保存しておくことが出来るものですが、

  1. パラメータストアにパスワードを置いておく
  2. それをデプロイ時に取得し、アプリケーションコードに書き込む

とすることで、安全にパスワードを管理することができます。

問題点として、パラメータストアからデータを取得するのが面倒なこと、取得したデータをアプリケーションコードに書き込むのが面倒なことが上げられますが、実はSpring Bootであれば、それらを劇的に簡単にする方法があります。

そこで今回は、最後の「AWSパラメータストアを使用」してDBのパスワードを管理する方法について、Spring Bootで簡単に行うやり方について説明します。

Spring Cloudを使ったパラメータストアとの統合

Spring Bootには、Spring Cloudというプロジェクトが存在します。 ここではAWSとの統合を容易にする様々なライブラリが提供されているのですが、その中にパラメータストアとの統合を容易にするものも存在しているのです。

以下の設定だけで、パラメータストアからパスワードを取得出来るようになります。

アプリケーションコードの設定

アプリケーションコードの設定を行います。 必要なのは、 build.gradleapplication.yml のみです。

build.gradle

バージョンは適宜変更してください。

implementation 'io.awspring.cloud:spring-cloud-starter-aws-parameter-store-config:2.3.2'

application.yml

以下以外の設定は通常通りで大丈夫です。

spring:
  application:
    name: sample.application # パラメータストアのキーに使用します
  config:
    import: 'aws-parameterstore:'
  datasource:
    password: xxxx # ここにパスワードが入ります。上書きされるので、何を書いていても大丈夫です。

aws:
  paramstore:
    region: ap-northeast-1 # 使用したいパラメータストアのregionを設定してください
    prefix: /config # パラメータストアのキーのprefixに使用します

コードとしては、なんと実質これだけで「パラメータストアからのパスワードの取得」と「取得したパスワードのアプリケーションコードへの書き込み」ができたことになります!

AWSと接続するための認証

コードとしては上記で完成ですが、パラメータストアからデータを取得するためには、AWSと接続するための認証の設定が必要となります。 方法例として、以下のものが挙げられます。

環境変数で設定する

AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY という名前の環境変数を作成し、それぞれにパラメータストアにアクセスできる権限を持つIAMユーザのアクセストークン・シークレットトークンを入力します。

クレデンシャルファイルを使用する

AWS CLIaws configure コマンド等を使って、パラメータストアにアクセスできる権限を持つIAMユーザのクレデンシャルファイルを作成します。

ECSやEC2インスタンスプロファイルのクレデンシャルを使用する

実行環境のECSやEC2インスタンスプロファイルに、パラメータストアからデータを取得できるポリシーを追加します。

詳しくはこちらを御覧ください。

とりあえずローカルで確認するだけなら、環境変数かクレデンシャルファイルを使用すると良いでしょう。

パスワードの保存

ここまででパラメータストアからデータを取得する準備は整いました! 最後に、パラメータストアにデータを保存します。

キー名は、

{$aws.paramstore.prefix}/{$spring.application.name}_{$プロファイル}/spring.datasource.password

となります。 もし実行時に local というプロファイルを使用するのであれば、今回の設定の場合は

/config/sample.application_local/spring.datasource.password

というキーの値にDBのパスワードを入れれば大丈夫です。 念の為、「安全な文字列」として保存しておくと良いでしょう。

最後に

DBのパスワードは、バージョン管理する管理方法が他の方法と比べてあまりに簡単すぎるので、まだそうしてしまっているアプリケーションも多いのではないでしょうか。 保存しているGithubリポジトリをprivateにしておけばとりあえずは安全にも見えますが、例えば何かしらのヒューマンエラーでpublicにしてしまって、その間に見られてしまう可能性も考えられます。 そして、それによってDBのデータが改竄されてしまった場合、損害は計り知れないものとなってしまう場合もありうるでしょう。

幸いSpring Bootであれば、上記のように比較的簡単にセキュアな方法で管理ができるので、ぜひやってみてはいかがでしょうか。


さて、私の今回のブログは以上ですが、アドベントカレンダーはまだまだ続きます! ぜひ明日以降も御覧ください!

qiita.com