Windows2012R2 の Vagrant Boxイメージを作成する

Vagrant + VirtualBox で使う Windows2012R2 の Boxイメージを作成します。

## 概要

Windows2012R2 の Boxイメージの入手方法は大きく３つあります。  
  
(1) HashiCorp社 の Atlasサービス上で公開されている Boxイメージをダウンロードする  

HashiCorp社は Vagrant・Packer（あとTerraformもですね！）の開発元です。Atlasのアカウントを取れば誰でも Boxイメージを登録可能です。  
  
2017/05/16現在、"Vagrant Windwos2012R2"で Google先生に伺いを立てると『これをダウンロードすればいいじゃない』と以下の URL を教えてくださいます。

https://atlas.hashicorp.com/mwrock/boxes/Windows2012R2

この方法が一番簡単な入手方法です。ただし、インターネット上の勝手サイトで公開されているイメージはその信頼性を吟味する必要があります。

(2) 以下の工程を全て手作業で行って、Boxイメージを作る

* Microsoftのサイトから評価版のWindows2016をダウンロード
* VirtualBoxに Windows2012R2 をインストール
* Windows2016に Vagrantで使うための設定実施
* PackerでBoxイメージ化

全て手作業でイメージを作成するので、信頼性が高いイメージが作れますが、手間と知識が必要です。この方法を試す場合は以下を参考にすると良いと思います。

Creating a Base Box
https://www.vagrantup.com/docs/boxes/base.html

Windows Server 2012R2 の Vagrant Base Boxを作る
http://qiita.com/kutsushitaneko/items/4d37237808cbc165f6b0

(3) Packerテンプレートを使ってほぼ自動でBoxイメージを作る

Box-CutterというCommunityがいくつかのOSのPackerテンプレートを公開してくれています。
https://github.com/boxcutter/windows.git

Packerテンプレートを使うと、適切なOSイメージのダウンロードから、VagrantBoxとなるための前提の設定まで全自動で作業してくれます。今回はお手軽にこちらを使ってBoxイメージを作ってみましょう。

## 事前準備

Internetに接続可能なMacに Vagrant の Boxイメージを作成する環境を準備します。Macでなくても RedHatやCentOS上でもほぼ同じコマンドで作成可能です。ただし、Packerでのイメージ作成にVirtualBoxを利用しているので AWS EC2や Bluemix Infrastructure のVSIの上では動きません。

以下のソフトウェアを Macに導入してください。

* Vagrant （https://www.virtualbox.org/wiki/Downloads）
* Virtual Box （https://www.vagrantup.com/downloads.html）
* Packer （https://www.packer.io/downloads.html）

作ったBoxイメージは、同じ Vagrant + VirtualBoxの環境であれば、どこに持っていっても動きます。Macで作ったBoxイメージが、Windows上の Vagrant + VirtualBoxで動きます。便利ですね。

## Box 作成

### vagrant plugin導入

まず、Windows接続する際に必要なので、Vagrant の WinRM用のプラグインを導入します。

```shell-session
$ vagrant plugin install vagrant-winrm
Installing the 'vagrant-winrm' plugin. This can take a few minutes...
Fetching: minitar-0.6.1.gem (100%)
The `minitar` executable is no longer bundled with `minitar`. If you are
expecting this executable, make sure you also install `minitar-cli`.
Fetching: vagrant-winrm-0.7.0.gem (100%)
Installed the plugin 'vagrant-winrm (0.7.0)'!

$ vagrant plugin list
vagrant-share (1.1.8, system)
vagrant-winrm (0.7.0)
```

### Packer テンプレートファイル入手

それでは早速Boxイメージの作成を始めます。　　
適当なディレクトリに移動して、Box-Cutter の Windowsリポジトリを `git clone` します。

```shell-session
$ git clone https://github.com/boxcutter/windows.git
Cloning into 'windows'...
remote: Counting objects: 4105, done.
remote: Compressing objects: 100% (437/437), done.
remote: Total 4105 (delta 354), reused 0 (delta 0), pack-reused 3620
Receiving objects: 100% (4105/4105), 6.69 MiB | 713.00 KiB/s, done.
Resolving deltas: 100% (3327/3327), done.
```

### Packer実行

いよいよ Packerを実行します。

MSのサイトから評価版のWindows2016のISOイメージをダウンロードしたり、他にもいろんな処理をしているのでわたしの MacBookAir では 3時間かかりました。。
 
```shell-session
$ make virtualbox/eval-win2012r2-standard
rm -rf output-virtualbox-iso
mkdir -p box/virtualbox
packer build -only=virtualbox-iso -var 'cm=nocm' -var 'version=1.0.4' -var 'update=false' -var 'headless=false' -var "shutdown_command=shutdown /s /t 10 /f /d p:4:1 /c Packer_Shutdown" -var "iso_url=http://care.dlservice.microsoft.com/dl/download/6/2/A/62A76ABB-9990-4EFC-A4FE-C7D698DAEB96/9600.17050.WINBLUE_REFRESH.140317-1640_X64FRE_SERVER_EVAL_EN-US-IR3_SSS_X64FREE_EN-US_DV9.ISO" -var "iso_checksum=849734f37346385dac2c101e4aacba4626bb141c" eval-win2012r2-standard.json
virtualbox-iso output will be in this color.

==> virtualbox-iso: Downloading or copying Guest additions
    virtualbox-iso: Downloading or copying: file:///Applications/VirtualBox.app/Contents/MacOS/VBoxGuestAdditions.iso
==> virtualbox-iso: Downloading or copying ISO
    virtualbox-iso: Downloading or copying: http://care.dlservice.microsoft.com/dl/download/6/2/A/62A76ABB-9990-4EFC-A4FE-C7D698DAEB96/9600.17050.WINBLUE_REFRESH.140317-1640_X64FRE_SERVER_EVAL_EN-US-IR3_SSS_X64FREE_EN-US_DV9.ISO
    virtualbox-iso: Download progress: 0%
（中略）
==> Builds finished. The artifacts of successful builds are:
--> virtualbox-iso: 'virtualbox' provider box: box/virtualbox/eval-win2012r2-standard-nocm-1.0.4.box
```

ログ全量は以下を参照してください。
https://github.com/kentarok/openfiles/blob/master/packer_win2012r2.log

`packer`コマンドを実行したカレントディレクトリに BoxファイルができていればOKです。

```shell-session
$ ls -l box/virtualbox/eval-win2012r2-standard-nocm-1.0.4.box
-rw-r--r--  1 kentarok  staff  4270653404  5 17 11:27 box/virtualbox/eval-win2012r2-standard-nocm-1.0.4.box
```

ここまでくればBoxファイルだけ移動させて、`git clone` した `windows` ディレクトリは削除しちゃってもOKです。

## 作成したBoxイメージから仮想OSの起動

作ったBoxイメージから Windows2012R2 を起動してみましょう。

### box add

まず、お手元のMacの Vagrantに Boxイメージを `box add` します。

```shell-session
$ vagrant box add windows-2012r2 ./box/virtualbox/eval-win2012r2-standard-nocm-1.0.4.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'windows-2012r2' (v0) for provider:
    box: Unpacking necessary files from: file:///Users/kentarok/windows/box/virtualbox/eval-win2012r2-standard-nocm-1.0.4.box
==> box: Successfully added box 'windows-2012r2' (v0) for 'virtualbox'!
k-MBP13:windows kentarok$ vagrant box list
windows-2012r2 (virtualbox, 0)
k-MBP13:windows kentarok$ ls -l ~/.vagrant.d/boxes/
total 0
drwxr-xr-x  3 kentarok  staff  102  5 17 11:35 windows-2012r2
```

`vagrant box list` で表示されればOKです。
ちなみに `add` された Boxイメージは `ユーザのホームディレクトリ/.vagrant.d/boxes` 配下にコピーされています。`add`しちゃえば、その環境ではBoxイメージは不要なので削除してもOKです。

### Vagrantファイル作成

Vagrant ファイルは以下のような感じに作成します。
作成した `Vagrantfile` は `windows2012r2` とかディレクトリ作って、その下においてください。

```shell-session
$ cat Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.define "vagrant-eval-win2012r2-standard"
  #config.vm.box = "eval-win2012r2-standard"
  config.vm.box = "windows-2012r2"

  # Port forward WinRM and RDP
  config.vm.network :forwarded_port, guest: 3389, host: 3389, id: "rdp", auto_correct:false
  config.vm.communicator = "winrm"
  config.vm.guest = :windows
  config.vm.network :forwarded_port, guest: 5985, host: 5985, id: "winrm", auto_correct:true
  # Port forward SSH
  #config.vm.network :forwarded_port, guest: 22, host: 2222, id: "ssh", auto_correct:true

  config.vm.provider :virtualbox do |v, override|
    v.gui = true
    v.customize ["modifyvm", :id, "--memory", 1536]
    v.customize ["modifyvm", :id, "--cpus", 1]
    v.customize ["modifyvm", :id, "--vram", "256"]
    v.customize ["setextradata", "global", "GUI/MaxGuestResolution", "any"]
    v.customize ["setextradata", :id, "CustomVideoMode1", "1024x768x32"]
  end
end
```

### vagrant up

いよいよ Windows2012R2 を起動します。  
Vagrantfileをおいたカレントディレクトリに移動して、`vagrant up` コマンドを実行してみてください。

```shell-session
$ vagrant up
Bringing machine 'vagrant-eval-win2012r2-standard' up with 'virtualbox' provider...
==> vagrant-eval-win2012r2-standard: Importing base box 'windows-2012r2'...
==> vagrant-eval-win2012r2-standard: Matching MAC address for NAT networking...
==> vagrant-eval-win2012r2-standard: Setting the name of the VM: win2012r2_vagrant-eval-win2012r2-standard_1494989087260_17093
==> vagrant-eval-win2012r2-standard: Clearing any previously set network interfaces...
==> vagrant-eval-win2012r2-standard: Preparing network interfaces based on configuration...
    vagrant-eval-win2012r2-standard: Adapter 1: nat
==> vagrant-eval-win2012r2-standard: Forwarding ports...
    vagrant-eval-win2012r2-standard: 3389 (guest) => 3389 (host) (adapter 1)
    vagrant-eval-win2012r2-standard: 5985 (guest) => 5985 (host) (adapter 1)
    vagrant-eval-win2012r2-standard: 5986 (guest) => 55986 (host) (adapter 1)
    vagrant-eval-win2012r2-standard: 22 (guest) => 2222 (host) (adapter 1)
==> vagrant-eval-win2012r2-standard: Running 'pre-boot' VM customizations...
==> vagrant-eval-win2012r2-standard: Booting VM...
==> vagrant-eval-win2012r2-standard: Waiting for machine to boot. This may take a few minutes...
    vagrant-eval-win2012r2-standard: WinRM address: 127.0.0.1:5985
    vagrant-eval-win2012r2-standard: WinRM username: vagrant
    vagrant-eval-win2012r2-standard: WinRM execution_time_limit: PT2H
    vagrant-eval-win2012r2-standard: WinRM transport: negotiate
==> vagrant-eval-win2012r2-standard: Machine booted and ready!
==> vagrant-eval-win2012r2-standard: Checking for guest additions in VM...
==> vagrant-eval-win2012r2-standard: Mounting shared folders...
    vagrant-eval-win2012r2-standard: /vagrant => /Users/kentarok/Vagrant/win2012r2
```

Linuxと違って、Windowsは少々お時間がかかります。。が、無事起動したようです。

### 起動後の確認

RemoteDesktop Clientで以下のようなConfigを作成し、RemoteDesktop接続してください。`Vagrantfile` に記載した通り、Windowsサーバの `3389`Portへのアクセスは、localhostの `3389`Portから Forwardingされます。

![cab83775-1594-5d93-dd48-f38cd055746c.png](https://qiita-image-store.s3.amazonaws.com/0/54436/f7fb9342-e256-6556-10e0-2250a974fb7c.png)

接続できたでしょうか。  
ちなみに、ライセンス周りもばっちりでした。

<img width="572" alt="スクリーンショット 2017-05-17 11.47.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/54436/577b929d-d00a-8f81-6891-b0d16ed5a8af.png">

## 最後に

しれっと３時間待たされたりしますが、Windowsのダウンロード含めて簡単に自動でBoxイメージ作れるのは便利ですね！