a2 Tech blog

試したこと・調べたこと・感じたことを発信するITエンジニアの日記です。仕事とは直接関係ないけど興味あることを模索していきます。

WindowsでServerspecを試すwithAzure

Windowsプラットフォームでインフラテストフレームワークの、Serverspecを試す必要があったので、Azure上に検証用環境を作ってみました。こういう時にクラウドは便利です。必要な時に必要な環境がサクッと作れますので。

Serverspecの開発者の著書を参考に作業しました。

Serverspec

Serverspec

テスト実行クライアントとテスト対象サーバの構築

開発用やテスト用の環境を素早くプロビジョニングするためにDevTest LabsというAzureの機能を使って構築しています。どんなものかはMicrosoftの公式を読んでください。10分ぐらいでネットワークまで含めてVMの構築を簡単に行えます。

azure.microsoft.com

今回は、テスト実行クライアントには「Windows 10 Enterprise」、テスト対象サーバには「Windwos Server 2012 R2 Datacenter」を選択しています。特にこれでないといけないというのはないので好きなもので良いと思います。検証の目的がWindowsでの実施なので、両方Windwosをプラットフォームを選択しています。

このようにVMが2つ構築されればOKです。

f:id:ninna2:20170629225600p:plain

TestClientが、テスト実行クライアントで、内部IP 10.0.0.4、テスト対象のサーバがTestServer01で、内部IP 10.0.0.5となってます。

f:id:ninna2:20170629232756p:plain

テスト実行クライアントのセットアップ

テスト実行クライアントのセットアップを行います。インフラテストフレームワークであるServerspecはRubyで作られてますので、Rubyのインストールから行なっていきます。ちなみに私はRubyは全然詳しくないです。詳しくなくてもある程度簡単に使えるのがServerspecの良い点であるのかなと思います。

WindowsでのRubyインストールは、「rubyinstaller」を使うのが無難だと思います。現時点(2017/6/25)では、2.4.1が最新版となってます。

rubyinstaller.org

ダウンロードしてインストーラを起動して、進めていけば導入は完了です。

Rubyがインストールできたら、早速、Serverspecのインストールを行います。Rubyではパッケージ管理をgemで行います。ですので、gemコマンドを実行するだけで導入できます。ちなみに、Serverspecでは、rakeとwinrmパッケージも使っているので、合わせて入れておきます。コマンドプロンプトでもPowerShellでもどちらも構わないので、管理者権限で実行した上で、下記のコマンドを実行します。

> gem install serverspec
> gem install rake
> gem install winrm

Serverspecでは、Windwos環境のテストを行うためにはWindowsリモート管理(WinRM)を使用して接続するのが一般的なようです。Windows + OpenSSHでも良いような気はしますが、今回は普通にWinRM使います。WinRMを使用できるように設定を行います。

PowerShellを管理者モードで起動して、下記のコマンドを実行します。

> Set-Item WSMan:\localhost\Client\TrustedHosts -Value *

PowerShellによるリモート操作も合わせて許可しておきます。

> Enable-PSRemoting -SkipNetworkProfileCheck

ネットワーク設定がパブリックだと、エラーになるのでネットワーク設定をプライベートに変更するか、上記のようにネットワーク設定のスキップ(-SkipNetworkProfileCheck)パラメーターを指定して有効化します。

これで、Serverspecを実行するクライアントのセットアップは完了です。

ローカルテストが出来るか試してみる

まずはローカル(自分自身)をテスト対象としてテスト出来るかやってみます。

作業ディレクトリを作成します。この辺は各自の好みでやってもらって構いません。私はC:¥serverspec¥localを作業ディレクトリにしました。

> mkdir C:¥Serverspec
> cd C:¥Serverspec
> mkdir local
> cd local

ServerSpec-initコマンドで初期化します。Select OS typeはWindows(2)、Select a backend typeはcmd(2)を選択します。これで、テンプートができます。

PS C:\Serverspec\local>serverspec-init
Select OS type:

  1) UN*X
  2) Windows

Select number: 2

Select a backend type:

  1) WinRM
  2) Cmd (local)

Select number: 2

 + spec/
 + spec/localhost/
 + spec/localhost/sample_spec.rb
 + spec/spec_helper.rb
 + Rakefile
 + .rspec

テストスクリプト(spec/localhost/sample_spec.rb)を、Windowsを対象にテストする場合は、初期テンプレートが役に立たないので書き換えます。とりあえず、動作確認程度なので、C:¥windowsフォルダの存在確認ぐらいの簡単なものにしてます。

require 'spec_helper'

describe file('C:\Windows') do
  it { should be_directory }
end

書き換えたら、実行します。実行は、Rakefileが存在するところで実行です。

PS C:\Serverspec\local> rake spec
C:/Ruby24-x64/bin/ruby.exe -I'C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/rspec-support-3.6.0/lib';'C:/Ruby24-x64/lib/ruby/ge
ms/2.4.0/gems/rspec-core-3.6.0/lib' 'C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/exe/rspec' --pattern 'spec/
localhost/*_spec.rb'

File "C:\Windows"
  should be directory

Finished in 0.48437 seconds (files took 3.5 seconds to load)
1 example, 0 failures

結果が返ってくればOKです。

テスト対象サーバのセットアップ

リモート環境をテストするために、テスト対象サーバの設定をしていきます。テスト対象サーバでは、WinRMの接続ができるように設定するだけです。Agentなどが不要なのがServerspecの良いところです。

テスト実行クライアントで設定した内容と同じような設定を入れてます。PowerShellを管理者モードで起動して、下記のコマンドを実行します。

> Set-Item WSMan:\localhost\Client\TrustedHosts -Value *

PowerShellによるリモート操作も合わせて許可しておきます。

> Enable-PSRemoting

これだけでOKです。

念のため、テスト実行クライアントからWinRMで繋がるかどうかをテストしておきましょう。認証ダイアログが出るので、パスワードを入力するとつながるはずです。

PS C:\> Enter-PSSession -ComputerName 10.0.0.5 -Credential Azureuser

リモートへのテストの実行

リモート接続してテストするServerspecのテストコードを作っていきましょう。テスト実行クライアントで作業します。

作業ディレクトリを作成します。C:¥serverspec¥remoteとしてます。

> cd C:¥serverspec
> mkdir remote
> cd remote

serverspec-initコマンドで初期化します。Select OS typeはWindows(2)、Select a backend typeは先ほどは2でしたが今度はWinRM(1)を選択します。あと、サーバ名を聞いてくるので、テスト対象サーバTestServer01を指定します。これで、リモート用のテンプートができます。

PS C:\Serverspec\remote> 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

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

テストスクリプト(spec/remote/sample_spec.rb)を作成します。今回はTestというディレクトリを作ってそれが存在するかどうかのテストにしています。テスト対象サーバにつながっていることがちゃんとわかるようにしておきたかったからです。

require 'spec_helper'

describe file('C:\Test') do
  it { should be_directory }
end

次に、spec/spec_helper.rbを変更します。serverspec-initコマンドで生成されるスクリプトは、winrmパッケージの進化に追いついていないらしく上手く動きません。ですので、書き換えます。

下記を参考にさせてもらいました。

qiita.com

WinRM::WinRMWebServiceは使えないようなのでWinRM::Connectionを使うように修正すれば良いみたいです。

require 'serverspec'
require 'winrm'

set :backend, :winrm

opts = {
  user: "usrname",
  password: "passwd",
  endpoint: "http://#{ENV['TARGET_HOST']}:5985/wsman",
  operation_timeout: 300,
}

winrm = WinRM::Connection.new(opts)
Specinfra.configuration.winrm = winrm

ユーザー名、パスワードは適時環境に合わせてください。さて、実行してみます。Rakefileが存在するディレクトリでの実行です。

PS C:\Serverspec\remote> rake spec
C:/Ruby24-x64/bin/ruby.exe -I'C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/rspec-support-3.6.0/lib';'C:/Ruby24-x64/lib/ruby/ge
ms/2.4.0/gems/rspec-core-3.6.0/lib' 'C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/rspec-core-3.6.0/exe/rspec' --pattern 'spec/
TestServer01/*_spec.rb'

File "C:\Test"
  should be directory

Finished in 3.16 seconds (files took 2.08 seconds to load)
1 example, 0 failures

これで、すごく簡単なテストスクリプトだけどWindowsでServerpecを実行することができました。Agentlessな点が良いですね。外部から接続できないといけないのですが、そこだけクリアできれば、インフラテストは簡単にスクリプト化できそうです。複数のサーバに対して実行していくことや、CI/CDへの組み込みあたりをもう少し真面目に考えていく必要があるのかなと思っていますので、その辺りはまたブログに書きたいと思います。