Posted at

rebar3で環境毎の変数設定を適用する

More than 3 years have passed since last update.

※ Erlang勉強しはじめたばかりなのでベストプラクティスではないかもしれません


モチベーション

Erlangプロジェクトで、外部リソースを参照する必要があり環境ごとにエンドポイント設定を変えたい…という場合があります。

例えば、Erlangアプリケーションから外部Redisを参照するような場合です。

{ok, RedisHost} = application:get_env(my_application, redis_host).

ベタ書きでホスト情報をコード中に書いていくのではなく、上記のように、アプリケーションのコードから動的にホスト情報を取得したいです。


rebar3で環境ごとのapplication environment variableを設定する


rebar3のProfileについて

rebar3にはProfileという機能があります。以下のようなことが簡単にできます。



  • rebar.configに任意の設定をprofile名とひもづけて書いておくことができる


  • rebar3コマンドにrebar3 as <profile> <command>のような形式でprofile名を与え、任意のprofile設定をコマンド実行時に適用することができる

rebar3では内部でrelxを利用してリリースパッケージを作成しています。また、rebar.config内にrelxのconfigをそのまま書くことができます。

relxのconfigにはsys_configというものがあり(configuration · erlware/relx Wiki)、ここではerl -config <config>のconfig fileとして指定するファイルパスを設定することができます。

(※Erlangのconfig設定についてはこちらを参照しました Erlang -- config

この機能を利用して、以下のようにすれば環境ごとの変数設定ができそうです。


  • 環境ごとにconfig fileを用意する

  • 環境ごとにrebar3のProfileを用意する


  • rebar.config内でProfile設定ごとにconfig fileを切り替えるような設定をする


rebar.configでProfile設定を追加する例

下記のように環境毎のconfig fileを用意します。

%% config/sys.config

[
{my_application, [
{redis_host, "127.0.0.1"}
]}
].

%% config/sys.config.production


[
{my_application, [
{redis_host, "10.0.0.1"}
]}
].

rebar.configでは、productionというProfile設定を追加します。Prodile設定production以下にrelxのsys_config設定を追加します。

%% rebar.config


%% ... 省略
{relx, [
{release,
{my_application, "0.0.1"},
[my_application, sasl]},

{dev_mode, true},
{include_erts, false},
{vm_args, "./config/vm.args"},
{sys_config, "./config/sys.config"}, %% 開発環境用のsys.config
{extended_start_script, true}
]}.

{profiles, [
%% ※必要に応じてdefault profile設定を追加
{production, [
{relx, [
{dev_mode, false},
{sys_config, "./config/sys.config.production"} %% 本番環境用のsys.config
]}
]}
]}.

Profileで設定した項目の優先順ですが、2016/06/29現在ドキュメントでは下記のように説明されています


  1. Profile設定のdefault


  2. REBAR_PROFILE環境変数


  3. asで指定されたProfile

  4. rebar3コマンド設定で指定されたProfile設定

上記のrebar.configでは、標準のrelxの設定を書いたうえでproduction環境用のProfile設定を書いています。

production環境用のリリースパッケージを作る場合はrebar3 as production releaseコマンドを使えば、rebar3がrelxのsys_config設定として./config/sys.config.productionを参照してくれます。

今回の例だと、rebar3 as production releaseしてできたリリースパッケージ中のコードで{ok, RedisHost} = application:get_env(my_application, redis_host)すると、Redishost10.0.0.1となります。


rebar3を使ってリリースパッケージを作成

前述したように、production環境用のリリースパッケージはrebar3 as production releaseで作成することができます。

今回の例ではProfileをproductionしか用意していませんが、rebar.configにdevelopment, testなどのProfile設定を追加しておくと環境ごとに細かく設定を切り替えることができるので便利そうです。