About
タイトルだけを見ると何を当たり前の事をと思われると思いますが
Ruby on Railsではdevelopmentやproductionでの変数を切り替える方法がいくつかあります。
プログラム内で分岐する
def switch_var
case Rails.env
when 'production' then 'var of production'
when 'development' then 'var of development'
else 'default var'
end
end
こんなコードを書いている人もいると思います。
私も昔書いていましたが、何度か変数の変更が入ると変更すべきコードを探すのが億劫になります。
dotenv-rails
https://github.com/bkeepers/dotenv
.envファイルを読み込む事で各環境での変数を定義します。
ただ、.envはgitへのコミット非推奨な割に
dotenvとrailsが密になってしまいstaging環境やproduction環境を構築する際に窮屈さを感じました。
ただ、ローカル環境においてはdocker-composeと.envを組み合わせるという方法はアリだと思います。
config設定用のgemを利用する
他にも色々ありますが、yamlでconfigを管理する様なgemがあります。
それなりに便利なので一時期使っていましたが、
結局gemに依存するとメンテナンスコストもかかってしまうので
特にマイクロサービスレベルでの環境変数程度で有ればgemは不要だと私は思いました。
環境変数をアプリケーションに渡す
test, development環境
Docker前提で作っているのでdocker-composeで渡します。
CI上でもdocker-compose.ymlを専用に作っておいてそちらを利用しています。
version: '3'
services:
web:
environment:
- RAILS_ENV
- RACK_ENV
- AWS_BUCKET_NAME=xxxx
- AWS_ACCESS_KEY_ID=xxxx
- AWS_SECRET_ACCESS_KEY=xxxx
何も書かないとhostの環境変数が使われます。
production環境
マイクロサービスをTerraformで定義しています。
ECSのタスク定義で渡します。
resource "aws_ecs_task_definition" "task" {
container_definitions = data.template_file.service_container_definition.rendered
}
data "template_file" "service_container_definition" {
template = file("./templates/container_definitions.json.tpl")
}
[
{
"environment": [
{
"name": "RAILS_ENV",
"value": "production"
},
{
"name": "RACK_ENV",
"value": "production"
},
{
"name": "AWS_BUCKET_NAME",
"value": "xxxx"
},
{
"name": "AWS_ACCESS_KEY_ID",
"value": "xxxx"
},
{
"name": "AWS_SECRET_ACCESS_KEY",
"value": "xxxx"
}
]
}
]
実際にはアプリケーションケーションの規模によって
最適なツールが有るのかも知れませんが
マイクロサービスにおいてはこういう形で渡した方が見通しも良くなっていると思いました。