• chefのruby_blockを用いて環境変数を再読み込み

    こんにちは。小宮です。 chefでいろいろ自動化していくうちに、途中で変更された値というか変数を使いたい場合が出てくるのかなと思います。 1回目は上手くいかないけど2回目は上手くいくというような冪等にならない怪現象を解決したいと思う時がそのうちきます。 そんなとき、、 ohaiで値がとれる場合はそれを使いなければohaiのプラグインを自作するか、 ruby_blockを書いたり、notifiesで:immediatelyとかつけて呼び出すって感じの対応が必要になったりします。。 何言ってっかわかんねえ!と思うかたは以下のリンク先にchefの実行順序に関して書かれているので見てみるといい気がします。 Chefのレシピは上から下に実行されるという誤解 | Engine Yard Blog JP これだけだと不親切かもしれないので以下ご参考まで。 template "/etc/profile.d/rbenv.sh" do not_if "grep rbenv /etc/profile.d/rbenv.sh" source "rbenv.sh.erb" action :create notifies :create, "ruby_block[initialize_rbenv]", :immediately end ruby_block "initialize_rbenv" do block do ENV['RBENV_ROOT'] = node[:rbenv][:root] ENV['PATH'] = "#{node[:rbenv][:root]}/bin:#{node[:rbenv][:root]}/shims:#{node[:ruby_build][:bin_path]}:#{ENV['PATH']}" end action :nothing end 少し解説しますと、 chefではレシピ中での改変を前提とした処理はくふうがひつようで、 rubyで書かれた処理はconvergeの手前で行われてしまってその時点では途中の改変を認識できないようです。(だから2回目に成功する) ruby_blockリソースはconvergeのタイミングと同じ時に動くようです。 特定のリソースの処理が行われるときだけ実行したい場合にはそのリソースのnotifiesにはタイミングを指定できます。(:immediatelyとか:delayedとかあるらしい) この場合、ruby_blockリソースのactionにはnothingを指定しておき、templateリソースでprofileの設定を置いて:immediatelyをnotifiesに指定することで ただちに変数の再読み込みが実行される、という話になります。(レシピを分けてる場合にnotifiesつかうと-oで個別実行しにくくはなりそう。)
    ...