本日の反省文です。ご査収ください。
元々、Cookbookを書く時に、
「AttributesにHashを使いたくなったらLWRPにしろ」
というオレオレルールがありました。
これは、Cookbookの再利用性を確保して見通しよくするために、
なんとなく決めた自分なりの基準の一つだったのですが、
今日(2014.10.09)、それを破った手抜きCookbookで問題が起きましたorz
Chefにはattributesを定義できる場所が色々ありますが、
それらはざっくり言うと以下の様な感じで扱われます。
(ソースを流し見して把握しただけなので、間違いがあるかもしれません。また、説明しやすいように若干正確な挙動とは異なっています。)
- それぞれで定義されているattributesをHash化する(というかそもそもHashみたいな感じ)
- それぞれのHashをそれぞれ末端まで再帰的にmergeする
- Hashの末端で被った部分は優先順位に応じて上書きする
参考までに該当箇所のソース
https://github.com/opscode/chef/blob/master/lib/chef/node/attribute.rb#L318https://github.com/opscode/chef/blob/master/lib/chef/mixin/deep_merge.rb#L130- https://github.com/opscode/chef/blob/master/lib/chef/node/attribute.rb#L383
- https://github.com/opscode/chef/blob/master/lib/chef/mixin/deep_merge.rb#L46
- https://github.com/opscode/chef/blob/master/lib/chef/mixin/deep_merge.rb#L74
問題は上記の2の部分で、
nodesやらrolesやらenvironmentsで定義したattributesの中にHashがあると、
それは「末端」ではないので、上書きではなくmergeされてしまいます。
つまり、上書きしたつもりがmergeされていて、
Cookbookのデフォルトとenvironmentsで定義した値が合わさって、
余計な設定が入ってしまったのです。
補足:
Cookbokkを書き直さずに上書きさせたい場合は、
override attributesに定義すると、とりあえず上手く行きます。
ということで、最後にもう一度…
「AttributesにHashを使いたくなったらLWRPにしろ」
手抜きは本当に(・A・)イクナイ!!