どうも、Kohei(@koheinishino_)です。
今回はServerspecの使い方と注意点について解説します。
Serverspec(サーバースペック)とは、サーバー状態のテストを自動化するためのフレームワークです。
「nginxがインストールされているか」や「80番ポートがリッスン状態になっているか」など、構築したサーバ環境が意図した通りに構成されているかを自動で確認できます。
RubyでつくられておりRubyのテストフレームワークであるRSpecとほぼ同じ書き方ができるので、Rubyのエンジニアであれば比較的とっつきやすいことも特徴です。
この記事を読むことでServerspecの使い方や躓きやすいポイントについて理解して、サーバーのテスト自動化をサクッと実現できるようになります。
初めてServerspecを導入することになったけど使い方がよくわからない…。
Serverspecの使い方や注意点を知りたい!
と悩まれている方は是非最後までお読みください!
今回の記事作成にあたり、下記のサイトを参考にさせていただきました。
Serverspecの使い方
前提条件
Rubyが必要なのでrbenv等でインストールしておきましょう。
Serverspecはgemとしてインストールので、必要に応じてBundlerもインストールしておいてください。本記事ではBundlerを使ってインストールする方法で解説していきます。
また、AWSのEC2等の外部のサーバーのテストを実施する場合は事前にSSH接続の設定を行っておいてください。本記事ではOSがAmazonLinux2のEC2サーバーをテストする想定で設定していきます。
インストール手順
Serverspec用のディレクトリを作成し、ディレクトリ内で下記コマンドを実行してGemfileを生成します。
$ bundle init
そして、Gemfileの内容を下記のように編集します。rakeコマンドでテストを実行するため、Rakeのgemもインストールします。
source "https://rubygems.org"
gem 'serverspec'
gem 'rake'
Gemfileの編集が終わったら下記のコマンドでインストールしましょう。
$ bundle install
Serverspecの初期設定
gemのインストールが完了したら、引き続き下記のコマンドでServerspecの初期設定を行います。
$ bundle exec 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: example.com
+ spec/
+ spec/example.com/
+ spec/example.com/sample_spec.rb
+ spec/spec_helper.rb
+ Rakefile
+ .rspec
4つ答える箇所があり、それぞれ下記のように入力します。
- OSのタイプは何か?→UN*Xなので”1“を入力
- 接続方法は何か?→SSH接続するため”1“を入力
- Vagrantを使ったインスタンスか?→今回は使わないので”n“(No)を入力。
- テスト対象のサーバーのホスト名は何か?→”SSHのconfigに記載したホスト名かIPアドレス(ここではexample.com)”を入力
※ Vagrantとは、仮想環境を操作するためのソフトウェアです。
入力が完了するとServerspecの実行に必要なファイル群が生成されます。
各ファイルの説明
ファイル名 | 内容 |
---|---|
Rakefile | rakeコマンドを使ってテストを実行するための設定ファイル。 |
spec_helper.rb | Serverspecを使ってテストを実行する際のテスト設定などを記述したRubyスクリプト。 |
sample_spec.rb | テストスクリプト本体。デフォルトではWebサーバーの設定テストのための項目がサンプルとして記述されている。 |
実際に私が作成したServerspecのファイルはコチラのGitHubリポジトリにプッシュしてあるので、参考にしてみてください。
テスト実行
下記コマンドでテストを実行します。***_spec.rbというファイルが全て実行されるため、ファイルごとにテスト項目を分けて管理するのもOKです。
$ bundle exec rake spec
Serverspecの注意点
ここからはServerspecの注意点について解説します。テストが上手くいかないという方は参考にしてみてください。
下記の参考サイトにテスト項目の例がたくさん存在するので、私自身テスト項目の用意には時間はかかりませんでした。
しかし、何度やってもテストがパスしない項目がいくつかありました。具体的には下記のテスト項目です。
# Ruby2.4.5がインストールされていること
describe command('ruby -v') do
its(:stdout) { should match /ruby 2\.4\.5+/ }
end
# TCPの80番ポートがリッスン状態になっていること
describe port(80) do
it { should be_listening.with('tcp') }
end
EC2を直接見に行ってもテストはパスする状態になっているはずなのにテストが通らないのです。
サーバー側とServerspec側で環境の違いがあるはず!
と推測し問題を切り分けていき、原因を特定して解決できました。私が詰まって感じた主な注意点を2つ紹介します。
SSH経由だとPATHが通っていないことがある
SSH経由だとPATHが通っていないことがあるそうです。
Serverspecではテスト実行時に任意のコマンドを対象サーバーに実行してテストがパスするかを判定しているのですが、PATHが通っていないことでコマンドが使えずにテストが失敗するケースがあります。
私の場合はEC2内にRubyをインストールする際に~/.bash_profileでPATHを通しており、これがSSH接続によって読み込まれなくてServerspecがコマンドを使えなかったことが原因でした。
「spec_helper.rb」の下記の行がコメントアウトされているとsbin関連のディレクトリに格納されているコマンドが使えないこともあるので、こちらも合わせて確認してみてください。
# Set PATH
set :path, '/sbin:/usr/local/sbin:$PATH'
下記のテストを実行して、Serverspecが読み込んでいるPATHを確認してみるのもオススメです。
# Serverspecで読み込めるPATHを確認
describe command('echo $PATH') do
its(:stdout) { should match hoge }
end
想定と異なる権限で実行されていることがある
また、Serverspecはデフォルトでsudo権限つきで実行されるため、権限周りでテストが上手くいかないことも多いです。
sudo権限で実行するかどうかは「spec_helper.rb」の下記の行で変更可能です。この例ではsudo権限で実行されないようにしています。
# Disable sudo
set :disable_sudo, true
下記のテストを実行して、Serverspecがどの権限で実行されているかを確認してみるのもオススメです。
# Serverspecがどの権限で実行されているかを確認
describe command('whoami') do
its(:stdout) { should match root }
end
まとめ:Serverspecを導入してサーバーテストに自動化にチャレンジ
Serverspecの使い方と注意点について解説しました。特に伝えたいところは最後の注意点の部分です。
私自身、Serverspecで色々なテストを書いてみるとPATHや権限周りの理解が浅かったなと実感しました…。初学者のころは予備知識が足りなくて避けてきましたが、現在は少し理解できるようになった気がします。
少し話が逸れてしまいましたが、使い方自体はそこまで難しくないツールだと思うので是非サーバーのテスト自動化へチャレンジしてみてください!