右往左往ブログ

日々よりみち

Rubyを知らずにchefでrecipeを書くときのTips

Rubyをほとんど使ったことがなくて、そのままchefのrecipeを書こうとすると、いろいろと細かいところがどう書くのか分からなくなります。 ということで、個人的に困ったところをメモします。

複数のリソースを使う

%w{... ...}で必要な分だけ記入して、eachでぐるぐる回します。

%w{vim-enhanced yum-utils}.each do |pkgs|
  package pkgs do
    action :install
  end
end

環境変数を設定する

ruby_blockの中でENV["ENV_NAME"]を使います。

ruby_block  "set-env-java-home" do
  block do
    ENV["JAVA_HOME"] = "/usr/java/default"
  end
end

恒久的に設定する場合は、/etc/profile.d/配下にスクリプトを置きます。

file "/etc/profile.d/jdk.sh" do
  content <<-EOS
    export JAVA_HOME="/usr/java/default"
  EOS
  mode 0755
end

ファイルが存在するかどうかを判定する

File.exist?("<PATH>")を使います。
not_ifと併用すると、ファイルが存在しない場合に実行されます。

bash "fluentd_repo" do
  code <<-EOL
   curl -L http://toolbelt.treasure-data.com/sh/install-redhat.sh | sh
  EOL
  not_if {File.exist?("/usr/sbin/td-agent")}
end

特定の文字列が含むかどうかを判定する

環境変数が設定されているかどうかを判定したくて調べました。
<STRING>.include?(<CHECK_STRING>)で利用します。

ruby_block  "set-env-rbenv" do
  block do
    ENV["RBENV_ROOT"] = "/usr/local/rbenv"
    ENV["PATH"] = ENV["RBENV_ROOT"] + "/bin:" + ENV["PATH"]
  end
  not_if {ENV["PATH"].include?("/usr/local/rbenv")}
end

上記では、環境変数${PATH}"/usr/local/rbenv"が含まれていない場合に環境変数の設定が行われます。

複数の(可変の)行を挿入する

/etc/hostsをtemplateとしてhosts.erbで管理するとき、attributeでホストの一覧を直接記述してしまうと、ホストが増えた時に、いちいちtemplateごと変えることになり面倒…なので、hashで設定することにします。

attributes/default.rb :

default['Network']['config']['HostIPList'] = {
    "host1" => "192.168.5.1",
    "host2" => "192.168.5.2",
    "host3" => "192.168.5.3",
    "host4" => "192.168.5.4"
}

templates/default/hosts.erb :

<% node['Network']['config']['HostIPList'].each do | hostname , ip | %>
<%= ip %>    <%= hostname %>
<% end %>

chefで上記templateを配布した後は、最終的に以下のようになります。

/etc/hosts :

192.168.5.1    host1
192.168.5.2    host2
192.168.5.3    host3
192.168.5.4    host4

もしホストを追加したくなったら、attributeに行を追加すればよさそうです。