ryotatake blog

Webエンジニア

Rails 6.0で環境ごとにcredentialsを準備するとconfig/credentials.yml.encは読み込まれない

Rails 6.0で導入されたmulti environment credentialsの挙動で少しハマったので、同じように困る方のために記録を残しておきます。

環境

Rails 6.0.3.4

最初に結論

デフォルトで存在するconfig/credentials.yml.encと、その環境用に準備したconfig/credentials/$environment.yml.encがある場合、config/credentials.yml.encは読み込まれず、config/credentials/$environment.yml.encだけが読み込まれます。

今回ハマった内容

Rails 6.0からは、環境ごとにcredentialsのファイルを分けられるようになりました。
Add support for multi environment credentials. · rails/rails

普段はbin/rails credentials:editで編集すると、記載した内容は暗号化されてconfig/credentials.yml.encに保存されます。

環境ごとにファイルを分ける場合は、例えばdevelopment環境用のcredentialsファイルを用意するには次のようにします。

$ bin/rails credentials:edit --environment development

これでconfig/credentials/development.yml.encに設定が保存されます。

私は、config/credentials.yml.encconfig/credentials/development.yml.encがある場合は、config/credentials/development.yml.encの設定が優先されるがconfig/credentials.yml.encでの設定も使えるものだと思っておりました。

なので次のような設定をしていました。

# config/credentials.yml.enc

common_setting_1: hogehoge
# config/credentials/development.yml.enc

development_setting_1: fugafuga

しかしコンソールで確認してみると、

Rails.application.credentials.development_setting_1
=> "fugafuga"
Rails.application.credentials.common_setting_1
=> nil

config/credentials.yml.encの設定がうまく反映できておらず、何か設定が足りないのか、書き方が間違っているのか、、としばらく悩みました。

結局、config/credentials.yml.encconfig/credentials/development.yml.encがある場合はconfig/credentials/development.yml.encだけが読み込まれるという仕様でした。

これについては、DHHさんは

There's no merging. If you're in the development environment, and config/credentials/development.yml.enc is found, then that'll be loaded. We won't even try to do anything with config/credentials.yml.enc. We won't try to merge some intersection of both files either. These are separate files and separate stores of credentials.

https://github.com/rails/rails/pull/33521#issuecomment-412382031

と2つのcredentialsファイルをマージはしない、とはっきりコメントされていました。

bin/rails credentials:helpでヘルプを見ると、

The credentials command supports passing an --environment option to create an environment specific override. That override will take precedence over the global config/credentials.yml.enc file when running in that environment.

とあり、config/credentials/development.yml.encconfig/credentials.yml.encより優先されることは分かったのですが、そもそもconfig/credentials.yml.encが読み込まれていない、というのは想定外でした。