Windowsのターミナルエミュレータ(蛇足)
Chefではコマンドを利用する場合や、SSH接続の簡略化のため ~/.ssh/
などのパスを利用する場合があります。
Windowsローカルの環境で開発を行う場合は、ターミナルエミュレータminttyのインストールなどをオススメします。
ミドルウェアのインストール
VirtualBoxとVagrantはインストーラでインストールします。
Rubyのインストール
Rubyのインストールから適切な方法を選択します。
バージョンは現在の最新版である2.1.2を前提として進めます。
- OS X :
brew install rbenv ruby-build
でrbenvをインストールする方法をオススメします。 - Linux : $HOME以下にrbenvでインストールする方法をオススメします。
- Windows : インストーラでインストールします。
Rubyインストール後はBundlerは必ず入れておきましょう。
(rbenv rehash
はrbenvでRubyをインストールした場合に実行します。)
$ gem install bundler
$ rbenv rehash
作業環境のセットアップ
作業ディレクトリを作り、Chefの実行やテストに必要なgemをインストールします。
$ mkdir sample
$ cd sample
$ bundle init
$ vim Gemfile
Gemfile
には以下を記述します。(バージョンは随時確認し、最新版を利用してください)
source "https://rubygems.org"
gem 'knife-solo', '~> 0.4.2'
gem 'knife-solo_data_bag', '~> 1.1.0'
gem 'berkshelf', '~> 3.1.5'
group :test do
gem 'foodcritic', '~> 4.0.0'
gem 'test-kitchen', '~> 1.2.1'
gem 'serverspec', '~> 2.1.0'
gem 'chefspec', '~> 4.0.2'
end
記述したgemをインストールします。
$ bundle install
$ rbenv rehash
Chef-Repo(knife-solo版)セットアップ
作業ディレクトリ以下にChefのファイル構成(通称Chef-Repo)を作成します。今回はknife-solo版です。
また、ついでに一つクックブックを作っておきます。
$ knife solo init .
$ knife cookbook create sample -o site-cookbooks
作成直後はこのようなディレクトリ構成になります。
sample/
├── Berksfile
├── cookbooks/
├── data_bags/
├── environments/
├── nodes/
├── roles/
└── site-cookbooks/
└── sample/
├── CHANGELOG.md
├── README.md
├── attributes/
├── definitions/
├── files/
│ └── default/
├── libraries/
├── metadata.rb
├── providers/
├── recipes/
│ └── default.rb
├── resources/
├── spec/
│ ├── recipes/
│ │ └── default_spec.rb
│ └── spec_helper.rb
└── templates/
└── default/
Vagrant セットアップ
Vagrantを使ってテスト用の仮想OSを管理します。
ゼロインストール状態からの再テストなどを行う時に便利なsaharaプラグインをインストールしておきます。
$ vagrant plugin install sahara
次にOSイメージの選択とイメージの取得、VMの起動を行います。
(vagrant up
は初回はイメージのダウンロードに時間がかかります)
$ vagrant init chef/debian-7.4
$ vagrant up
VMへのSSHログインを試してみます。ログインできたらCtrl+Dで終了しましょう。
$ vagrant ssh
ssh
コマンドでログインできるように、
vagrant ssh-config
コマンドが自動作成したssh設定を保存しておきます。
$ vagrant ssh-config --host vagrant
$ vagrant ssh-config --host vagrant >> ~/.ssh/config
これにより、次のようにsshコマンドでログインできるはずです。
$ ssh vagrant
Chefの実行
Vagrantで建てたサーバにクックブックを適用してみましょう。
まずはじめに、chefの実行環境をサーバにセットアップします。以下のコマンドを実行してください。
$ knife solo prepare vagrant
Bootstrapping Chef...
などの出力があり、chef-clientのセットアップが自動で進行します。
今回は仮想OSに Debian 7.4 を選択しましたが、OSのバージョンにあわせて自動でパッケージが選択されます。
chef-clientのインストールが完了したら、この状態を記録しておきます。Vagrantでインストールしたsaharaプラグインを利用し、スナップショットを作ります。
$ vagrant sandbox on
続いて、作業ディレクトリにnodes/vagrant.json
ファイルが生成されているので、次のように編集しrun_list
に "recipe[sample]"
を追加します。
{
"run_list": [
"recipe[sample]"
],
"automatic": {
"ipaddress": "vagrant"
}
}
設定が終わったら、knife solo
コマンドを実行し、sampleクックブックを実行します。
$ knife solo cook vagrant
以下の様な出力が最終行に出て、0個のリソースの更新、つまり何も実行しなかったことを示しています。
Chef Client finished, 0/0 resources updated in 7.901792483 seconds
レシピを更新して再実行
sampleクックブックのレシピを更新します。 site-cookbooks/sample/recipes/default.rb
をエディタで開き、以下を追記します。
directory "/tmp/hoge" do
action :create
end
file "/tmp/hoge/ipaddress.txt" do
content node[:ipaddress]
end
file "/tmp/hoge/time.txt" do
content Time.now.to_s
end
先程と同じく実行してみると、今度は3個のリソースが更新されたと表示されます。
$ knife solo cook vagrant
...
Chef Client finished, 3/3 resources updated in 8.175327603 seconds
実際にログインしてみると、ディレクトリとファイルが生成され、IPアドレスや作業した時刻が記録されていることがわかります。
再実行と冪等性
さて、同じ処理をもう一回実行してみます。
$ knife solo cook vagrant
...
Chef Client finished, 1/3 resources updated in 6.992058771 seconds
リソースがひとつ更新されたとあります。
time.txt
ファイルに記載された時間は実行時の時間であるため毎回異なり、chefがそれを検知したため更新を実行しました。
ファイルが既にある場合は更新しないようにしてみましょう。
not_if
を追加して条件をみたす場合は適用しないようにします。
file "/tmp/hoge/time.txt" do
content Time.now.to_s
+ not_if { ::File.exists?("/tmp/hoge/time.txt”) }
end
同じく実行してみると、file[/tmp/hoge/time.txt] action create (skipped due to not_if)
という表示が出て、今度はファイルの更新は実行されませんでした。
結果に表示されるリソースの総数はスキップした分減りますが、スキップしたことがログに残ります。
まとめ
「既にあるリソース(ファイルやサービスの状態)に対して既に同じ内容であるかを確認して、もし差異があれば処理を実行する」というのがChefの冪等性という概念です。
今回は変更が行われる例として時間を設定しましたが、通常は設定ファイル内の項目や値が古い場合や、稼働しているはずのサービスが稼働していない、アップデートで削除されるはずのファイルが存在する、などの適用する状況による差異が生まれます。
Chefではこのような「定義された状態」になっていない部分にのみ変更を加え、一定の状態に「収束(converge)」させることを目指します。
この「状態を定義」するのがChefのレシピです。