【Ruby】YAMLに環境変数を埋め込む

2021年3月7日Ruby

こんにちは、しきゆらです。
毎年12~2月は気分が落ち気味で何も手がつかない時期なんですが、今年は何もできてませんでした。
気が付いたら、前回の更新が11月ということに驚いています。

さて、今回はタイトルの通りYAMLに環境変数を埋め込みたいなぁと思って何とかしたのでメモしておきます。
YAMLは設定ファイルなどでよく作りますが、Gitで管理したいが重要項目は共有したくないことはよくあるかと思います。
こんな時、YAMLファイルを知っていそうな人経由で回していく運用とかをしているところもあるかもしれませんが、ずっとうまく回るわけはありません。
ということで、YAMLに必要項目を記載しておき、チーム内だけで見れるところに必要な情報を置いておけばよいだろう、という考えです。

方針としては、ファイルにそれっぽいマーカーをつけて置き、ファイル読み込み時に環境変数と置換してYAMLオブジェクトを作る感じです。
例としてはこんな感じ。

# YAMLファイルを文字列として読み込み
yaml_str = File.read("path/to/yaml.yml")
# ${ENV_VARIABLE}形式で埋め込んだ環境変数を置換する
yaml_str.gsub!(/\${\w*}/) do |matched|
  ENV[matched.gsub(/\W*/, "")]
end
 
# YAML文字列をオブジェクトに変換
YAML.safe_load(yaml_str, symbolize_names: true)

実際に挙動を見てみます。
上記のスクリプトを適当なメソッドにして動かしてみます。

 irb(main):001:1* def test(yaml_str)
 irb(main):002:2*   yaml_str.gsub!(/\${\w*}/) do |matched|
 irb(main):003:2*    ENV[matched.gsub(/\W*/, "")]
 irb(main):004:1*  end
 irb(main):005:1*
 irb(main):006:1*  YAML.safe_load(yaml_str, symbolize_names: true)
 irb(main):007:0> end
 => :test
 irb(main):008:0> test("token: ${SERVICE_TOKEN}")
 => {:token=>nil}
 irb(main):009:0> ENV["SERVICE_TOKEN"]
 => nil
 irb(main):010:0> ENV["SERVICE_TOKEN"] = "hogehoge"
 => "hogehoge"
 irb(main):011:0> ENV["SERVICE_TOKEN"]
 => "hogehoge"
 irb(main):012:0> test("token: ${SERVICE_TOKEN}")
 => {:token=>"hogehoge"}

${SERVICE_TOKEN}という文字列を環境変数の置換して、hogehogeという値を埋め込むことができています。
マーカーは自分で定義しているので、正規表現が書ければ好きな形式で表現できます。
本来はerbとかを使って埋め込んだほうがいらないバグが起きないかと思いますが、中でやっていることはこんな感じなので知っておくと便利かと思います。

今回は、ここまで。
おわり

Posted by shikiyura