お仕事でWindowsサーバをserverspecでテストしたい!という要件があり、ご自宅のWindows PCで色々と実験するための環境を作ってみた。
動作環境
ご自宅にはマトモな環境が無いので、WindowsマシンをホストOSにして、VirtualBoxでLinuxのゲストOSを作った。ゲストOSでserverspecを実行し、リモートでホストOSをテストできるようにする。
- ホストOS(テスト対象ホスト)
- OSはWindows7 Home Premium
- ゲストOS用にVirtualBox 4.3.2をインストール
- ゲストOS(serverspec実行環境)
- テスト対象ホストのVirtualBoxで動作。ネットワーク設定は以下の通り。
- アダプター1はNAT
- アダプター2はホストオンリーアダプター
- OSはCentOSで、事前にRubyがインストールされている。バージョンは以下の通り。
- CentOS 6.3
- Ruby 2.0.0p481
- テスト対象ホストのVirtualBoxで動作。ネットワーク設定は以下の通り。
serverspecの設定を行う
serverspec実行環境にserverspecをインストールする。
まずはserverspec用のディレクトリを作る。
$ mkdir serverspec
$ cd serverspec
Gemfileにserverspec等、必要なgemを書いてインストールする。
Windowsホストをリモートでテストする為に、winrmもインストールする。
$ vi Gemfile
$ cat Gemfile
source 'https://rubygems.org'
gem 'serverspec'
gem 'rake'
gem 'winrm'
$ bundle install --path=vendor/bundle
serverspec-initコマンドを実行し、設定のひな型を作成する。
OS typeに「Windows」、backend typeに「WinRM」を選択する。
bundle exec serverspec-init
Select OS type:
1) UN*X
2) Windows
Select number: 2
Select a backend type:
1) WinRM
2) Cmd (local)
Select number: 1
+ spec/
+ spec/localhost/
+ spec/localhost/httpd_spec.rb
+ spec/spec_helper.rb
+ Rakefile
動く事が確認出来れば良いので、とりあえずホスト名をテストするシナリオを作成する。
※デフォで作成されるhttpd_specは、邪魔だったので一旦削除した。
$ vi spec/localhost/host_spec.rb
$ cat spec/localhost/host_spec.rb
require 'spec_helper'
describe command('hostname') do
its(:stdout) { should match /Win-PC/ }
end
serverspecの設定はひとまずここで完了。
テスト対象ホストでWinRMを設定する。
WinRM(Windows Remote Management)は、HTTP/HTTPSでコンピュータをリモート管理するプロトコルで、serverspecからリモートのWindowsホストをテストする際も、WinRMでアクセスしてテストするのが一般的らしい。
まずは、管理者権限でpower shellを起動する。
「アクセサリ」->「Windows PowerShell」->「Windows PowerShell」を右クリックして「管理者として実行」をクリックし起動する。
以下のコマンドを発行し、WinRMの初期設定を行う。
PS C:\windows\system32> winrm qc
WinRM はこのコンピューター上で要求を受信するように設定されていません。
次の変更を行う必要があります:
WinRM サービスを開始します。
変更しますか [y/n]? y
WinRM は要求を受信するように更新されました。
WinRM サービスが開始されました。
このコンピュータ上のあらゆる IP への WS-Man 要求を受け付けるため、HTTP://* 上に WinRM リスナを作成します。
変更しますか [y/n]?
WinRM はリモート管理用に更新されました。
WinRM サービスの種類を正しく変更できました。
WinRM サービスが開始されました。
このコンピュータ上のあらゆる IP への WS-Man 要求を受け付けるため、HTTP://* 上に WinRM リスナを作成しました。
接続ネットワークに、PrivateもしくはDomain以外のものが存在する場合、以下のエラーが発生する。今回はVirtualBox Host-Only Networkが「識別されていないネットワーク」になっていた為、このエラーでハマってしまった。
Set-WSManQuickConfig : このコンピューターのネットワーク接続の種類の 1 つが Public に設定されているため、WinRM ファイアウォール例外は機能しません。
ネットワーク接続の種類を Domain または Private に変更して、やり直してください。
ローカル・セキュリティ・ポリシー等で設定可能なようだが、Windows7がHome Premiumである為使えず。。。なので、以下リンクの通りレジストリを修正して対応する。
次にBasic認証と暗号化していないメッセージを受けるけるよう設定する。
この設定を行っていないと、テスト実行時に401エラーが出てテストがfailになる。
PS C:\windows\system32> winrm set winrm/config/service/auth '@{Basic="true"}'
Auth
Basic = true
(略)
PS C:\windows\system32> winrm set winrm/config/service '@{AllowUnencrypted="true"}'
Service
(略)
AllowUnencrypted = true
(略)
serverspec用のユーザーを作成する。コントロールパネルのユーザーアカウントから管理者権限をつけたユーザーを作成。
これでWinRMの設定は完了。
serverspecを実行する。
実行する前に、ユーザー情報をspec_helper.rbに設定する。
$ vi spec/spec_helper.rb
$ cat spec/spec_helper.rb
require 'serverspec'
require 'winrm'
set :backend, :winrm
user = '(WIndowsユーザー名)'
pass = '(パスワード)'
endpoint = "http://#{ENV['TARGET_HOST']}:5985/wsman"
winrm = ::WinRM::WinRMWebService.new(endpoint, :ssl, :user => user, :pass => pass, :basic_auth_only => true)
winrm.set_timeout 300 # 5 minutes max timeout for any operation
Specinfra.configuration.winrm = winrm
テストを実行する。テスト通った。
bundle exec rake spec
/usr/local/rvm/rubies/ruby-1.9.3-p448/bin/ruby -S rspec spec/localhost/host_spec.rb
.
Finished in 0.64601 seconds
1 example, 0 failures
これでWindowsサーバのテストシナリオの実装が捗るぜ!