Getting started with Serverspec

Writing automated tests for code is almost always a good idea; however testing server configuration is often overlooks. There are some great tools out there to help you automat testing servers. Serverspec is one tool that can be used to do this.

Serverspec allows you to write RSpec tests for server infrastructure. As a bonus Serverspec is also agent-less and can be run via SSH. This is great because it means you don't need to worry about distributing test code.

Installing Serverspec

On CentOS Serverspec can be installed using the RubyGems package manager. First install the required ruby packages:

yum install -y rubygem-rake rubygems

You can then install Serverspec using the gem command:

gem install serverspec

Note: The commands above should normally be run as root, however you can install gems as a non-root user. If you do this the gems will be unpacked in ~/.gem instead of /usr/local/share/gems/.

Setting up a simple spec file

Before getting started make sure you have configured SSH keys to allow you to connect to the server you want to test:

$ ssh-keygen
$ ssh-copy-id remote.example.com

You can then run serverspec-init to setup a basic Serverspec structure:

$ 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: remote.example.com
 + spec/
 + spec/remote.example.com/
 + spec/remote.example.com/sample_spec.rb
 + spec/spec_helper.rb
 + Rakefile
 + .rspec

This will create a spec file (sample_spec.rb) with some example tests similar to the following:

require 'spec_helper'

describe package('httpd') do
  it { should be_installed }
end

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

describe port(80) do
  it { should be_listening }
end

Note: the example above is a simplified version of the spec file serverspec-init will normally produce.

Running tests

serverspec-init will also create a rakefile which can be used to run rspec:

$ rake spec
/usr/bin/ruby -I/usr/local/share/gems/gems/rspec-core-3.5.4/lib:/usr/local/share/gems/gems/rspec-support-3.5.0/lib /usr/local/share/gems/gems/rspec-core-3.5.4/exe/rspec --pattern spec/remote.example.com/\*_spec.rb

Package "httpd"
  should be installed

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

Port "80"
  should be listening (FAILED - 3)
...

RSpec will look in .rspec for options, however these can be overridden using the SPEC_OPTS variable. For example if you want to use the progress formatter:

$ rake spec SPEC_OPTS='--format progress'
/usr/bin/ruby -I/usr/local/share/gems/gems/rspec-core-3.5.4/lib:/usr/local/share/gems/gems/rspec-support-3.5.0/lib /usr/local/share/gems/gems/rspec-core-3.5.4/exe/rspec --pattern spec/remote.example.com/\*_spec.rb
.FFF

You can also run spec files directly using the rspec command:

$ export GEM_PATH=/usr/local/share/gems/
$ rspec spec/remote.example.com/sample_spec.rb

Package "httpd"
  should be installed

Service "httpd"
  should be enabled
  should be running

Port "80"
  should be listening

Finished in 0.38349 seconds (files took 0.28304 seconds to load)
4 examples, 0 failures

Where next?

Once you've got Serverspec up and running, the resource types section on the Serverspec site is worth a visit. It's full of examples which should make writing you're first few tests easy.