WindowsでのServerspec

マシン構成をテスト可能にするServerspecですが、ありがたいことにWindowsでも動作します。

ここでは、インストールの手順と、使用方法についてまとめます。

インストール

Rubyのインストール(テスト実行マシンのみ)

ServerspecはRubyのインフラの上で動作するので、Rubyのインストールが必要です。ただし、テスト対象のマシンでインストールする必要性はありません。テストを実行するマシンでだけインストールが必要です。

WindowsにRubyをインストールする方法は何種類もありますが、RubyInstallerを使うのが無難です。

Rubyのダウンロード方法、セットアップについては以下のRubyInstallerのサイトで確認してください。後必ずDevKitのインストールもしておきましょう。

http://rubyinstaller.org/

今後の作業は、Ruby 2.1.5 AMD64版、Devkitがインストール済で有ることを前提に進めます。

gemでのserverspec, rake, winrmのインストール(テスト実行マシンのみ)

Serverspecは実行にRakeを必要としているので、Rakeのインストールが必要です。また、リモートのマシンを操作するためにWinRMを必要とするので、その為のモジュールもインストールします。

$ gem install serverspec
$ gem install rake
$ gem install winrm

ここだけではないですが、gemによるインストールでは管理者権限のついたコンソールで実行する方が無難です。

WinRMの設定(すべてのマシン)

管理者権限付きでPowerShellのコンソールを開いて、以下の内容のスクリプトファイルを作って実行するか、一行ずつ実行させます。

#PowerShellで外部スクリプトを実行可能にする
Set-ExecutionPolicy -ExecutionPolicy "RemoteSigned" -Force
Get-ExecutionPolicy

#リモートアクセスを有効にする
Enable-PSRemoting -Force

#タイムアウト設定
Set-Item -Path "WSMan:\localhost\MaxTimeoutms" 1800000
Get-Item -Path "WSMan:\localhost\MaxTimeoutms"

#暗号化されていない接続を許可
Set-Item -Path "WSMan:\localhost\Service\AllowUnencrypted" "true"
Get-Item -Path "WSMan:\localhost\Service\AllowUnencrypted"

#Basic認証を許可
Set-Item -Path "WSMan:\localhost\Service\Auth\Basic" "true"
Get-Item -Path "WSMan:\localhost\Service\Auth\Basic"

以上で基本的なセットアップは終わりです。

serverspecの使い方

Serverspecを実行するディレクトリでserversepc-initコマンドで初期化を以下の要領で行います。

$ serverspec-init
DL is deprecated, please use Fiddle
Select OS type:

  1) UN*X
  2) Windows

Select number: 2

Select a backend type:

  1) WinRM
  2) Cmd (local)

Select number: 1

Input target host name: localhost
 + spec/
 + spec/localhost/
 + spec/localhost/sample_spec.rb
 + spec/spec_helper.rb
 + Rakefile
 + .rspec

上はリモートでlocalhostのテストを行う設定です。

作成されるディレクトリの構造です、specディレクトリ以下がテスト記述になります。specフォルダ以下にホスト毎のディレクトリが作られ、そのホスト毎のディレクトリにある*_sepc.rbというテスト記述がRakeによって実行される仕組みです。またその時、spec/spec_helper.rbが共通設定と使用され、このファイルのなかでリモートログインに必要なユーザー名、パスワードの設定を行います。

spec/spec_helper.rbの設定

自動的に作成されるファイルは以下のようになっています。

require 'serverspec'
require 'winrm'

set :backend, :winrm

user = 
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

これにユーザー名、パスワードの記述を加えますが、もう一つOS設定の記述を加えます。

require 'serverspec'
require 'winrm'

set :backend, :winrm
set :os, :family => 'windows'

user = 'hoge@localdomain'
pass = 'password'
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

5行目が追加で記述した部分です。

テスト記述

テスト記述は、specディレクトリの下のホスト名毎のディレクトリに下に、*_spec.rbという決まりで作成します。また、自動的にsample_spec.rbというファイルが作成されますが、内容的にはWindowsでは動かないですし、意味が無いので削除してしまいましょう。

Serverspecのコマンドで、Windowsに対応しているものは以下にまとめられています。

serverspec/WINDOWS_SUPPORT.md at master · serverspec/serverspec.

以下は私の作ったサンプル。

require 'spec_helper'
# ホスト名の確認
describe command('hostname') do
  its(:stdout) { should match /Akagi/ }
end
# プログラムのインストールの確認
# .with_version()により、特定のバージョンがインストールされているか確認できる
# HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstallを確認するため、ユーザー
# 毎インストールするプログラムは確認できない。当然、プログラムの追加と削除に出て来ない物も確認で
# きない
# マルチバイト文字が含まれる場合には確実にUTF-8でファイル保存する
describe package('Microsoft Office Developer Tools for Visual Studio 日本語 Language Pack') do
  it { should be_installed.with_version('12.0.31107')}
end
# サービスの確認
describe service('DNS Client') do
  it { should be_installed }
  it { should be_enabled }
  it { should be_running }
  it { should have_start_mode("Auto") }
end
# コマンド実行結果の確認
describe command('& "ipconfig"') do
  its(:stdout) { should match /IPv4 Address.*192\.168\.10\.11/ }
end

コマンド実行結果の確認は私のサンプルのやり方でやらないとエラーになるので注意してください。

テスト実行

テストのディレクトリで、rake specで実行します。

実行します。わざとプログラムのバージョンを誤った物にして、テストを失敗させています。

$ rake spec
DL is deprecated, please use Fiddle

Command "hostname"
  stdout
    should match /Akagi/

Package "Microsoft Office Developer Tools for Visual Studio 日本語 Language Pack"
  should be installed (FAILED - 1)

Service "DNS Client"
  should be installed
  should be enabled
  should be running
  should have start mode "Auto"

Command "& "ipconfig""
  stdout
    should match /IPv4 Address.*192\.168\.10\.11/

Failures:

  1) Package "Microsoft Office Developer Tools for Visual Studio 日本語 Language Pack" should be installed
     On host `localhost'
     Failure/Error: it { should be_installed.with_version('12.0.31107')}
       expected Package "Microsoft Office Developer Tools for Visual Studio 日本語 Language Pack" to be installed
       $exitCode = 1
$ProgressPreference = "SilentlyContinue"
try {
  function FindInstalledApplication
{
  param($appName, $appVersion)

  if ((Get-WmiObject win32_operatingsystem).OSArchitecture -notmatch '64')
  {
      $keys= (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*')
  }
    else
  {
      $keys = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*','HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*')
  }

  if ($appVersion -eq $null) {
    @($keys | Where-Object {$_.DisplayName -like $appName -or $_.PSChildName -like $appName}).Length -gt 0
  }
  else{
    @($keys | Where-Object {$_.DisplayName -like $appName -or $_.PSChildName -like $appName  } | Where-Object {$_.DisplayVersion -eq $appVersion} ).Length -gt 0
  }

}


  $success = ((FindInstalledApplication -appName 'Microsoft Office Developer Tools for Visual Studio 日本語 Language Pack' -appVersion '12.0.31107') -eq $true)
  if ($success -is [Boolean] -and $success) { $exitCode = 0 }
} catch {
  Write-Output $_.Exception.Message
}
Write-Output "Exiting with code: $exitCode"
exit $exitCode

       Exiting with code: 1

     # ./spec/localhost/host_spec.rb:8:in `block (2 levels) in '

Finished in 9.84 seconds (files took 0.77945 seconds to load)
7 examples, 1 failure

Failed examples:

rspec ./spec/localhost/host_spec.rb:8 # Package "Microsoft Office Developer Tools for Visual Studio 日本語 Language Pack" should be installed

C:/Ruby21-x64/bin/ruby.exe -I'C:/Users/ishisaka/.gem/ruby/2.1.0/gems/rspec-support-3.2.2/lib';'C:/Users/ishisaka/.gem/ruby/2.1.0/gems/rspec-core-3.2.1/lib' 'C:/Users/ishisaka/.gem/ruby/2.1.0/gems/rspec-core-3.2.1/exe/rspec' --pattern 'spec/localhost/*_spec.rb' failed
C:/Ruby21-x64/bin/ruby.exe -I'C:/Users/ishisaka/.gem/ruby/2.1.0/gems/rspec-support-3.2.2/lib';'C:/Users/ishisaka/.gem/ruby/2.1.0/gems/rspec-core-3.2.1/lib' 'C:/Users/ishisaka/.gem/ruby/2.1.0/gems/rspec-core-3.2.1/exe/rspec' --pattern 'spec/localhost/*_spec.rb'

以下はすべて成功した場合。

$ rake spec
DL is deprecated, please use Fiddle

Command "hostname"
  stdout
    should match /Akagi/

Package "Microsoft Office Developer Tools for Visual Studio 日本語 Language Pack"
  should be installed

Service "DNS Client"
  should be installed
  should be enabled
  should be running
  should have start mode "Auto"

Command "& "ipconfig""
  stdout
    should match /IPv4 Address.*192\.168\.10\.11/

Finished in 10.09 seconds (files took 0.74643 seconds to load)
7 examples, 0 failures

C:/Ruby21-x64/bin/ruby.exe -I'C:/Users/ishisaka/.gem/ruby/2.1.0/gems/rspec-support-3.2.2/lib';'C:/Users/ishisaka/.gem/ruby/2.1.0/gems/rspec-core-3.2.1/lib' 'C:/Users/ishisaka/.gem/ruby/2.1.0/gems/rspec-core-3.2.1/exe/rspec' --pattern 'spec/localhost/*_spec.rb'

まとめ

そんなに難しくも無く、大変シンプルで使いやすいと思います。今回触れていませんが、IIS関連での確認できることも多いです。

Powershell DSCやChef, Puppetなどと組み合わせて、Windowsシステム構築のアジリティを上げていっていただけたらと思います。

そこまで行かなくても、インストールされたソフトウェアの構成確認等Sier的な使い道でも効率を上げられると思いますので。

参考書籍

Serverspec
Serverspec 宮下 剛輔

オライリージャパン 2015-01-17
売り上げランキング : 28444

Amazonで詳しく見る by G-Tools

One thought on “WindowsでのServerspec”

コメントを残す

This site uses Akismet to reduce spam. Learn how your comment data is processed.