Chef の高い学習コストを払い終えたのかやっとしっくりき始めたけど、Cookbook の開発環境についてはまだまだしっくりには程遠い。いまのところこんな感じというのをシェア。
Vagrant でたてたローカルの VM で Cookbook でやりたいことを直接試して、いい感じになったら serverspec でテストを書いて通るようになったら vagrant-sahara でロールバック後、Cookbook に置き換える感じです。ServerSpec でのテストはきれいにかけて Chef 依存もなく気に入っているけど、attributes の値を変えたときに正しく反映されるかなどは書けず、他のテストツールも合わせて使わないとなあと感じてる。test-kitchenも気になってて見た感じはこのスタイルを一枚の yamlにまとめられる程度の印象で触れていない。
不満はとにかく Vagrant が遅いこと。VirtualBoxが遅いのかと思い、vagrant-lxc を試してみたけどあまり変わらなかった(バグってるのでそのままは使えない。VM へのプロビジョンがもう少しでも高速化できれば Guard も使っていきたいけど現状では難しい印象。serverspec-init
で生成される spec_helper.rb
では素直に vagrant ssh-config
を毎回実行しているけど、これに20秒程度かかっていてどうしようもない感じだったので以下のように修正している。これですぐテストが走るようにはなる。
require'serverspec'require'pathname'require'net/ssh'includeServerspec::Helper::Ssh# include Serverspec::Helper::DetectOS# DetectOS をやめて決め打ちにすることで数秒短縮できるincludeServerspec::Helper::DebianSSH_CONFIG_FILE = '.vagrant-ssh-config' ... # `vagrant ssh-config` がとてつもなく遅いので結果をキャッシュしている# Multi-VM でうまくいくかは試していないunlessFile.exists?(SSH_CONFIG_FILE) system("vagrant ssh-config > #{SSH_CONFIG_FILE}") end config = File.open(SSH_CONFIG_FILE).read if config != '' config.each_line do |line| if match = /HostName (.*)/.match(line) c.host = match[1] elsif match = /User (.*)/.match(line) user = match[1] elsif match = /IdentityFile (.*)/.match(line) options[:keys] = [match[1].gsub(/"/,'')] elsif match = /Port (.*)/.match(line) options[:port] = match[1] endendend