hidemium's blog

日々学んだことをアウトプットする。

rbenvでruby をインストールするChefのレシピを書いてみた

前回は、Opscode Communityに公開さているレシピを使い、rubyをインストールしましたが、Chefのレシピを書く練習のため、今回は、rbenvでrubyをインストールするレシピを書いてみました。

構成

Windows 7: Chef 11.10
Ubuntu 12.04: サーバ構築対象
Ubuntu 12.04はDocker 0.10上で動作しています。

レシピの作成

Rubyインストール用のcookbookを作成します。

$ cd chef-repo/
$ knife cookbook create ruby -o site-cookbooks

recipesファイルを以下のように編集します。
設定内容は以前の記事とほぼ同じですが、「.bash_profile」を「rbenv.sh」に変更したり、Ubuntuに合わせて導入パッケージを変更したりしています。また、実行ユーザはrootユーザを想定しています。

$ vi site-cookbooks/ruby/recipes/default.rb
%w{git-core build-essential libssl-dev}.each do | pkg |
    package pkg do
        action :install
    end
end

git "/usr/local/rbenv" do
    repository "git://github.com/sstephenson/rbenv.git"
    reference "master"
    action :sync
end

%w{/usr/local/rbenv/shims /usr/local/rbenv/versions}.each do |dir|
    directory dir do
    action :create
    end
end

git "/usr/local/ruby-build" do
    repository "git://github.com/sstephenson/ruby-build.git"
    reference "master"
    action :sync
end

bash "install_ruby_build" do
    cwd  "/usr/local/ruby-build"
    code "./install.sh"
    action :run
end

template "rbenv.sh" do
    path "/etc/profile.d/rbenv.sh"
    owner "root"
    group "root"
    mode "0644"
    source "rbenv.sh.erb"
end

bash "rbenv install" do
    code   "source /etc/profile.d/rbenv.sh; rbenv install #{node.build}"
    action :run
    not_if { ::File.exists?("/usr/local/rbenv/versions/#{node.build}") }
end

bash "rbenv rehash" do
    code   "source /etc/profile.d/rbenv.sh; rbenv rehash"
    action :run
end

bash "rbenv global" do
    code   "source /etc/profile.d/rbenv.sh; rbenv global #{node.build}"
    action :run
end

attributesファイルを以下のように編集します。
インストールするRubyのバージョンを変更する場合は、attributesファイルで変更します。※2.0.0-p353も対応しています。

$ vi site-cookbooks/ruby/attributes/default.rb
default["build"] = "1.9.3-p545"

templatesファイルを以下のように編集します。

$ vi site-cookbooks/ruby/templates/default/rbenv.sh.erb
export RBENV_ROOT="/usr/local/rbenv"
export PATH="/usr/local/rbenv/bin:$PATH"
eval "$(rbenv init -)"

JSONファイルにRubyインストール用のcookbookを指定します。

$ vi nodes/<サーバのIPアドレス>.json
{
  "run_list":[
    "recipe[ruby]"
  ]
}

サーバにChefをインストールします。

$ knife solo bootstrap root@<サーバのIPアドレス> -p <ポート番号>

他のOSバージョンでの実行

今回、Ubuntu 12.04に対するレシピを作成しましたが、それ以外のOSバージョンで上記のレシピを実行した場合にどうなるか試してみました。
レシピを実行した結果、以下のようなエラーがでました。

---- Begin output of apt-get -q -y install git-core=1:1.7.9.5-1 ----
STDOUT: Reading package lists...
Building dependency tree...
Reading state information...
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 git-core : Depends: git (> 1:1.7.0.2) but it is not going to be installed
STDERR: E: Unable to correct problems, you have held broken packages.
---- End output of apt-get -q -y install git-core=1:1.7.9.5-1 ----
Ran apt-get -q -y install git-core=1:1.7.9.5-1 returned 100
WARNING: Chef-Client has not been regression tested on this O/S Distribution
WARNING: Do not use this configuration for Production Applications.  Use at your own risk.
:
---- Begin output of apt-get -q -y install build-essential=11.5ubuntu2.1 ----
STDOUT: Reading package lists...
Building dependency tree...
Reading state information...
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 build-essential : Depends: libc6-dev but it is not going to be installed or
                            libc-dev
                   Depends: g++ (>= 4:4.4.3) but it is not going to be installed

STDERR: E: Unable to correct problems, you have held broken packages.
---- End output of apt-get -q -y install build-essential=11.5ubuntu2.1 ----
Ran apt-get -q -y install build-essential=11.5ubuntu2.1 returned 100

予想以上にOSのバージョン差異による影響がありました。また、対象OSでChef-Clientがテストされていない場合もあるようです。Chefを導入する場合は、テストが重要になってきそうです。
ちなみに、他のOSバージョンでのテストも、Dockerを用いて行いました。テストごとに環境を使い捨てにできるで、さくっと使えて便利ですね。