- 更新日: 2014年7月14日
- Vagrant & Chef
Chefでrbenvとruby-buildをインストール
昨日のエントリーで書いた The Environment Cookbook Pattern に則って、rbenv と ruby-build をインストールする Chef の Cookbook を独自に作成してみました。
Chef Cookbook の管理方針、The Environment Cookbook Pattern について | EasyRamble
The Environment Cookbook Pattern
結果から言うと、結構良い感じに仕上がりました。以下の CentOS に rbenv と ruby-build をインストールする手順を、Chef で自動化する作業となります。
rbenv と ruby-build で Ruby をインストールして管理 〜 CentOS6 | EasyRamble
このエントリーは、CentOS サーバー設定用 Chef Cookbook/Recipe の目次 の一部です。
rbenv + ruby-build をインストールする Application Cookbook を作成
まずは、rbenv と ruby-build をインストールする汎用的な Cookbook の雛形を作成します。The Environment Cookbook Pattern でいう、Application Cookbook レイヤーの Cookbook となります。したがって、汎用できるように作成し、ノード固有の設定値は変数にしておく。
1 2 3 |
$ bundle exec knife cookbook create -o site-cookbooks app_rbenv_cookbook |
できた app_rbenv_cookbook の Recipe(default.rb)を編集。
site-cookbook/app_rbenv_cookbook/recipes/default.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# Cookbook Name:: app_rbenv_cookbook # Recipe:: default # -------------------------------------------------- # install rbenv # -------------------------------------------------- # create rbenv group and add executable user (vagrant) for /usr/local/rbenv to the rbenv group group "rbenv" do action :create members "vagrant" append true end # install rbenv from github git "/usr/local/rbenv" do repository "git://github.com/sstephenson/rbenv.git" reference "master" action :checkout user "root" group "rbenv" end # create rbenv.sh from templates/default/rbenv.sh.erb template "/etc/profile.d/rbenv.sh" do owner "root" group "root" mode 0644 end # -------------------------------------------------- # install ruby-build # -------------------------------------------------- # create directory for ruby-build plugin directory "/usr/local/rbenv/plugins" do owner "root" group "rbenv" mode "0755" action :create end # install ruby-build from github git "/usr/local/rbenv/plugins/ruby-build" do repository "git://github.com/sstephenson/ruby-build.git" reference "master" action :checkout user "root" group "rbenv" end # -------------------------------------------------- # build Ruby # -------------------------------------------------- # install ruby (node.set["rbenv"]["ruby"]["versions"]).each do |ruby_version| execute "install ruby #{ruby_version}" do not_if "source /etc/profile.d/rbenv.sh; rbenv versions | grep #{ruby_version}" command "source /etc/profile.d/rbenv.sh; rbenv install #{ruby_version}" action :run end end # set global ruby execute "set global ruby" do not_if "source /etc/profile.d/rbenv.sh; rbenv global | grep '#{global_ruby}'" command "source /etc/profile.d/rbenv.sh; rbenv global #{node.set["rbenv"]["ruby"]["global"]}; rbenv rehash" action :run end |
コメントを見れば分かると思いますが、rbenv のインストール、ruby-build を rbenv のプラグインとしてインストール、Ruby をインストールの3つの作業を行っています。
rbenv のインストールでは、起動スクリプト(/etc/profile.d/rbenv.sh)をテンプレートから作成していますので、テンプレート用のファイルを別途作成する。(後述)
また、Ruby のインストール部分では、ノードに固有な値を node.set の変数で指定しています。
node.set[“rbenv”][“ruby”][“versions”]
インストールする Ruby のバージョンを指定する。配列で指定して、いっぺんに複数のバージョンの Ruby をインストールできるようにしています。
node.set[“rbenv”][“ruby”][“global”]
global で使う Ruby のバージョンを指定する。
これらの値は、後述する Wrapper Cookbook で変数に値をセットします。
続いて、上記 rbenv をインストールする Recipe で利用する、rbenv 起動スクリプト用のテンプレートを作成します。
site-cookbook/app_rbenv_cookbook/templates/default/rbenv.sh.erb
1 2 3 4 5 |
export RBENV_ROOT="/usr/local/rbenv" export PATH="$RBENV_ROOT/bin:$PATH" eval "$(rbenv init -)" |
これが、/etc/profile.d/rbenv.sh に作成されます。
Application Cookbook を wrap する Wrapper Cookbook を作成
上記 rbenv + ruby-build のインストール用の Application Cookbook を wrap する Wrapper Cookbook を作成します。
1 2 3 |
$ bundle exec knife cookbook create -o site-cookbooks wrapper_project_name_cookbook |
site-cookbook/wrapper_project_name_cookbook/recipes/default.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Wrapper Cookbook for project_name # wrap Application Cookbook and describe specification # include_recipe "app_name_cookbook" and set variables # # Cookbook Name:: wrapper_project_name_cookbook # Recipe:: default # for rbenv node.set["rbenv"]["ruby"]["versions"] = ["2.1.2", "1.9.3-p547"] node.set["rbenv"]["ruby"]["global"] = "2.1.2" # recipes include_recipe "app_git_cookbook::default" include_recipe "app_zsh_cookbook::default" include_recipe "app_rbenv_cookbook::default" |
インストールする Ruby のバージョンは、2.1.2 と 1.9.3-p547 の2つ。global な Ruby は 2.1.2 を指定。
Wrapper Cookbook は、Application Cookbook をラップして、ノードに固有な設定(つまりサーバー固有の仕様)を書く Cookbook です。ここでは、以下の2つの値をノード固有の値と設定しています。
node.set[“rbenv”][“ruby”][“versions”] rbenvでインストールするRubyのバージョン
node.set[“rbenv”][“ruby”][“global”] globalなRubyバージョン
これらの設定をプロジェクトごと(ノードごと)に変更することで、インストールする Ruby のバージョンや global な Ruby のバージョンを柔軟に変更できる。さらに最初に作成した app_rbenv_cookbook は汎用的に作ってあるので、簡単に使いまわせる。たとえば、以下のようなちょっと古い Ruby バージョンを利用する場合での Wrapper Cookbook の例。
site-cookbook/wrapper_another_project_name_cookbook/recipes/default.rb
1 2 3 4 5 6 |
# for rbenv node.set["rbenv"]["ruby"]["versions"] = ["1.8.7-p375", "2.0.0-p481"] node.set["rbenv"]["ruby"]["global"] = "1.8.7-p375" # recipes include_recipe "app_rbenv_cookbook::default" |
ノード固有の値は簡単に違う値を設定できるし、app_rbenv_cookbook::default は include_recipe するだけで簡単に使いまわせます。
Wrapper Cookbook の俺流管理パターン
本家の The Environment Cookbook Pattern によると、Wrapper Cookbook は {project_name}-{wrapped_cookbook} という名前にするそうなので、この場合 project_name-app_rbenv_cookbook とするのが本家通りだろうと思います(おそらく)。
ただしこうすると、プロジェクト毎に Application Cookbook のレイヤーで作成したパッケージインストール用 Cookbook の数だけ、Wrapper Cookbook も作成されることになります。project_name-app_rbenv_cookbook, project_name-app_git_cookbook …など。これは小規模〜中規模の運用では少々大げさに感じましたので、私の場合現在は wrapper_project_name_cookbook という名前の Wrapper Cookbook を作成する方針にしています。つまりプロジェクト毎に1つの Wrapper Cookbook を作成し、この中で必要な変数の値を設定して、利用する全ての Application Cookbook を include_recipe します。
Wrapper Cookbook については現在以上の方針で管理しています。あとは、作成した Wrapper Cookbook(今回の場合、wrapper_project_name_cookbook)をノードに適用させればOK。無事に上手く動作しました。
実際には、もう一枚のレイヤー Environment Cookbook を被せていますが、Application Cookbook と Wrapper Cookbook は以上のような感じです。個人的には、なかなか良いのではないかな〜と考えています。
- Vagrant & Chef の関連記事
- Vagrantで使うVirtualBoxのVM(仮想マシン)を外付けHDDに移動
- Chefで/etc/sysctl.confのkernel.panicを設定
- Chefでtelnetをインストール
- Chefでyumリポジトリを追加する設定
- Chef で iptables の設定
- ChefでSSH接続用の公開鍵をサーバーに設置
- nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
- Chef Recipe でユーザー・グループを作成
- Chef Recipe で CentOS のネットワーク・ホストを設定
- NetworkManager 他不要なパッケージを削除する Chef Recipe
Leave Your Message!