IDCF テックブログ

IDCF テックブログ

クラウド・データセンターを提供するIDCフロンティアの公式テックブログ

Serverspecでテスト自動化

Serverspecとは

こんにちは。山田です。 まさかとは思いますが、2017年にもなってサーバーのテストを片手にエクセルのテスト項目をもち、目視で確認している人はいないとは思います。 実はまだ、お手てで頑張ってテストをしている。そんな人に今回の記事を贈ります。 いつまでも旧態然としたエクセル主義を撲滅するためにもServerspecでテストを自動化し、周りの上司へ「一台ずつ確認してるんですか〜?」と言ってやってください。 今回はIDCFクラウド上にてServerspecを構築し、実際のテストを行うまでの手順をご紹介します。

Serverspecのすごいところは以下通りです。

  • サーバーの設定/状態が正しいか一瞬でチェックできる。
  • サーバーにエージェントなどをインストールする必要がない。
  • プログラミング未経験でもなんとかなるようにできている。

f:id:nhashiguchi:20170703074934p:plain

使用目的

Serverspecは元々、インフラコードのリファクタリングを目的に開発されていますが、 様々な目的に使用することが可能です。

  • サーバー・ネットワーク機器の設定/構築作業における確認手順の自動化
  • 既存サーバーの状態確認
  • Serverspecの真の目的であるインフラコードのリファクタリング

今回のお話では、サーバーの設定/構築作業における確認手順の自動化に絞ってお伝えします。 例えば手順書ベースで確認作業を行なう場合、見落としが発生したり、確認作業の長期化などの問題があります。 そこでServerspecを使うと下記のメリットがあります。

  • 見落としがない
  • 属人化の解消
  • 作業時間の圧倒的短縮
  • あるべき姿が定義されるので、設定/状態の厳密な確認が可能

では実際どのようにしてサーバーの状態をチェックするのか具体的にみてみましょう。 例えばWordPressをインストールしたサーバーをテストするためには次のようなコードを書きます。

require 'spec_helper'

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

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

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

コードとか書いたことのない人でも、何がしたいのかがわかりますね。
では、実際にServerspecをIDCFクラウド上に構築し、サーバーのテストを行ってみましょう。

IDCFクラウド上に作成する仮想マシンのスペック

今回はIDCFクラウド上でCentOS 7.3がインストールされている仮想マシンを作成します。 詳細は下の表に記載しています。
※IPはDHCPで動的に割り当てられたIPをそのまま利用しています。

ホスト名 マシンタイプ OS
serverspec light.S1 CentOS 7.3

それでは早速Serverspecサーバーを作成していきましょう。

Serverspecユーザー作成

今回はServerspecユーザーを作成し、ユーザーのホームディレクトリ以下に インストールをしていきます。
※今回は検証のため、Serverspecユーザーをwheel(管理者)グループへ追加していますが、皆様の環境に合わせて正しく権限付けしてください。

# useradd serverspec
# usermod -G wheel serverspec
# su - serverspec

ruby,rbenvのインストール

まずは、必要パッケージをインストールします。

$ sudo yum -y groupinstall "Development Tools"
$ sudo yum -y install git openssl-devel readline-devel zlib-devel

上記をインストールしたら、つづいてrubyをインストールします。

まずはgitからクローン

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

パスの設定

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ source ~/.bash_profile

Ruby2.3.4をインストール

$ rbenv install 2.3.4
$ rbenv global 2.3.4

Serverspecのインストール

ユーザーディレクトリにてGemfileを作成します。

$ gem install bundler
$ bundle init

直下にGemfileが作成されるので、 内容を以下に変更

$ vi Gemfile

こんな感じにします。

$ cat Gemfile
source "https://rubygems.org"

gem 'serverspec'
gem 'rake'
gem 'highline'

それではbandleコマンドでServerspecをインストールします。

bundle install --path /home/serverspec/

するとServerspec直下にディレクトリが作成されます。

$ ls
Gemfile  Gemfile.lock  ruby

Serverspecの設定を行います。

$ bundle exec serverspec-init
Select OS type:

  1) UN*X
  2) Windows

Select number: 1 ←今回はCentOSを使用しているので「1」を選択

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 1 ←今回はsshで行なうので「1」を選択

Vagrant instance y/n: n    ←今回はVagrantはつかわないので、「n」を選択
Input target host name: wordpress-server
 + spec/
 + spec/wordpress-server/
 + spec/wordpress-server/sample_spec.rb
 + spec/spec_helper.rb
 + Rakefile
 + .rspec

現在のディレクトリ状況

$ tree  --charset=o  -L  3
.
|-- Gemfile
|-- Gemfile.lock
|-- Rakefile
|-- ruby
|   `-- 2.3.0
|       |-- bin
|       |-- build_info
|       |-- cache
|       |-- doc
|       |-- extensions
|       |-- gems
|       `-- specifications
`-- spec
    |-- spec_helper.rb
    `-- wordpress-server
        `-- sample_spec.rb

11 directories, 5 files

この状態で、Serverspecを使えるようになりました。

複数ホストを指定できるように設定変更

デフォルトのままだと、1つのホストに対してしかServerspecを実行できません。 なので、二つのファイルを書き換え、複数ホストに対応させていきます。

Rakefile

require 'rake'
require 'rspec/core/rake_task'
require 'yaml'
require 'highline/import'

properties = YAML.load_file('properties.yml')

#ENV['SSH_USER'] = ask("Enter ssh user: ") { |q| q.echo = true }
#ENV['SSH_PASSWORD'] = ask("Enter ssh password: ") { |q| q.echo = false }

desc "Run serverspec to all hosts"
task :serverspec => 'serverspec:all'

namespace :serverspec do
  task :all => properties.keys.map {|key| 'serverspec:' + key }
  properties.keys.each do |key|
    desc "Run serverspec to #{key}"
    RSpec::Core::RakeTask.new(key.to_sym) do |t|
      ENV['TARGET_HOST'] = properties[key][:hostname]
      t.pattern = 'spec/{' + properties[key][:roles].join(',') + '}/*_spec.rb'
      t.fail_on_error = false
    end
  end
end

spec_helper.rb

require 'serverspec'
require 'pathname'
require 'net/ssh'
require 'yaml'

set :backend, :ssh
set :path, '/sbin:/usr/sbin:$PATH'
set :request_pty, true

RSpec.configure do |c|
  c.before :all do
    set :host, ENV['TARGET_HOST']
    options = Net::SSH::Config.for(c.host)
    ## for login key + passphrase configurations
    options[:keys] = ENV['KEY'];
    options[:user] = ENV['SSH_USER']
    #options[:password] = ENV['SSH_PASSWORD']
    set :ssh_options, options
  end
end

上記を書き換えたら実行環境は完成です。

では、実際のテスト内容を記載していきます。
まずはspecディレクトリに移動に移動します。
本環境では対象サーバー名を「wordpress-server」としたので、 その名前のディレクトリが作成され、中にsample_spec.rbファイルが格納されています。
この.rbファイルに確認したいテスト内容を記載します。 今回はsample_spec.rbを編集して、実行してみましょう。

$ cd /home/serverspec/spec/wordpress-server
$ vi sample_spec.rb
require 'spec_helper'

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

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

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

describe service('mariadb') do
  it { should be_enabled }
  it { should be_running }
end
describe port(3306) do
  it { should be_listening }
end

describe service('php-fpm') do
  it { should be_enabled }
  it { should be_running }
end
  • Nginxはインストールされているか。
  • Nginxは自動起動設定されているか。サービスが上がっているか。
  • ポート80はLISTENしているか
  • MariaDBは自動起動設定されているか。サービスが上がっているか。
  • ポート3306はLISTENしているか
  • php-fpmは自動起動設定されているか。サービスが上がっているか。
    を確認しています。 その他の設定や、サービスの起動状態なども確認できるので、公式サイトをチェックしてみてください。
    http://serverspec.org/resource_types.html

最後にServerspecをでテストしたい対象と、テストの内容を properties.ymlに記載します。
デフォルトでは存在しないので、新規で作成します。

vi /home/serverspec/properties.yml
wordpress-server:
  :roles:
    - wordpress-server
  :hostname: wordpress-server

今回は一台のみ記載しましたが、この上記と同様の記載を追記していくことで複数のホストを登録できます。 roles部分に記載したものの実態は spec/wordpress-server/sample_spec.rbです。 wordpress-serverディレクトリ以下の*.rbがこのroleで実行されます。 複数のroleを記載して実行することも可能です。

Serverspecを実行

※実行前にテスト対象へのssh接続ができるようにしてください。
 テスト対象への名前解決ができるようにしてください。

$ pwd
/home/serverspec
$ bundle exec rake serverspec --trace KEY=~/.ssh/id_rsa
[serverspec@serverspec ~]$ bundle exec rake serverspec --trace KEY=~/.ssh/id_rsa
** Invoke serverspec (first_time)
** Invoke serverspec:all (first_time)
** Invoke serverspec:wordpress-server-syamada (first_time)
** Execute serverspec:wordpress-server-syamada
/home/serverspec/.rbenv/versions/2.2.3/bin/ruby -I/home/serverspec/ruby/2.2.0/gems/rspec-core-3.6.0/lib:/home/serverspec/ruby/2.2.0/gems/rspec-support-3.6.0/lib /home/serverspec/ruby/2.2.0/gems/rspec-core-3.6.0/exe/rspec --pattern spec/\{wordpress-server-syamada\}/\*_spec.rb

Package "nginx"
/home/serverspec/ruby/2.2.0/gems/specinfra-2.68.0/lib/specinfra/backend/ssh.rb:76:in `create_ssh': Passing nil, or [nil] to Net::SSH.start is deprecated for keys: user
  should be installed

Service "nginx"
  should be enabled
  should be running

Service "mariadb"
  should be enabled
  should be running

Port "3306"
 should be listening

Service "php-fpm"
  should be enabled
  should be running

Port "80"
  should be listening

Finished in 0.41725 seconds (files took 0.24948 seconds to load)
9 examples, 0 failures

** Execute serverspec:all
** Execute serverspec

上記のように完了します。
成功した場合は緑の文字で出力され、失敗の場合は赤字で出力されます。

まとめ

IDCFクラウド上でさくっとServerspecサーバーを立ててサーバーのテストをする方法を紹介しました。 皆様も是非、Serverspecを使って、エクセル管理のテスト項目書の撲滅を目指しましょう。 次はよく使用するテスト項目などの紹介をしてみたいと思います。

Copyright © IDC Frontier Inc.