Serverspecの概要からインストールまで
Serverspecのインストール
ServerspecはRubyのgemパッケージとして配布されています。そのため、RubyおよびRubygemsがインストールされている環境であれば、以下のコマンドだけでインストール完了です。
$ sudo gem install serverspec
このコマンドを実行すると、Specinfraなどの依存するパッケージもすべてインストールされます。
Serverspecの初期化処理
Serverspecの実行元サーバ上で初期化処理(serverspec-init)を行います。
$ serverspec-init Select OS type: 1) UN*X 2) Windows Select number: 1 ←テスト対象サーバのOS種別を選択 Select a backend type: 1) SSH 2) Exec (local) Select number: 1 ←テスト実行のタイプを選択 Vagrant instance y/n: n ←Vagrantの管理下のインスタンスかどうかを選択 Input target host name: server-01 ←テスト対象サーバのホスト名を入力 + spec/ + spec/server-01/ + spec/server-01/httpd_spec.rb + spec/spec_helper.rb + Rakefile
上記はLinuxマシン(server-01)に対してSSH接続でテストする場合の実行例です。Windowsマシンに対してWinRM接続でテストする場合には、OS typeを「2) Windows」、backend typeを「1) WinRM」に設定して初期化します。
この初期化処理により、テスト実行に最低限必要なファイル群が生成されます。そのうちの1つであるspec_helper.rbの中には、対象サーバに接続するための設定が含まれます。そのため、初期化実行時の選択内容に応じてspec_helper.rbの中身が変わります。実際のテストコードは生成された「spec//」ディレクトリの中のxxx_spec.rbです。serverspec-initを実行するとデフォルトでApache HTTP Serverのテストコードであるhttpd_spec.rbがサンプルとして作成されます。
接続設定
先述した通り、Serverspecをリモートにあるサーバに対して実行する場合には接続設定が必要となります。
SSH接続の場合
SSH接続の場合には、セキュリティ面を考慮して、公開鍵認証での接続を利用することをお勧めします。
テスト対象のサーバに公開鍵認証での接続設定をした上で、Serverspec実行元サーバに対して以下の設定を実施します。まずServerspecを実行するユーザが、対象サーバにSSH接続する際に秘密鍵を読み込んで接続できるようにするため、SSH接続を設定します。Serverspecでは、初期化処理時に設定したホスト名をもとに対象サーバに接続します。そのため、そのホスト名でのSSH接続時に作成した秘密鍵を読み込んで接続を実行できるようSSHクライアントを設定します。たとえば、ホームディレクトリ以下の.ssh/configに以下のように記述します。
Host server-01 HostName 10.0.0.10 Port 22 User user1 IdentityFile ~/.ssh/serverspec-key
こうすることで、Serverspecがspec/server-01ディレクトリ以下のテストコードを実行する際、server-01にuser1というユーザ名で~/.ssh/serverspec-keyという鍵ファイルを使って接続を試みることになります。また接続時にインタラクティブにパスワード入力を求められないよう、事前にパスフレーズなしで公開鍵認証できるように設定しておきます。
WinRM接続の場合
WinRMの場合、テスト実行対象のWindowsマシンにてwinrm qcコマンド等を利用してWindows Remote Managementサービスを起動し、WinRMの接続設定を実施します。
Serverspec実行元サーバには、WinRM接続用に追加でwinrmというgemパッケージをインストールします。
$ sudo gem install winrm
serverspec-init実行時にWinRMで実行するように進めると以下のようなspec_helper.rbが作成されます。
require 'serverspec' require 'winrm' include SpecInfra::Helper::WinRM include SpecInfra::Helper::Windows RSpec.configure do |c| user = <user name> pass = <password> endpoint = "http://<hostname>:5985/wsman" c.winrm = ::WinRM::WinRMWebService.new(endpoint, :ssl, :user => user, :pass => pass, :basic_auth_only => true) c.winrm.set_timeout 300 # 5 minutes max timeout for any operation end
ここにWinRM接続情報を記述することで、Windowsマシンに対して接続してテストを実行できます。
sudo実行設定
テスト実行対象サーバがLinuxマシンの場合、稼働状況の確認用のコマンドを実行する際に「sudo」をつけて実行する仕様となっています。そのため、先述の接続設定の時に指定したユーザに対してsudoの実行権限を付与する必要があります。テスト実行対象サーバ内で、以下の設定を実施します。
# visudo user1 ALL=(ALL) ALL
上記のように設定すると、sudo実行時にユーザのパスワードを聞かれます。パスワードについてはSUDO_PASSWORD環境変数に設定するか、環境変数にパスワードを設定したくない場合には、ASK_SUDO_PASSWORD環境変数を1に設定することでServerspec実行時にインタラクティブにパスワード入力を求められるようになります。
テストコードの作成
実行したいテストコードはserverspec-init実行時に作成されたフォルダの中に作成します。フォルダ構成としては以下のような形となります。
Rakefile spec/ - spec_helper.rb - server-01/ - httpd_spec.rb - xxx_spec.rb ・・・・ - server-02/ ・・・・
Serverspecのテスト実行時の読み込みファイルの設定等は、Rakefileにて定義されています。標準のRakefileの記述では、specディレクトリ以下の各ディレクトリ内のxxx_spec.rbという名前のファイルが読み込まれて、順次テストが実行されるようになっています。
require 'rake' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) do |t| t.pattern = 'spec/*/*_spec.rb' end task :default => :spec
そのためテストコードを追加作成する場合は、xxx_spec.rbのような名前でファイルを作成して「spec/接続先サーバ名ディレクトリ/」以下に配置します。テストコードのファイルは、Webサーバやデータベースサーバ、セキュリティ設定関連のテストというように、テストの種類毎に分類して作成するなど、環境にあわせて管理しやすい形で分割することをお勧めします。またRakefileの内容を修正すれば、特定のディレクトリ以下のテストコードのみ実行するなどの応用も可能です。
テスト実行
Serverspecのテストを実行するためには、rakeコマンドを利用します。先述したRakefileにタスクが定義されています。rakeコマンドを利用することで、この記述に従ってテストコードの内容が実行されます。標準のRakefileには「spec」という名前のRakeタスクが定義されていて、これを実行することで先述した通りに各テストコードが実行される仕組みになっています。
$ rake spec
また特定のテストファイルのみ実行したければ、rspecコマンドを利用して以下のようにテストファイルを指定します。
$ rspec spec/server-01/httpd_spec.rb
Serverspecの出力は、デフォルトではテスト結果が正常なら「.」のみ、失敗した場合には「F」とその状況が表示される形式となっています。より詳細に実行結果を表示したい場合には、Serverspecの実行元サーバにてテストを実行するユーザのホームディレクトリ直下に以下のようなファイルを作成します。
$ vim ~/.rspec --format documentation
これにより、テスト結果の出力は以下のようになります。
$ rake spec Package "python" should be installed Finished in 0.24518 seconds 1 examples, 0 failures
テストコードの記述方法
テストコードは「ResourceType」と「Matcher」の2つの要素から成り立っています。
ResourceType
ResourceTypeはテストの対象となるリソースを定義します。標準でサポートしているResourceTypeはこちらにまとめられています。サーバ内のファイルやプロセス、パッケージなどがResourceTypeに相当します。
Matcher
MatcherとはResourceTypeの状態を定義するもので、ResourceTypeの種類毎にサポートされるMatcherは異なります。ResourceType一覧のページに、各Matcher毎の例がまとめられています。
テストコードの書式
テストコードの書式は以下のようになります。
例1:「◯◯◯が△△△であるべきである」という形のテスト
具体例として、「pythonというパッケージ」が「インストールされているべきである」というテストコードは以下のようになります。
require 'spec_helper' describe package('python') do it { should be_installed } end
例2:「◯◯◯の□□□が△△△であるべきである」という形のテスト
具体例として、「server-01というホスト」の「IPアドレス」が「10.1.1.2であるべきである」というテストコードは以下のようになります。
require 'spec_helper' describe host('server-01.example.com') do its(:ipaddress) { should eq '10.1.1.2' } end
このようにServerspecのテストコードはRSpec形式の記法となっており、テストしたい内容を非常に読みやすい形で記述できます。
まとめ
ServerspecはChefやAnsibleによる自動処理とセットで活用することで、非常に効果を発揮するテストフレームワークです。迅速で正確な環境セットアップに欠かせないものではないでしょうか。内部の仕組みや利用方法についても、本記事で紹介したように非常にシンプルになっています。「構築したつもりだったが設定漏れがあり、障害の原因となった」といった苦い経験をされたことがある方は、ぜひお試しいただくことをお勧めします。今回は、仕組みや基本的な利用の流れについて触れました。次回は、より具体的なケースをもとにテストコードの書き方を解説します。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Serverspecの効果的活用に向けたTips
- Serverspecテストコード実例の紹介とコード記述の際のポイント
- Ansibleにおいてテストを行う理由
- 開発チームの環境をAnsibleで一括構築しよう
- RailsのテストフレームワークRSpecの基礎知識
- テスト駆動インフラ/インフラCIの潮流、Serverspecが果たす役割
- Serverspec誕生からインフラCIの今後までを開発者に聞いてみた
- マシン・イメージを自動構築し、作業効率を高めるPacker入門
- WordPress コース 2nd Stage を攻略しよう(Linux 仮想マシン編)
- Windows Azure上にLinuxインスタンスを立ち上げる(クエスト5)