Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Windows 環境で Vagrant + Chef + Serverspec を使って Windows Server マシンのテスト駆動開発を行う #GetChef_ja

More than 5 years have passed since last update.

以下の記事に影響を受け、Windows 環境上に Vagrant と Chef、Serverspec を使った Windows Server マシンのテスト駆動開発環境を作った際の手順を自分用のメモとしてまとめました。

Vagrant と Chef、Serverspec のインストールと操作は、PowerChef という PowerShell モジュールを作成しましたので、これを使います。

1: PowerChef モジュールのインストール

まず、PowerChef モジュールをローカルマシンにインストールします。

手順 1-1: 'Windows PowerShell' を起動します

ホストマシン
スタートメニューから `Windows PowerShell` を起動します

手順 1-2: PowerShellスクリプトの実行セキュリティ・ポリシーを RemoteSigned に変更します

ホストマシン
PS> Set-ExecutionPolicy RemoteSigned
PS> Get-ExecutionPolicy

RemoteSigned

→ RemoteSigned と表示されることを確かめます。

手順 1-3: インストールスクリプト(install.ps1)を使って、GitHub上からモジュールをダウンロードします

ホストマシン
PS> Invoke-Expression (New-Object System.Net.WebClient).DownloadString("https://raw.github.com/kukita/PowerChef/master/install.ps1")

Installation of 'PowerChef' has finished successfully. と表示されればインストールの成功です。

2: ホストマシン環境のセットアップ

次に、ローカルマシンをホストマシン環境としてセットアップします。

手順 2-1: PowerChef モジュールをインポートします

ホストマシン
PS> Import-Module "PowerChef"
PS> Get-Module
ModuleType Version    Name
---------- -------    ----
Manifest   3.1.0.0    Microsoft.PowerShell.Management
Manifest   3.1.0.0    Microsoft.PowerShell.Utility
Manifest   0.5.2      PowerChef

PowerChef が表示されていることを確かめます。

手順 2-2: SetUp-ChefWorkstation ファンクションを使って、ローカルマシンを WorkStation 環境としてセットアップします

ホストマシン
PS> SetUp-ChefWorkstation -PowerChefHomePath "D:\PowerChef"
※30分くらいかかります。最後に WinRM のセキュリティ設定に関して聞かれるので [Y]Yes を選択します。

次のソフトウェアがインストールされます。

手順 2-3: Open-HomeVagrantfile ファンクションを使って、Vagrant ホームディレクトリの Vagrantfile を編集します

ホストマシン
PS> Open-HomeVagrantfile

→ 仮想化支援機能の有無等ホストマシンのスペックに合わせてファイルを編集しファイルを閉じます。

3: Windows Server 2012 R2 の Box を作成する

Vagrant 上で動作する Windows Server の Box を作成します。

手順 3-1: 'Oracle VM VirtualBox' を起動します

ホストマシン
スタートメニューから 'Oracle VM VirtualBox' を起動します

手順 3-2: Show-VeeweeDefinitionVboxList ファンクションを使って、Bento(Veewee)で定義済みの OS の一覧を表示します

ホストマシン
PS> Show-VeeweeDefinitionVboxList
windows-2008r2-standard
windows-2012-standard
windows-2012r2-standard
windows-7-enterprise
windows-8-enterprise

手順 3-3: Invoke-VeeweeVboxBuild ファンクションを使って、Bento(Veewee)を実行し仮想マシン(VirtualBox のゲストOS)を作製します

ホストマシン
PS> Invoke-VeeweeVboxBuild "windows-2012r2-standard"

→ コンソール画面が立ち上がり Windows のインストールがはじまれば成功です。

※ISOイメージのダウンロードで失敗する場合は、手動でダウンロードを行った後、仮想マシンを削除してから再度コマンドを実行してください。

手順 3-4: New-VagrantBox ファンクションを使って、作成した VirtualBox のゲスト OS をベースに Vagrant の Box を作製します

ホストマシン
PS> New-VagrantBox "windows-2012r2-standard"
PS> & vagrant box list

windows-2012r2-standard               (virtualbox, 0)

windows-2012r2-standard が表示されれば成功です。このファンクションは任意のゲストOSをBox化することができます。必要がなければ、ベースとして作成した仮想マシンは削除してください。

4: 仮想マシン(VirtualBox のゲスト OS)を作成する

開発/テスト対象となる仮想マシンを作成します。

手順 4-1: New-ChefRepo ファンクションを使って、"SampleRepo" という名前のリポジトリを作成します

ホストマシン
PS> New-ChefRepo "SampleRepo"
PS> Show-ChefRepoList

Name        CreationTime        LastWriteTime       LastAccessTime
----        ------------        --------------      -------------
SampleRepo  2014/XX/XX XX:XX:XX 2014/XX/XX XX:XX:XX 2014/XX/XX XX:XX:XX

SampleRepo が表示されることを確かめます。

手順 4-2: Get-ChefRepoPath ファンクションを使って、作成した chef-repo のパスを取得しカレントディレクトリを移動します

ホストマシン
PS> Get-ChefRepoPath "SampleRepo" | Set-Location
PS> pwd

Path
----
D:\PowerChef\chef-repositories\SampleRepo\chef-repo

D:\PowerChef\chef-repositories\SampleRepo\chef-repo と表示されることを確かめます。

手順 4-3: New-ChefNode ファンクションを使って、Vagrantfileを作成します

ホストマシン
PS> New-ChefNode -BoxName "windows-2012r2-standard" -OSType "Windows" -VMNumber 10
PS> Show-ChefNodeList

D:\PowerChef\chef-repositories\SampleRepo\chef-repo> Show-ChefNodeList

Name             Parent      CreationTime        LastWriteTime       LastAccessTime
----             ------      ------------        -------------       --------------
ip-192-168-56-10 development 2014/XX/XX XX:XX:XX 2014/XX/XX XX:XX:XX 2014/XX/XX XX:XX:XX

ip-192-168-56-10 という名前の仮想マシンが作成されたことを確かめます。

手順 4-4: Create-ChefNode ファンクションを使って、仮想マシン(VirtualBox のゲスト OS)を作成します

ホストマシン
PS> Create-ChefNode "ip-192-168-56-10"
PS> Show-ChefNodeStatus "ip-192-168-56-10"

Current machine states:

ip-192-168-56-10          running (virtualbox)

The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.

→ 状態が running と表示されていることを確かめます。

5: 仮想マシン(VirtualBox のゲスト OS)のテストを行う

手順 5-1: Open-ChefNodeSpecfile ファンクションを使って、Serverspec の Spec ファイル(default_spec.rb)を編集します

ホストマシン
PS> Open-ChefNodeSpecfile "ip-192-168-56-10"

Testing for files. の部分に 3 行追記します。

default_spec.rb
require 'serverspec'
require 'winrm'

include Serverspec::Helper::WinRM
include Serverspec::Helper::Windows

RSpec.configure do |c|
  user = 'vagrant'
  password = ask("Enter password: ") { |q| q.echo = false }
  endpoint = 'http://192.168.56.10:5985/wsman'

  c.winrm = ::WinRM::WinRMWebService.new(endpoint, :ssl, :user => user, :pass => password, :basic_auth_only => true)
  c.winrm.set_timeout 300 # 5 minutes max timeout for any operation
end

# # Testing for user groups.
# describe group('xxxxxx') do
#   it { should exist }
# end

# # Testing for users.
# describe user('xxxxxx') do
#   it { should exist }
#   it { should belong_to_group 'xxxxxx' }
#   it { should_not belong_to_group 'xxxxxx' }
# end

# # Testing for directories.
# describe file('C:\xxxxxx\xxxxxx') do
#   it { should be_directory }
# end

# # Testing for files.
# describe file('C:\xxxxxx\xxxxxx') do
#   it { should be_file }
#   it { should contain /^xxxxxx/ }
#   it { should be_readable.by('owner') }
#   it { should be_readable.by_user('xxxxxx') }
#   it { should_not be_readable.by('others') }
#   it { should_not be_readable.by_user('xxxxxx') }
#   it { should be_writable.by('owner') }
#   it { should be_writable.by_user('xxxxxx') }
#   it { should_not be_writable.by('others') }
#   it { should_not be_writable.by_user('xxxxxx') }
#   it { should be_executable.by('owner') }
#   it { should be_executable.by_user('xxxxxx') }
#   it { should_not be_executable.by('others') }
#   it { should_not be_executable.by_user('xxxxxx') }
# end
describe file('C:/test.txt') do
  it { should be_file }
end

# # Testing for enabled services.
# describe service('xxxxxx') do
#   it { should be_enabled }
#   it { should be_running }
# end

# # Testing for disabled services.
# describe service('xxxxxx') do
#   it { should_not be_enabled }
#   it { should_not be_running }
# end

# # Testing for open ports.
# describe port(port_number) do
#   it { should be_listening.with('tcp') }
#   it { should be_listening.with('udp') }Pow
# end

# # Testing for close ports.
# describe port(port_number) do
#   it { should_not be_listening }
# end

# # Testing for command returns.
# describe command('xxxxxx') do
#   it { should return_stdout /^xxxxxx/ }
#   it { should return_exit_status 0 }
# end

手順 5-2: Test-ChefNode ファンクションを使って、Serverspec を実行します

ホストマシン
PS> Test-ChefNode "ip-192-168-56-10"

 :
中略
 :
1 example, 1 failure

Failed examples:

→ テストに失敗することを確かめます。

6: Chef のレシピを作成して仮想マシン(VirtualBox のゲスト OS)に適用します

手順 6-1: New-Cookbook ファンクションを使って、"make-testfile" という名前のクックブックを作成します

ホストマシン
PS> New-Cookbook "make-testfile"

Maintainer: xxxxxxx xxxxxx ←作成者(メンテナー)の名前を入力します。
MainteinerEmail: xxxxxxxx@xxxxxx.xx ←作成者(メンテナー)のメールアドレスを入力します。

PS> Show-CookbookList

Name          Parent         CreationTime        LastWriteTime       LastAccessTime
----          ------         ------------        --------------      -------------
make-testfile site-cookbooks 2014/XX/XX XX:XX:XX 2014/XX/XX XX:XX:XX 2014/XX/XX XX:XX:XX

手順 6-2: Open-CookbookRecipe ファンクションを使って、クックブックのデフォルトレシピ(default.rb)を編集します

ホストマシン
PS> Open-CookbookRecipe "make-testfile"

次のように編集してファイルを閉じます。

default.rb
file "C:/test.txt" do
  action :create
end

手順 6-3: Start-ChefZero ファンクションを使って、ローカルマシン上にChef Zero(インメモリー版軽量 Chef Server)を起動します。

ホストマシン
PS> Start-ChefZero
PS> & NETSTAT.EXE -anb | Select-String "8889"

→ ポート 8889 番の状態が LISTENING であることを確かめます。

手順 6-4: New-ChefZeroACL ファンクションを使って、Windows ファイアウォールの設定を行います(Windows 8、Windows Server 2012 以降の環境のみ)

PS> New-ChefZeroACL

手順 6-5: Update-Cookbook ファンクションを使って、依存関係のあるクックブックをダウンロードし Chef Zero にアップロードします

PS> Update-Cookbook "make-testfile"
PS> & knife cookbook list

→ クックブックの一覧が表示されれば成功です。

手順 6-6: SetUp-ChefNode ファンクションを使って、作成した仮想マシンを Chef の Node 環境としてセットアップします

ホストマシン
PS> SetUp-ChefNode "ip-192-168-56-10"

→ パスワード欄に vagrant と入力し [OK] ボタンをクリックします。

手順 6-7: knife コマンドを使って、Chef Zero サーバー上に Node として登録されたことを確認します

ホストマシン
PS> & knife node list

ip-192-168-56-10

ip-192-168-56-10 が表示されれば成功です。

手順 6-8: knife コマンドを使って run_list に作成したクックブックを追加します

ホストマシン
PS> & knife node run_list add "ip-192-168-56-10" "make-testfile::default"
PS> & knife node show "ip-192-168-56-10"

手順 6-9: Environment の設定ファイル development.json を作成します

ホストマシン
PS> New-Item -Path ".\environments\development.json" -ItemType "File" -Value @'
{
  "name": "development",
  "json_class": "Chef::Environment",
  "chef_type": "environment",
  "default_attributes": {
  }
}
'@

手順 6-10: knife コマンドを使って、 Environment を設定します

ホストマシン
PS> & knife environment create from file ".\environments\development.json"

手順 6-11: Converge-ChefNode ファンクションを使って、クックブックを仮想マシンに適用します(仮想マシン上で chef-client を実行します)

ホストマシン
PS> Converge-ChefNode "ip-192-168-56-10"

7: 仮想マシン(VirtualBox のゲスト OS)の再テストを行う

手順 7-1: Test-ChefNode ファンクションを使って、Serverspec を実行します

ホストマシン
PS> Test-ChefNode "ip-192-168-56-10"

 :
中略
 :
1 example, 0 failures

→ テストが通ったことを確認します。


Vagrant + Chef + Serverspec を使って、Windows Server 環境も Infrastructure as Code & TDD してしまうという話でした。

今回、使用した PowerShell のモジュール PowerChef の詳しい使い方については、以下を参照してください。

以上

kukita
某FinTech関連事業会社にて Ops サイドの統括責任社として24時間365日稼働しているサービスの SRE(Site Reliability Engineering) や DevOps の推進に従事しています。 ※各記事の内容は個人の見解であり、所属する組織の公式見解ではありません。
https://jp.linkedin.com/in/kukita
nssol
お堅いと評判のユーザ系SIerです。※各記事の内容は個人の見解であり、所属する組織の公式見解ではありません。
https://www.nssol.nipponsteel.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away