serverspec

서버 설정을 테스팅할 수 있는 프로그램. 

http://serverspec.org/

But the true aim of Serverspec is to help refactoring infrastructure code.

사용법은 serverspec 사이트에서 보면 되며 지원하는 리소스 타입

설치

Ubuntu에서 설치 : 일반사용자로 설치를 할 경우에는 퍼미션 관련한 에러가 났다. 일반유저로 설치하는 방법이 있겠지만 그냥 root로 프로그램을 설치를 해 주었다.

$ gem install serverspec
Fetching: serverspec-2.38.0.gem (100%)
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /var/lib/gems/2.3.0 directory.
# gem install serverspec

설정

설정하기 : serverspec-init 을 실행하고 원하는 hostname 을 입력하면 샘플 spec file로 spec/www.example.jp/sample_spec.rb 가 생성이 된다.

$ serverspec-init
Select OS type:

  1) UN*X
  2) Windows

Select number: 1

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 1

Vagrant instance y/n: n
Input target host name: www.example.jp

SSH를 이용하여 원격에 있는 서버를 대상으로 실행을 할 때에는 사전에 ssh 설정이 적절하게 되어 있어야 한다.

위와 같이 실행을 한 경우 serverspec에서 다음과 같은 텟플릿을 구성을 한다. 각 호스트당 테스트를 구성할 수 있다.

|-- Rakefile
`-- spec
    |-- spec_helper.rb
    `-- www.example.jp
        `-- sample_spec.rb


실행하기

테스팅 실행하기

$ rake spec
....

위 명령 실행시 http://serverspec.org/ 페이지에는 "/usr/bin/ruby -S rspec spec/www.example.jp/sample_spec.rb" 이라고 되어 있는데 이런 식으로 실행을 할 경우에는 serverspec 을 설치한 서버에 처음 로그인을 한 user로 로그인을 시도한다. 

spec/spec_helper.rb 에서 변경을 하면 된다고 하는데 ruby 를 잘 몰라서 어떻게 해결을 할 수 있는지는 모르겠다.

그렇지만 rake spec으로 실행을 할 때는 현재 로그인되어 있는 user로 실행을 하기 때문에 문제가 없었다.


테스팅

10.210.200.187 host에 대해서 테스팅 케이스를 생성을 함.

$ cat spec/10.210.200.187/myexample_spec.rb
require 'spec_helper'

describe file('/mydir') do
  it { should be_mounted.with( :device => '/dev/xvdb' ) }
end

describe package('docker-engine') do
  it { should be_installed }
end

describe service('docker')  do
  it { should be_enabled }
  it { should be_running }
end

describe service('collectd')  do
  it { should be_enabled }
  it { should be_running }
end

describe service('log-forward')  do
  it { should be_enabled }
  it { should be_running }
end

describe service('telegraf')  do
  it { should be_enabled }
  it { should be_running }
end

describe file('/mydir') do
  it { should be_owned_by 'myexample' }
  it { should be_grouped_into 'myexample' }
end

describe command('getent passwd | grep ":/home:"') do
  its(:exit_status) { should eq 0 }
end

위와 같이 작성을 한 후 rake spec 명령을 실행함.

$ rake spec
/usr/bin/ruby2.3 -I/var/lib/gems/2.3.0/gems/rspec-support-3.5.0/lib:/var/lib/gems/2.3.0/gems/rspec-core-3.5.4/lib /var/lib/gems/2.3.0/gems/rspec-core-3.5.4/exe/rspec --pattern spec/10.210.200.187/\*_spec.rb

File "/mydir"
  should be mounted

Package "docker-engine"
  should be installed

Service "docker"
  should be enabled
  should be running

File "/mydir"
  should be owned by "myexample"
  should be grouped into "myexample"

Command "getent passwd | grep ":/home:""
  exit_status
    should eq 0

Finished in 1.38 seconds (files took 0.24832 seconds to load)
13 examples, 0 failures

How to use Serverspec tests as shared behaviors

http://serverspec.org/advanced_tips.html 에서 How to use Serverspec tests as shared behaviors 를 이용하면 각종 테스트 케이스를 만들어서 여러 호스트에서 이용을 할 수 있다.

그렇지만 위 문서에는 설명이 나와있는데 이 경우 serverspec 관련한 몇가지 소스를 수정을 할 필요가 있다.  Rakefile, spec/spec_helper.rb 두가지를 수정을 해주면 된다.


serverspec-init 을 실행하여 10.210.200.77 서버에 대해서 설정을 한 초기 설정

$ tree serverspec
serverspec
|-- Rakefile
`-- spec
    |-- 10.210.200.77
    |   `-- myexample_spec.rb
    `-- spec_helper.rb

함께 사용을 할 test를 spec/shared 디렉토리에 구성을 한다.

$ tree serverspec.test/
serverspec.test/
|-- Rakefile
`-- spec
    |-- 10.210.200.77_spec.rb
    |-- shared
    |   `-- base
    |       `-- init.rb
    `-- spec_helper.rb

Rakefile은 https://github.com/rubyisbeautiful/serverspec_examples/blob/master/Rakefile 을 그대로 이용을 한다.

Rakefile은 테스팅을 할 대상 서버, test spec 파일을 어떻게 가져올지를 지정을 하는 부분이다.  task가 기본 샘플파일 설정인 spec이 아닌 serverspec 이므로 이 부분을 조심해야 한다.

이 파일을 이용할 경우 rake targets 를 이용하면 어떤 서버를 대상으로 하는지 보여주여서 편리하다.

$ rake targets
10.210.200.77

이제 기본으로 생성이 된 spec_helper.rb 파일을 변경을 해주어야 한다.

https://github.com/rubyisbeautiful/serverspec_examples/blob/master/spec/spec_helper.rb 파일을 참고하면 된다.

우리가 필요한 것은 spec/shared/base/init.rb 를 불어오는 부분인데 shared/ 밑에서 rb 파일을 불러오는 부분만 수정을 해서 사용을 하면 된다.

$ diff -bBu serverspec/spec/spec_helper.rb serverspec.test/spec/spec_helper.rb
--- serverspec/spec/spec_helper.rb      2017-03-08 17:40:59.228563714 +0900
+++ serverspec.test/spec/spec_helper.rb 2017-03-09 14:50:21.705362038 +0900
@@ -1,5 +1,11 @@
 require 'serverspec'
 require 'net/ssh'
+require 'pathname'
+
+
+base_spec_dir = Pathname.new(File.join(File.dirname(__FILE__)))
+
+Dir[base_spec_dir.join('shared/**/*.rb')].sort.each{ |f| require f }

 set :backend, :ssh


실행하기 :  rake serverspec 으로 실행

$ rake targets
10.210.200.77

$ rake serverspec
...

How to share Serverspec tests among hosts

http://serverspec.org/advanced_tips.html : 여러 개의 호스트에서 serverspec 테스트 공유하는 방법. 여러 개의 role을 구성하여 테스트를 구성할 수 있다.

관련자료

http://serverspec.org/advanced_tips.html : 여러 개의 호스트에서 serverspec 테스트 공유하는 방법, 특정 호스트별 변수 설정, 병렬 실행, sudo 제어하기 등 내용이 있음.

https://github.com/rubyisbeautiful/serverspec_examples : 예제