こんにちは。小宮です。
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で個別実行しにくくはなりそう。)
PATHが通ってると何がうれしいかというと、 このあとで実行される予定のbashリソース内でのruby-buildによる処理が1回目のレシピ適用時からまともに動くようになります♪ ヘ(^o^ヘ)(ノ^o^)ノ ♪ ただruby-buildとかchefでやるとpackageリソースで配置するだけじゃなくてmakeとかが走るため時間かかってアレなので、 個人的にはpackerとかrpm自作にゆずりたいと思いました。
Ohaiでhostnameをリロードする方法については以下リンク先をご覧ください。Ohaiのプラグイン自作はしたことないです。 chef-solo - ohaiのhostnameの利用方法について - Qiita
以下も参考にさせていただきました。ありがとうございました。 Rubyを知らずにchefでrecipeを書くときのTips - 右往左往ブログ chef の ruby_block 内でリソースを実行する - Qiita rubyスクリプト内でリソース呼んでる場合に便利そうです。
では読んでいただいてありがとうございました。