Rails 6よりサポートされたMulti Environment Credentialsをプロジェクトに導入する

## 開発環境
```
$ docker-compose -v
docker-compose version 1.25.5

$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]

$ bin/rails -v
Rails 6.0.3.1
```


## はじめに

`Rails 5.2`よりサポートされているCredentialsは、`Rails 6`より環境毎に秘匿情報を設定できるようになりました。`gem 'dotenv-rails'`で環境変数やAPIキーを管理すると、環境変数を追加する度に`.env`の更新内容を他の開発メンバーに共有する必要があります。Herokuを使用している場合は、開発環境とは異なる環境変数をHeroku上に追加設定する必要があるためちょっと面倒...これらの煩わしさから解放してくれる点で、`Multi Environment Credentials`は素敵ですね✨ただし、生成した環境毎のkeyは`.gitignore`されるので自身のメモ帳などに記述して、他の開発メンバーに共有しましょう。

## Multi Environment Credentials導入後のディレクトリとファイル構成
```
# 本記事とは関連しない箇所は省略
$ tree .
.
...
├── config
... ...
│   ├── credentials
│   │   ├── development.key
│   │   ├── development.yml.enc
│   │   ├── production.key
│   │   ├── production.yml.enc
│   │   ├── staging.key
│   │   └── staging.yml.enc
│   │   ├── test.key
│   │   └── test.yml.enc
│   ├── credentials.yml.enc
... ...
│   ├── master.key
... ...
```

開発環境、ステージング環境、本番環境に`Multi Environment Credentials`を導入すると、上記のようなファイル構成になります。`config`ディレクトリにグローバルなkey(master key)と暗号化された設定内容、`credentials`ディレクトリに環境毎のkeyと暗号化された設定内容が配置されます。

## Masterのcredentials keyを生成・秘匿情報の編集
```
$ EDITOR=vim bin/rails credentials:edit
```

`Rails 5.2`と同様ですね。`config/master.key`と`config/credentials.yml.enc`が存在しない場合は生成され、存在する場合は既存のkeyが参照されてvimが起動するはずです。Docker環境で`File encrypted and saved.`と言われてvimが起動しない場合、アプリケーションコンテナ内でそっと`apt install -y vim`を叩いてあげましょう😌

## 環境毎のcredentials keyを生成・秘匿情報の編集

```
# テスト環境
$ EDITOR="vim" bin/rails credentials:edit -e test

# 開発環境
$ EDITOR="vim" bin/rails credentials:edit -e development

# ステージング環境
$ EDITOR="vim" bin/rails credentials:edit -e staging

# 本番環境
$ EDITOR="vim" bin/rails credentials:edit -e production
```

開発環境なら、`-e development`という感じでオプションで環境を指定します。ちなみに、`--environment=development`という指定も同じです。


## 環境毎のcredentialsを確認

```
# テスト環境
$ bin/rails credentials:show -e test

# 開発環境
$ bin/rails credentials:show -e development

# ステージング環境
$ bin/rails credentials:show -e staging

# 本番環境
$ bin/rails credentials:show -e production
```

こんな感じで環境をオプション指定してコマンドを叩くと、以下のように環境毎に設定した値を確認することができます。

```
aws:
  access_key_id: 123
  secret_access_key: 345
```

## credentialsへのアクセス

```
# 本番環境の場合
$ bin/rails c -e production

# 設定内容を確認
pry(main)> Rails.application.credentials.config
=> {:aws=>{:access_key_id=>123, :secret_access_key=>345}}

# 設定値にアクセス
pry(main)> Rails.application.credentials.aws[:access_key_id]
=> 123

# この書き方も同じ
pry(main)> Rails.application.credentials.dig(:aws, :access_key_id)
=> 123
```

アプリケーション内で、設定した値を使用したい場合は上記のように設定値にアクセスできます。
`Rails 5.2`と同様の記述ですが、環境毎に設定した値を読み込んでくれます👀

## CircleCIの設定

テストを通すために、CircleCIがテスト環境のcredentialsを読み込める必要があります。
`Projects > プロジェクト名 > Project Settings > Environment Variables`より設定できると思います。
`Name*`には`RAILS_MASTER_KEY`、`Value*`には`config/credentials/test.key`に書かれているkeyを設定してください。

## おまけ

### credentialsの設定値が反映されない！

ローカルのRailsサーバを再起動してください。Dockerの場合は、コンテナ停止（ダメならコンテナ破棄）後に再起動してみましょう。

### 環境毎のkey無くしたらどうするの？

そんなあなたに朗報です。`config/credentials/環境名.key`と`config/credentials/環境名.yml.enc`を削除して、`$ EDITOR="vim" bin/rails credentials:edit -e 環境名`を叩くだけです。

開発環境の場合、`config/credentials/development.key`と`config/credentials/development.yml.enc`を消去して、`EDITOR="vim" bin/rails credentials:edit -e development`を叩くと、消去した2ファイルが再生成されます。`config/credentials/development.key`を覗くと、再生成されたkeyが記述されているはずです✏️

## 参考
- [Rails 6 adds support for multi environment credentials](https://blog.saeloun.com/2019/10/10/rails-6-adds-support-for-multi-environment-credentials.html)
- [Add support for multi environment credentials. #33521](https://github.com/rails/rails/pull/33521)
- [Rails 5 から 6 にかけての secretes / credentials 周りの変遷](https://qiita.com/megane42/items/539812678773c60b7c8a)