chef-soloで作業環境構築の自動化
さくらのVPSを契約して放置しておいたままだったので、これを機に環境構築をしてみることにした。
なお現状はユーザーakahigeの追加とsshの設定だけ済ませた状態になっている。
- すべての設定はChef経由で行うこと
というルールでChefで同じ環境をいくらでも作れるものを目指してみよう。
Chefサーバーのセットアップはめんどくさいのでchef-soloでがんばる所存。
Rubyのインストール
とはいえChefの動く環境はChef以外で作らないといけない。
このあたりを省略するならシェルスクリプトによる自動化か、Chefが動くところまでセットアップした仮想マシンのイメージを使うほかなさそうだ。
必要なパッケージのインストール
$ wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
$ sudo rpm -ivh epel-release-5-4.noarch.rpm
$ wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.1-1.el5.rf.x86_64.rpm
$ sudo rpm -ivh rpmforge-release-0.5.1-1.el5.rf.x86_64.rpm
$ sudo yum install -y git
$ sudo yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel git
$ sudo yum update
Rubyに必要なパッケージとついでにGitとかも入れちゃう。GitはChefリポジトリのひな形を持ってくるのに必要なので。
Ruby 1.9.2のインストール
$ wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p0.tar.bz2
$ tar xjf ruby-1.9.2-p0.tar.bz2
$ cd ruby-1.9.2-p0
$ ./configure
$ make
$ sudo make install
ごく普通にインストール。
Chefのインストール
$ sudo gem install chef --no-rdoc --no-ri
chef-soloでがんばるのでサーバーは入れないでおk。
chef-repoの準備とchef-solo用の設定
Chefリポジトリのひな形をGitHubからいただいて来て設定ファイルを作る。
$ git clone git://github.com/opscode/chef-repo.git
$ cd chef-repo
$ mkdir .chef
.chef/solo.rb
file_cache_path "/tmp/chef-solo"
cookbook_path "/home/akahige/chef-repo/cookbooks"
これが設定ファイル。
chef-soloを実行したときに参照するクックブックの場所などを指定する。
.chef/chef.json
{
"run_list": [ "recipe[base_packages]" ]
}
JSONで適用するレシピを定義する。
とりあえずbase_packagesというレシピを適用することにしてみる。
chef-soloを実行してみる
$ sudo chef-solo -c .chef/solo.rb -j .chef/chef.json
この時点ではレシピを書いてないのでもちろんエラーが出るのみ。
レシピを書く
クックブックを作る
$ rake new_cookbook COOKBOOK=base_packages
deprecatedだからknifeを使いなさい、と警告が出るけどその通りにknifeを使ってもエラーになってうまく動かないので無視。
ともあれこれでいろいろとディレクトリやファイルを含んだクックブックができる。
cookbooks/base_packages/recipes/default.rb
レシピはクックブックのディレクトリ以下のrecipes/default.rbに書いていく。
%w{zsh screen nmap}.each do |package_name|
package package_name do
action :install
end
end
とりあえず思いついたところでzshとscreenとnmapなどを入れてみることとする。
ループの部分とかRubyで書けるのが予想以上に気持ちいい。
再びchef-soloを実行してみる
$ sudo chef-solo -c .chef/solo.rb -j .chef/chef.json
めでたく動作してzshとscreenとnmapが入った。
zsh
しかしzshだけ入っても使い慣れた環境は再現されない。
.zshrcを設置したい。
レシピがちょっと複雑になるのでzshをインストールを別のクックブックとして独立させる。
$ rake new_cookbook COOKBOOK=zsh
cookbooks/zsh/recipes/default.rb
package "zsh" do
action :install
end
rcfile = '/home/akahige/.zshrc'
template rcfile do
source "zshrc.erb"
end
file rcfile do
owner "akahige"
group "akahige"
mode "0644"
end
テンプレートファイルをコピーしてパーミッションなどを指定。
環境ごとのカスタマイズは必要ないのでfileリソースだけでいけるのかと思ったが、templateリソースじゃないとsourceが指定できなかった。(※後で気がついたがこういう用途のためにcookbook_fileというリソースがあった)
パッケージのインストール部分がbase_packagesのrecipes/default.rbと重複するがそのままでも問題ない。
ユーザー名がべた書きなのがちょっと気になるけど、自分専用レシピということでとりあえず気にしないことにする。
cookbooks/zsh/templates/default/zshrc.erb
テンプレートファイルとして設置したい.zshrcの内容そのままのzshrc.erbを置く。
内容は割愛。
クックブック内に置けるのはまとまりがよくていい。
.chef/chef.json
{
"run_list": [ "recipe[base_packages]", "recipe[zsh]" ]
}
新しく作ったレシピを適用するためrun_listに含める。
三度chef-soloを実行してみる
$ sudo chef-solo -c .chef/solo.rb -j .chef/chef.json
.zshrcが見事設置された。やっほい。
screen
次は.screenrc。zshのクックブックの時と同じ手順。
$ rake new_cookbook COOKBOOK=screen
cookbooks/screen/recipes/default.rb
package "screen" do
action :install
end
rcfile = '/home/akahige/.screenrc'
template rcfile do
source "screenrc.erb"
end
file rcfile do
owner "akahige"
group "akahige"
mode "0644"
end
zshと同じ。
なんかDRYにできないだろうかと思うがひとまずこのままで。
cookbooks/screen/templates/default/screenrc.erb
設置したい.screenrcの内容そのままのscreenrc.erbを置く。
内容は割愛。
.chef/chef.json
{
"run_list": [ "recipe[base_packages]", "recipe[zsh]", "recipe[screen]" ]
}
screenのレシピも追加。
またまたchef-soloを実行してみる
$ sudo chef-solo -c .chef/solo.rb -j .chef/chef.json
あかひげ はscreenが使えるようになった!
Git
一段落したところで変更をコミットしておこうとGitを使ったらgitのuser.nameとuser.emailを登録してないので怒られた。
これもChefで設定してみよう。
cookbooks/base_packages/recipes/default.rb
%w{git nmap}.each do |package_name|
package package_name do
action :install
end
end
`git config --global user.name "akahige"`
`git config --global user.email "akahigeg@gmail.com"`
超やっつけでこめんなさい。
まじめにやるなら~/.gitconfigをrcファイルと同じように置く方向か。
ついでにインストールするパッケージのリストからzshとscreenを消してgitを加えた。
最後のchef-soloを実行してみる
$ sudo chef-solo -c .chef/solo.rb -j .chef/chef.json
gitで怒られなくなりました。
ひとまず終わり
$ git commit -a
ということで保存完了。
これでCentOSの環境だったらどこへ行ってもすぐにzshとscreenなどよく使うツールの環境を整えられるようになった。
後で引き続きsshとかvimの設定なんかも追加してみよう。
chef-soloの感想
これはもうPuppetに戻れないかも。
Rubyでレシピを書けるということが想像していたよりずっとよかった。
それと実行を繰り返しながらちょっとずつ環境を構築していくのがTDDのノリに近くて楽しい。
この感覚はなぜかPuppetにはなかったな。なんでだろう。
TDDと言えばrake test_cookbooksというタスクもあるけどこれはなんなのかな。
しかしこれCapistranoと組み合わせたらchef-soloだけでもけっこういけるんじゃないかしら、とか思った。
chef.jsonの代わりにweb.jsonとかdb.jsonとか作って指定したらロールの代わりになるし。
そういう事を思ってしまうくらいChefサーバー立てるのがめんどくさいです。
2010/09/30追記
Chefサーバーを利用する場合、このエントリで扱っているような個々のユーザーの設定にはData Bagsという仕組みを使うことができる。
シェルの設定や各種ファイルの設置などができ、しかもknifeで検索も可能とか。
Chefの機能をフルに使うならChefサーバーは必須ということのようだ。
2011/05/23追記
chef-soloとCapistranoの組み合わせを実際やってみたらChefサーバーなしでもかなりいけるような気がしてきた。
“chef-soloで作業環境構築の自動化” に対して1件のコメントがあります。
コメントは受け付けていません。