LCL Engineers' Blog

バス比較なび・格安移動・バスとりっぷを運営する LCLの開発者ブログ

AWS EC2パラメータストアを利用したRails 秘匿情報の管理

DBの接続情報・APIキーなどの秘匿情報は、git管理下に置くべきではないですが、皆さんはどのようなに管理しているでしょうか?

先日のAWS Summit Tokyo 2017のDMM様の事例で、EC2 System Managerパラメータストアの紹介がありましたので、使ってみました。

※ タイトルにRailsとついてますが、特にRailsに依存する内容ではありません。

EC2 SystemManager パラメータストアとは

簡単に言うと、key/value形式のパラメータをAWSで集中管理できる仕組みだと理解しています。

主に、以下の特徴があります。

  • AWS API、CLIを利用してアクセス可能
  • KMSを利用してパラメータ値の暗号化が可能
  • IAMを利用して、各パラメータへのアクセス権を細かく制御可能

管理コンソールからの登録

EC2 Managemtn Consoleの左下に、Parameter Storeのメニューが有ります。Parameter Storeへアクセスするには、事前に、IAM Policyの「AmazonSSMFullAccess」を付与しておきます。 ( AmazonSSMFullAccessは、他の権限も含まれているため、厳密に権限管理する場合は、独自にポリシーを作成したほうが良いかと思います)

f:id:lcl-engineer:20170606214647p:plain

登録画面は、至ってシンプルです。この画面で登録するだけで、AWS CLI等で参照できるようになります。

f:id:lcl-engineer:20170606215310p:plain

AWS CLIからの参照

EC2インスタンスから、AWS CLIを使ってアクセスする方法を紹介します。

「AmazonSSMReadOnlyAccess」PolicyをAttachしたIAM Roleを作成し、EC2に割り当てておきます。

以下のコマンドでパラメータの取得可能です。

aws ssm get-parameters --region ap-northeast-1 --name production.db.user
->
{
    "InvalidParameters": [],
    "Parameters": [
        {
            "Type": "String",
            "Name": "production.db.user",
            "Value": "db_user"
        }
    ]
}

valueだけ取得したい場合は、queryを利用して以下のようにとれます。

aws ssm get-parameters --region ap-northeast-1 --name production.db.user  --query "Parameters[0].Value" --output text
-> db_user

パラメータストアのアクセス制御

ポリシーを独自で作成することで、細かいアクセス制御が可能です。 以下のポリシーの場合は、productionで始まるパラメータのみにアクセス可能です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1482841904000",
            "Effect": "Allow",
            "Action": [
                "ssm:GetParameters"
            ],
            "Resource": [
                "arn:aws:ssm:[region]:[AWSアカウント]:parameter/production.*"
            ]
        }
    ]
}

パラメータの命名ルールとして、環境名やサービス名を入れておくと、環境やサービス単位で適切な制御ができると思います。

KMSを利用した暗号化

暗号化については、クラスメソッド様の記事が非常に参考になりますので、紹介だけに留めておきます。

AWS KMS で EC2 Systems Managerパラメータストアを暗号化 | Developers.IO

Railsで利用する

例えば、Railsのデータベース接続情報で利用する場合は、database.ymlで環境変数から読み込むようにします。

production:
  <<: *default
  database: db
  username: <%= ENV['DATABASE_USER'] %>
  password: <%= ENV['DATABASE_PASSWORD'] %>
  host: <%= ENV['DATABASE_HOST'] %>
  port: <%= ENV['DATABASE_PORT'] %>

Railsの起動ユーザの .bash_profileで、パラメータストアから値を取得して環境変数にセットしておけば、Railsアプリから参照できるようになります。

export DATABASE_USER=$(aws ssm get-parameters --region ap-northeast-1 --name production.db.user --query "Parameters[0].Value" --output text)
export DATABASE_PASSWORD=$(aws ssm get-parameters --region ap-northeast-1 --name production.db.password --with-decryption --query "Parameters[0].Value" --output text)
export DATABASE_HOST=$(aws ssm get-parameters --region ap-northeast-1 --name production.db.host --query "Parameters[0].Value" --output text)
export DATABASE_PORT=$(aws ssm get-parameters --region ap-northeast-1 --name production.db.port --query "Parameters[0].Value" --output text)

bash_profileに書いておくと、該当ユーザでログインするたびに毎回、パラメータストアへのアクセスが発生してしまいます。 そのため、初回アクセス時に別ファイルに書き出し、2回目以降はパラメータストアではなくファイルから読み出すようにしています。

if [ -e ~/.credentials ]; then
  source ~/.credentials
else
  echo "export DATABASE_USER='"$(aws ssm get-parameters --region ap-northeast-1 --name production.db.user --query "Parameters[0].Value" --output text)"'" >> ~/.credentials
  echo "export DATABASE_PASSWORD='"$(aws ssm get-parameters --region ap-northeast-1 --name.production.db.password --with-decryption --query "Parameters[0].Value" --output text)"'" >> ~/.credentials
  echo "export DATABASE_HOST='"$(aws ssm get-parameters --region ap-northeast-1 --name production.db.host --query "Parameters[0].Value" --output text)"'" >> ~/.credentials
  echo "export DATABASE_PORT='"$(aws ssm get-parameters --region ap-northeast-1 --name production.db.port --query "Parameters[0].Value" --output text)"'" >> ~/.credentials
  source ~/.credentials
fi

パラメータストアの追加・更新があった場合は、一度ファイルを削除する運用にしていますが、もう少し良い方法がないか模索中です。

まとめ

Railsでの秘匿情報を管理する方法としては、「yaml_vault + AWS KMS 」が良いと思ってましたが、EC2 System Managerのパラメータストアも手軽にセキュアな環境が構築でき非常におすすめです。EC2 System Managerは地味ですが、他にも良い機能があるので、今後は是非活用していきたいと思います。

参考

EC2 Systems Manager のパラメータストアを利用したアプリケーション環境設定の管理 | Developers.IO

AWS Key Management Serviceを使ってconfigファイルを暗号化すると便利 - Qiita