Rails 環境別の設定ごと secrets.yml -> credentialへ移行
こんにちは。MUGENUPの林です。
私の担当サービスは、かつてRails 5.1以下を使っていた名残で、secrets.yml
で秘密情報を管理していました。
※現在の バージョンは 5.2.3 です。
secrets.yml
とdatabase.yml
が手動管理ということは、変更漏れによるエラーが発生してしまう可能性が高く危険です。
credentialへ移行し、変更の必要のないmaster.keyのみ手動管理する方法に切り替えることにしました。
credentialはRails5.2より追加されました。
credential作成
EDITOR="vim" bin/rails credentials:edit
のコマンドで編集画面が表示されます。
EDITOR="vim"
は作業環境でエディター設定をしている場合は省略可能です。
以下、初期の中身です。
# aws: # access_key_id: 123 # secret_access_key: 345 # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies. secret_key_base: 〜シークレットキー〜
secret_key_base は残し、既存のconfig/secrets.yml
をそのままコピーしてペーストしましょう。※ 理由は最後に
secret_key_base: 〜シークレットキー〜 default: &default development: <<: *default test: <<: *default staging: <<: *default production: <<: *default
といった形でコピー&ペーストすることで、環境別の設定もそのまま引き継げます。
保存すると、config/credentials.yml.enc
とconfig/master.key
が出来上がります。
.gitignore
では
# Ignore master key for decrypting credentials and more. /config/master.key
が追加されています。
credentialsは、環境別の設定をソースコード側で自動参照してくれないので、
ソースコード内のRails.application.secrets
を
Rails.application.credentials[Rails.env.to_sym]
と置き換えましょう。
config/database.yml は?
host: <%= Rails.application.credentials[Rails.env.to_sym][:db][:host] %> password: <%= Rails.application.credentials[Rails.env.to_sym][:db][:password] %>
host と password だけ credentials に任せる形にして、秘密の情報を無くし、 Gitの追跡対象に追加しました。
.gitignore
から
/config/database.yml
を消すことで、コミットができるようになります。
circleCIは?
設定のEnvironment Variables
からRAILS_MASTER_KEY
を環境変数(Name)として追加できるので、
master.keyの中身をValueに入れて追加します。
capistranoは?
手動管理していたconfig/secrets.yml
, config/database.yml
に対して貼られていたシンボリックリンクを、master.key
に置き換えます。
先に対象サーバーのシンボリックリンク先になるファイルを設置しましょう。
(例: [Railsのソースコードのあるパス]/shared/config/master.key)
config/deploy.rb
でデプロイ時の設定が行われているので、こちらを書き換えましょう。
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml') ↓ set :linked_files, fetch(:linked_files, []).push('config/master.key')
他にもsetup等でconfig/secrets.yml
, config/database.yml
がある場合は、適宜置き換えてください。
以上で完了です!
secret_key_base は、development / test と staging / production で取得方法が変わる
(development / test はダミーの文字列を自動生成して通ってしまう)
ようなので、慎重にご対応ください。
※secret_key_baseだけは特別対応をします!
Before
default: &default development: <<: *default secret_key_base: 〜今までのシークレットキー〜
のように、環境別に secret_key_base を設定していた場合はそちらを消し、
After
secret_key_base: 〜シークレットキー〜 default: &default development: <<: *default
と、defaultの外に、credential作成時に作られた最新のシークレットキーを書きましょう。
- Rails本体が secret_key_base を参照するときの
Rails.application.credentials.secret_key_base
をRails.application.credentials[Rails.env.to_sym].secret_key_base
と置き換えることができない - credentialsを初めて作成したときに secret_key_base が自動生成されることから、 credentialsと secret_key_base は1:1で、環境別に用意するものではなくなったと推測
以上の理由から、 secret_key_base は一つに統一し、Rails.application.credentials.secret_key_base
で呼び出せる形に整えることにしました。
ちなみに、環境別の設定に書くと
Missing 'secret_key_base' for 'staging' environment, set this string with 'rails credentials:edit'
というエラーが出てしまいます。