===========================
VagrantはChefで環境構築を自動化してくれるツールです。仮想マシンにはVirtualBoxなどが利用できます。
Windowsはssh
やrsync
などを追加するとKnife Soloが使えます。
Chef Soloの入門としてRuby(rbenv)の環境を自動構築する方法を紹介します。
(WindowsにUNIX互換の環境を追加するだけなのでChefの使い方はMacやLinuxでも同じです。)
Download & Install
こちらをWindowsのインストーラーでインストールします。
VirtualBox
VirtualBox for Windowsをインストールします。
VirtualBoxの登場はここだけです。あとはVagrantで仮想マシンをコントロールします。
Vagrant
Vagrant for Windowsをインストールします。
(この手順のインストールディレクトリはC:¥opt¥vagrant¥
です。)
VagrantにはRubyが必要なのでRuby for Windowsがインストールされます。
これでMinGWもインストールされるのでUNIX互換の環境が利用できます。
(RubyGemsは1.0.x
系なので注意しましょう。)
Minimalist GNU for Windows
VagrantのMinGWにパッケージ管理ツールはないのでMinGWをインストールします。
(この手順のインストールディレクトリはC:¥opt¥MinGW¥
です。)
msysGit
MinGWのパッケージにGitはないのでGit for Windowsをインストールします。
(この手順のインストールディレクトリはC:¥opt¥git¥
です。)
Terminal
VagrantのインストールでMinttyもインストールされています。
まずC:\opt\vagrant\embedded\bin\mintty.exe
のショートカットを作ります。
そのショートカットのリンク先(T)
に/bin/bash --login
を追加します。
.minttyrc
ファイルを設定していますが、通常はGUIで設定します。
(Minttyは背景を透過にできます。Macでも作業をするので透過はポイントです。)
$ cat << __EOS__ > ~/.minttyrc
Transparency=high
FontHeight=12
__EOS__
Package
VagrantのMinGWにmingw-get
コマンドを追加してssh
やrsync
などをインストールします。
$ cp -r /c/opt/MinGW/. /c/opt/vagrant/embedded/
$ cd /c/opt/vagrant/embedded/var/lib/mingw-get/data/
$ cat defaults.xml|(rm defaults.xml;sed 's/%R\/msys\/1.0/\/opt\/vagrant\/embedded/g' > defaults.xml)
$ cat profile.xml|(rm profile.xml;sed 's/%R\/msys\/1.0/\/opt\/vagrant\/embedded/g' > profile.xml)
$ mingw-get update
$ mingw-get upgrade
$ mingw-get install msys-openssl msys-openssh
$ mingw-get install msys-rsync msys-tar
$ mingw-get install msys-vim
パッケージの一覧はこちらで確認できます。
$ mingw-get list | grep Package
Editor
Vimをインストールしていますが好きなエディターを使いましょう。
WindowsのExplorerからの操作でVagrantfileやChefのRecipeを編集できます。
Sublime TextはTerminalとExplorerから操作できるので使用しています。
.bash_profile
ファイルにエイリアスを設定すると便利です。
$ cat << __EOS__ >> ~/.bash_profile
alias ll='ls -al'
alias ee='/c/opt/sublimetext2/sublime_text'
__EOS__
$ . ~/.bash_profile
Virtual Machine
仮想マシンはGetting Startedと同じUbuntu 12.01
を利用します。
ログインはvagrant ssh
コマンドではなく/.ssh/config
ファイルとssh
コマンドを使います。
$ vagrant box add precise32 http://files.vagrantup.com/precise32.box
$ mkdir -p ~/vagrant/precise
$ cd ~/vagrant/precise
$ vagrant init precise32
$ vagrant up
$ mkdir ~/.ssh
$ vagrant ssh-config --host precise >> ~/.ssh/config
$ ssh precise
...
Welcome to your Vagrant-built virtual machine.
これでゲストOSにログインできました。次はVagrantfileを設定して環境を自動構築しましょう。
Chef
VagrantはChef Soloが利用されます。リモートマシンにリポジトリ(構築手順)を
rsync
で同期させてssh
でコマンドを実行するシンプルな仕組みです。
ホストOS(Knife Solo) <-- ssh --> ゲストOS(Chef Solo)
[Chef Repository] <--- rsync ---> [Chef Repository]
Knife Solo
Gemのknife-solo
をインストールするとChefが使えるようになりますが
MSYSに対応していない部分があるのでソースからインストールします。
Cygwinと認識されてディレクトリの先頭に/cygdrive/
を付けられるのでv0.2.0
をForkして修正しました。
(CygwinとMSYSをRbConfig
で区別できないものか… pull request
をするならv0.3.x
系にします)
Git
GitHubからソースを利用するのでgit
コマンドを使えるようにします。
また、Chefのリポジトリ管理はGitを使います。
$ ln -s /c/opt/git/bin/git.exe /c/opt/vagrant/embedded/bin/git.exe
$ ln -s /c/opt/git/libexec/git-core /c/opt/vagrant/embedded/libexec/git-core
$ ln -s /c/opt/git/share/git-core /c/opt/vagrant/embedded/share/git-core
Gem
ドキュメントが不要なら.gemrc
ファイルに設定します。
$ echo 'gem: --no-ri --no-rdoc' > ~/.gemrc
$ gem install bundler
$ gem install rake
$ gem install ffi
修正したmsys
のブランチをインストールします。
$ git clone git://github.com/ogom/knife-solo.git
$ cd ./knife-solo/
$ git checkout msys
$ bundle && rake install
$ cd ..
$ rm -rf ./knife-solo/
Cookbook
まずは簡単なレシピを作りましょう。Hello, Chef!
が出力されると成功です。
(個人のクックブックはsite-cookbooks
に作ります。)
$ cd ~/vagrant/precise
$ knife configure
$ knife solo init chef-repo
$ cd ./chef-repo/
$ knife cookbook create hello -o ./site-cookbooks
$ echo 'log "Hello, Chef!"' >> ./site-cookbooks/hello/recipes/default.rb
$ echo '{"run_list":["hello"]}' > ./nodes/precise.json
$ knife solo prepare precise
$ knife solo cook precise
...
* log[Hello, Chef!] action write
ここでGitのリポジトリを作ります。
リポジトリはknife cookbook
コマンドの前に必要です。
$ git config --global user.email "user@example.com"
$ git config --global user.name "user"
$ git init
$ git add .
$ git commit -m 'first commit'
KnifeでゲストOSで'git'コマンドを使えるようにします。
(サードパーティーのクックブックはcookbooks
を使います。)
$ knife cookbook site install git -o ./cookbooks
$ echo '{"run_list":["git"]}' > ./nodes/precise.json
$ knife solo cook precise
Recipe: git::default
* package[git] action install
- install version 1:1.7.9.5-1 of package git
$ ssh precise
vagrant@precise32:~$ git --version
git version 1.7.9.5
Vagrantfile
先ほどのGitのrecipe
をVagrantに設定します。
$ cd ~/vagrant/precise/
$ cat << __EOS__ > ./Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "precise32"
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = "./chef-repo/cookbooks"
chef.roles_path = "./chef-repo/roles"
chef.data_bags_path = "./chef-repo/data_bags"
chef.add_recipe "git"
end
end
__EOS__
マシンを削除してから、マシンを新しく作ります。
$ vagrant destroy --force
$ vagrant up
$ ssh precise
vagrant@precise32:~$ git --version
git version 1.7.9.5
マシンを再作成してもgit
コマンドが使えます。続いてRubyの環境を自動構築します。
rbenv
rbenvはRubyのバージョン管理ツールです。これを簡単にインストールできます。
Cookbookを管理するにはBerkshelfが便利です。
$ gem install berkshelf
先ほどのリポジトリに追加します。(rbenvはGitHubのリポジトリを利用します。)
$ cd ~/vagrant/precise/chef-repo
$ cat << __EOS__ > ./Berksfile
site :opscode
cookbook 'git'
cookbook 'ruby_build'
cookbook 'rbenv', github: "fnichol/chef-rbenv"
__EOS__
$ berks install --path ./cookbooks
まずはknifeで試します。
$ cat << __EOS__ > ./nodes/precise.json
{
"run_list": [
"git",
"ruby_build",
"rbenv::user"
],
"rbenv": {
"user_installs": [
{
"user": "vagrant",
"rubies": ["1.9.3-p429"],
"global": "1.9.3-p429",
"gems": {
"1.9.3-p429": [
{"name": "bundler"}
]
}
}
]
}
}
__EOS__
$ knife solo prepare precise
$ knife solo cook precise
$ ssh precise
vagrant@precise32:~$ which rbenv
/home/vagrant/.rbenv/bin/rbenv
vagrant@precise32:~$ ruby -v
ruby 1.9.3p429
/home/vagrant/
パスにrbenv
がインストールされています。最後にVagrantで試します。
$ cd ~/vagrant/precise/
$ cat << __EOS__ > ./Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "precise32"
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = "./chef-repo/cookbooks"
chef.roles_path = "./chef-repo/roles"
chef.data_bags_path = "./chef-repo/data_bags"
chef.add_recipe "git"
chef.add_recipe "ruby_build"
chef.add_recipe "rbenv::user"
chef.json = {
"rbenv" => {
"user_installs" => [{
"user" => "vagrant",
"rubies" => ["2.0.0-p195"],
"global" => "2.0.0-p195",
"gems" => {
"2.0.0-p195" => [
{"name" => "bundler"}
]
}
}]
}
}
end
end
__EOS__
マシンを再起動します。
$ vagrant reload
$ ssh precise
vagrant@precise32:~$ rbenv versions
system
1.9.3-p429
* 2.0.0-p195 (set by /home/vagrant/.rbenv/version)
vagrant@precise32:~$ ruby -v
ruby 2.0.0p195
Rubyのバージョンが変わりました。 レシピ通りです。 (キリッ
Actor
アクターが多いので今回の関係を図にしました。
Tree
今回の主なファイルです。(Chefの用語は慣れましょう。)
.
└─vagrant [ベイグラントの作業エリア]
└─precise [マシンの作業エリア]
│ Vagrantfile [ベイグラントの設定ファイル]
│
└─chef-repo [シェフのリポジトリ]
│ Berksfile [バークシャーの設定ファイル]
│ solo.rb
│
├─cookbooks [各種クックブック]
│ ├─build-essential
│ ├─chef_handler
│ ├─git
│ ├─rbenv [rbenvのクックブック]
│ │ │ Berksfile
│ │ │ Gemfile
│ │ │ Rakefile
│ │ │ Vagrantfile
│ │ │
│ │ ├─attributes
│ │ ├─libraries
│ │ ├─providers
│ │ ├─recipes [各種レシピ]
│ │ │ default.rb
│ │ │ system.rb
│ │ │ system_install.rb
│ │ │ user.rb
│ │ │ user_install.rb [ユーザにrbenvをインストールするレシピ]
│ │ │ vagrant.rb
│ │ │
│ │ ├─resources
│ │ ├─templates
│ │ └─test
│ └─ruby_build
├─data_bags
├─nodes
├─roles
└─site-cookbooks
└─hello
├─attributes
├─definitions
├─files
├─libraries
├─providers
├─recipes
│ default.rb [Hello, Chef!のレシピ]
│
├─resources
└─templates
Tips
Chef Solo
リモートマシンでChef Soloを実施することができます。
vagrant@precise32:~$ git clone git://github.com/opscode/chef-repo.git
vagrant@precise32:~$ cd ./chef-repo/
vagrant@precise32:~$ knife configure
vagrant@precise32:~$ knife cookbook create hello -o ./cookbooks
vagrant@precise32:~$ echo 'log "Hello, Chef!"' >> ./cookbooks/hello/recipes/default.rb
vagrant@precise32:~$ echo '{"run_list":["hello"]}' > ./localhost.json
vagrant@precise32:~$ echo 'file_cache_path "/tmp/chef-solo"' > ./solo.rb
vagrant@precise32:~$ echo 'cookbook_path ["/home/vagrant/chef-repo/cookbooks"]' >> ./solo.rb
vagrant@precise32:~$ sudo chef-solo -c ./solo.rb -j ./localhost.json
...
INFO: Hello, Chef!
Chef Soloで確認してからKnife Soloを使いましょう。