Rails
capistrano
Rails5
dotenv

secrets.ymlや環境変数をRails 5.2のEncrypted Credentialsに移行する

Encrypted Credentialsとは

これまでは、secret_key_baseや外部APIのアクセスキーなどの秘匿情報はsecrets.ymlに記述し、リポジトリにpushしないように気をつけつつ、デプロイ時にそれを本番サーバーに設置していました。他にもdotenvを使ったり環境変数を直接設定したりと方法はいくつかありますが、いずれにせよ秘匿情報のバージョン管理ができませんでした。

Rails5.2から導入されたEncrypted Credentialsを使うことによって、秘匿情報をまとめて暗号化してリポジトリに含めておくことができるようになりました。Encrypted secretsとは何だったのか。

それに伴ってデプロイ周りに少し手を入れる必要がありましたので、メモがてらまとめてみます。

暗号化された秘匿情報と鍵の生成

Railsを下位バージョンからアップデートした場合、秘匿情報ファイルと鍵ファイルを生成する必要があります。

$ EDITOR=vim bin/rails credentials:edit

エディタが開き、初期状態ではこのようになっています。

# aws:
#  access_key_id: 123
#  secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one $
secret_key_base: fd48be30aa33f5934ef1178c3f83221de9b6b58418f7270dbd6b4fed5d8d2139f762c975d05a2e3db470b31a227efc6c15185a94ff9ab10f7917e22804ca31da

これまでは以下のように環境毎にグルーピングされていましたがEncrypted Credentialsではproductionで使う情報のみを管理します。

secrets.yml
development:
  hoge: fuga
production:
  hoge: fuga

環境毎にCredentialsを使いたい場合は @sinsoku さんのエントリーをご参照ください。
http://sinsoku.hatenablog.com/entry/2018/02/10/222120

内容を保存すると下記のファイルが生成され、.gitignoreにmaster.keyが追加されます。

  • config/credentials.yml.enc
  • config/master.key

値の呼び出し方

hoge: fuga
aws:
  access_key_id: 123
  secret_access_key: 345

と設定した場合、

Rails.application.credentials.hoge # => "fuga"
Rails.application.credentials.aws # => {:access_key_id=>123, :secret_access_key=>345}
Rails.application.credentials.aws[:access_key_id] # => 123

このように取り出せます。

Devise

deviseを使っているアプリケーションで、secret_keyを環境変数などで独自に定義している場合は、それもcredentialsに移すとよいでしょう (コメントアウトすればデフォルトでRailsのsecret_key_baseが使われるのでこの手順は不要です)。

config/initializers/devise.rb
# before
config.secret_key = ENV['DEVISE_SECRET_KEY']
# after
config.secret_key = Rails.application.credentials.devise_secret_key

デプロイ

Capistrano

secrets.ymlの内容を全てcredentials.yml.encに移し終えたらデプロイ設定を変更します。
これまではリリースバージョン間でsecrets.ymlをシンボリックリンクにして共有していましたが、それをmaster.keyに置き換えます。

deploy.rb
append :linked_files, 'config/database.yml', 'config/master.key'

最後にデプロイ先サーバーにローカルと同じshared/config/master.keyを設置すれば完了です。

Heroku

master.key を直接置くのではなく環境変数としてセットします。あとは普通に git push heroku でデプロイできます。

$ heroku config:set RAILS_MASTER_KEY=`cat config/master.key`

所感

secrets.ymlも今まで通り使えるそうなので、特に必要がなければ無理に移行しなくても良いかなと思います。
自分の場合は本番サーバーにしか残されていない環境変数が結構あり、それらを安全にgit管理できるようになったのでメリットがありました。
以上です。