page_adsence

2015年2月13日金曜日

Ansibleで作った環境をServerspecでテストする

ServerspecとはAnsibleやChef、Puppetといったプロビジョニングツールで作成された環境が、本当に意図した通りに作成されているのかをテストするためのツール。
Rubyで書かれていて、RubyのテストフレームワークであるRSpecの書き方に準拠している。

説明はこのくらいにして、実際に使ってみる。
テストする環境としては、自分のローカルPC上に作成したVMマシンで、
既にVagrant、VirtualBox、Ansibleが使える状態になっている。
今回、ServerspecでテストするサーバはVagrant使って新しいVMを作っておく。

まずはインストールから。
gemがインストールしてあることが前提。

user_name@computer_name ~
$ gem install serverspec
DL is deprecated, please use Fiddle
Fetching: rspec-support-3.2.1.gem (100%)
Successfully installed rspec-support-3.2.1
Fetching: rspec-mocks-3.2.0.gem (100%)
Successfully installed rspec-mocks-3.2.0
Fetching: rspec-expectations-3.2.0.gem (100%)
Successfully installed rspec-expectations-3.2.0
Fetching: rspec-core-3.2.0.gem (100%)
Successfully installed rspec-core-3.2.0
Fetching: rspec-3.2.0.gem (100%)
Successfully installed rspec-3.2.0
Fetching: rspec-its-1.1.0.gem (100%)
Successfully installed rspec-its-1.1.0
Fetching: multi_json-1.10.1.gem (100%)
Successfully installed multi_json-1.10.1
Fetching: net-scp-1.2.1.gem (100%)
Successfully installed net-scp-1.2.1
Fetching: specinfra-2.12.7.gem (100%)
Successfully installed specinfra-2.12.7
Fetching: serverspec-2.8.2.gem (100%)
Successfully installed serverspec-2.8.2
Parsing documentation for multi_json-1.10.1
Installing ri documentation for multi_json-1.10.1
Parsing documentation for net-scp-1.2.1
Installing ri documentation for net-scp-1.2.1
Parsing documentation for rspec-3.2.0
Installing ri documentation for rspec-3.2.0
Parsing documentation for rspec-core-3.2.0
Installing ri documentation for rspec-core-3.2.0
Parsing documentation for rspec-expectations-3.2.0
Installing ri documentation for rspec-expectations-3.2.0
Parsing documentation for rspec-its-1.1.0
Installing ri documentation for rspec-its-1.1.0
Parsing documentation for rspec-mocks-3.2.0
Installing ri documentation for rspec-mocks-3.2.0
Parsing documentation for rspec-support-3.2.1
Installing ri documentation for rspec-support-3.2.1
Parsing documentation for serverspec-2.8.2
Installing ri documentation for serverspec-2.8.2
Parsing documentation for specinfra-2.12.7
Installing ri documentation for specinfra-2.12.7
Done installing documentation for multi_json, net-scp, rspec, rspec-core, rspec-expectations, rspec-its, rspec-mocks, rspec-support, serverspec, specinfra after 40 seconds
10 gems installed

次にテストしたいVMのVagrantfileがあるディレクトリへ移動。
自分の場合は下記のディレクトリだったので、そこへ移動。

user_name@computer_name ~
$ cd VirtualBoxMachines/test

でserverspecを初期化する。

user_name@computer_name ~/VirtualBoxMachines/test
$ serverspec-init
DL is deprecated, please use Fiddle
Select OS type:

  1) UN*X
  2) Windows

Select number: 1 ← serverspecでチェックするマシンがUnix系なのかWindows系なのかを選択

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 1 ← SSHで接続するリモートサーバなのか、ローカルサーバなのか。

Vagrant instance y/n: y ← Vagrantで作成したマシンなのか
Auto-configure Vagrant from Vagrantfile? y/n: y ← Vagrantfileを元にしてserverspecの設定ファイルを勝手に作ってくれる
 + spec/
 + spec/default/
 + spec/default/sample_spec.rb
 + spec/spec_helper.rb
 + Rakefile
 + .rspec

初期化すると、上記に書かれているファイルができている。
特に修正するわけでもなく、早速テストしてみる。

user_name@computer_name ~/VirtualBoxMachines/test
$ rake spec
rake aborted!
Circular dependency detected: TOP => spec => spec:all => spec:default => spec:all

Tasks: TOP => spec => spec:all => spec:default
(See full trace by running task with --trace)

エラーになった・・・。
原因をググって見ると、下記の様な記事が出てきたので、とりあえず記事通りに修正してみる。
https://saintaardvarkthecarpeted.com/blog/archive/2014/10/_Circular_dependency_detected__error_in_ServerSpec.html

user_name@computer_name ~/VirtualBoxMachines/test
$ vim Rakefile
require 'rake'
require 'rspec/core/rake_task'

task :spec    => 'spec:all'
task :default => :spec

namespace :spec do
  targets = []
  Dir.glob('./spec/*').each do |dir|
    next unless File.directory?(dir)
    targets << File.basename(dir)
  end

  task :all     => targets
  # task :default => :all ← ここをコメントアウトする

  targets.each do |target|
    desc "Run serverspec tests to #{target}"
    RSpec::Core::RakeTask.new(target.to_sym) do |t|
      ENV['TARGET_HOST'] = target
      t.pattern = "spec/#{target}/*_spec.rb"
    end
  end
end

もう一回試しに走らせてみる。
user_name@computer_name ~/VirtualBoxMachines/test
$ rake spec
/usr/local/bin/ruby.exe -I'/usr/local/lib/ruby/gems/2.1.0/gems/rspec-support-3.2.1/lib':'/usr/local/lib/ruby/gems/2.1.0/gems/rspec-core-3.2.0/lib' '/usr/local/lib/ruby/gems/2.1.0/gems/rspec-core-3.2.0/exe/rspec' --pattern 'spec/default/*_spec.rb'
DL is deprecated, please use Fiddle

Package "httpd"
  should be installed (FAILED - 1)

Service "httpd"
  should be enabled (FAILED - 2)
  should be running (FAILED - 3)

Port "80"
  should be listening (FAILED - 4)

Failures:

  1) Package "httpd" should be installed
     On host `default'
     Failure/Error: it { should be_installed }
       expected Package "httpd" to be installed
       sudo -p 'Password: ' /bin/sh -c rpm\ -q\ httpd
       package httpd is not installed

     # ./spec/default/sample_spec.rb:4:in `block (2 levels) in '

  2) Service "httpd" should be enabled
     On host `default'
     Failure/Error: it { should be_enabled }
       expected Service "httpd" to be enabled
       sudo -p 'Password: ' /bin/sh -c chkconfig\ --list\ httpd\ \|\ grep\ 3:on

     # ./spec/default/sample_spec.rb:8:in `block (2 levels) in '

  3) Service "httpd" should be running
     On host `default'
     Failure/Error: it { should be_running }
       expected Service "httpd" to be running
       sudo -p 'Password: ' /bin/sh -c ps\ aux\ \|\ grep\ -w\ --\ httpd\ \|\ grep\ -qv\ grep

     # ./spec/default/sample_spec.rb:9:in `block (2 levels) in '

  4) Port "80" should be listening
     On host `default'
     Failure/Error: it { should be_listening }
       expected Port "80" to be listening
       sudo -p 'Password: ' /bin/sh -c netstat\ -tunl\ \|\ grep\ --\ :80\\\

     # ./spec/default/sample_spec.rb:13:in `block (2 levels) in '

Finished in 0.33207 seconds (files took 19.95 seconds to load)
4 examples, 4 failures

Failed examples:

rspec ./spec/default/sample_spec.rb:4 # Package "httpd" should be installed
rspec ./spec/default/sample_spec.rb:8 # Service "httpd" should be enabled
rspec ./spec/default/sample_spec.rb:9 # Service "httpd" should be running
rspec ./spec/default/sample_spec.rb:13 # Port "80" should be listening

/usr/local/bin/ruby.exe -I'/usr/local/lib/ruby/gems/2.1.0/gems/rspec-support-3.2.1/lib':'/usr/local/lib/ruby/gems/2.1.0/gems/rspec-core-3.2.0/lib' '/usr/local/lib/ruby/gems/2.1.0/gems/rspec-core-3.2.0/exe/rspec' --pattern 'spec/default/*_spec.rb' failed

テストは通ってない(apacheインストールしてないので当然ですが)けど、動きました。
真っ赤っ赤で不安になる。
ちなみにテストが通る様になった時の結果がこれ。

user_name@computer_name ~/VirtualBoxMachines/test
$ rake spec
/usr/local/bin/ruby.exe -I'/usr/local/lib/ruby/gems/2.1.0/gems/rspec-support-3.2.1/lib':'/usr/local/lib/ruby/gems/2.1.0/gems/rspec-core-3.2.0/lib' '/usr/local/lib/ruby/gems/2.1.0/gems/rspec-core-3.2.0/exe/rspec' --pattern 'spec/default/*_spec.rb'
DL is deprecated, please use Fiddle

Package "httpd"
  should be installed

Service "httpd"
  should be enabled
  should be running

Port "80"
  should be listening

Finished in 0.1375 seconds (files took 15.45 seconds to load)
4 examples, 0 failures

緑色になって安心。
こうなるまでひたすらAnsibleのplaybookを修正し続ける。