LCL Engineers' Blog

夜行バス比較なび・格安移動・高速バス比較を運営する 株式会社LCL開発者のブログ

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

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

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

【資料公開】AWS Summit Tokyo 2017にてDMMのAWS移行について紹介してきました - DMM.comラボエンジニアブログ

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)

サーバプロビジョニングを自動化する場合は、Chef等で自動的に上記の内容をセットするようにしとけば良いと思ってますが、他にもっといい方法があるかもしれません。

まとめ

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

参考

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

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