Apacheなどの設定ファイルを書くとき、メインの設定ファイルから各機能毎の小さい設定ファイルをインクルードするのが定番かと思います。
Include conf.d/listen.conf
Include conf.d/user.conf
よく見ますよね。
erbのrenderを使ってインクルードする方法もある
Chefで設定ファイルを書くときは、上記のようにしてもいいのですが、erbのrender
メソッドを使ってインクルードする方法もあります。
<%= render "listen.conf.erb" %>
<%= render "user.conf.erb" %>
この場合は、Chef側であらかじめ設定ファイルが連結された上で、1個の巨大なhttpd.confがサーバに配置されることになります。
「巨大な1個の設定ファイル」は一見ダサく見えますが、実は意外とメリットもあるのです。
インクルードするファイルが増えたり減ったりした場合に、レシピを修正しなくてよい
Include方式の場合、設定ファイルを追加したり削除したりしようとすると、Include文を追加/削除するだけでなく、レシピのtemplateリソースの記述も修正する必要があります。
%{
listen.conf
user.conf # ← コレ
}.each do |file|
template "/etc/httpd/conf.d/#{file}" do
source "#{file}.erb"
end
end
このレシピを直すというのが意外に面倒で忘れがちです。
renderの場合はレシピの修正が不要です。
renderの方が削除時の事故が起こりにくい
Chefはファイルの削除が苦手だと言われていますがその通りです。
例えばconf.d/user.conf
が不要になったとして、テンプレートファイルとレシピからそれを削除したとします。
ところがChefのレポジトリ上で消してもサーバには設定ファイルが残ってしまうため、Include conf.d/*.conf
のような記述があると残留したファイルが読み込まれてしまいます。
対策として、サーバ上の不要ファイルを手動で削除したり、fileリソースのaction :delete
などを使って消したりする必要があります。これはかなり面倒です。
一方erbのrenderを使う場合、renderの行を削除すれば確実に削除を反映することができます。
プロビジョニングするときの--why-run
で差分としても現れます。
「設定ファイルは分割すべし」の意味は時代とともに変わる(かも)
「分割すべし」という考えは正しいですが、上記のようにChefレポジトリ上で分割できているのであれば、必ずしもサーバ上で分割配置されていなくてもよいかもしれません。
例えて言うなら、フロントエンド開発で、開発中はJSやCSSファイルを分割していても、リリースするときは結合してサーバに設置しますよね。それと似たようなことかなと思います。
ちなみに私はどっちの方法でやってるかというと、今のところはInclude方式とrender方式を両方使ってハイブリッドでやっています(w)
もうちょっと運用がこなれてきたらrender方式に統一するかもしれません。