terraform by HashiCorp * VMware vsphere ESXi5.5 で VM を自動生成

# terraform by HashiCorp * VMware vsphere ESXi5.5 で VM を自動生成
## 0．はじめに
大好きな[HashiCorp社](https://www.hashicorp.com/)の[terraform](https://www.terraform.io/)をつかって On-Premises の VMware ESXi5.5上でVMの自動生成を素振りしてみました。
同社のVagrantでもvsphere-pluginを利用すれば同様なことができるのですが
Gitで管理する際にterraformの方がVM構成をコードとしてより綺麗に残せる印象です。
対応プロバイダが多いので、試していませんがハイブリッドクラウドの分野などでも効果を発揮できるのではと思います。

後述しますAPI SDK呼出時のx509認証エラー以外は特に詰まるところもなく実施できました。
検証環境等でのデモ、素振り用などの参考にして頂ければと思います。
![terraform_vcenter.png](https://qiita-image-store.s3.amazonaws.com/0/117986/26e030c4-5175-1b1e-e409-22020addd9fd.png)

なお、terraformはインストールされている前提です。
基本的なインストール方法としては、以下で
1. [こちら](https://www.terraform.io/downloads.html)からインストール先に対応したファイルをダウンロード
2. ダウンロードファイルをunzipして、バイナリファイル（terraform）をパスの通ったディレクトリ（/usr/bin/など）に置く
3. `terrafrom --help`とコマンド入力してterraformのヘルプが表示されればOKです。

インストール方法やコマンドの使い方の詳細については以下公式サイトのドキュメントを参照頂ければと思います。
https://www.terraform.io/intro/getting-started/install.html

## 1.環境
- CentOS Linux release 7.2.1511 (Core)
- Terraform v0.7.7
- VMware vsphere ESXi5.5
- VMware vCenter Server 5.5 

## 2.コード
teraform公式サイトのドキュメントを参考にして作成しました。
https://www.terraform.io/docs/providers/vsphere/

なお、GuestVM単位でGit上でコード管理をしたかったのと
terraformの仕様上、コマンド実行時に、カレントディレクトリ内の*.tfをファイルを自動で読み込んでくれるみたいなので

今回は、以下の単位で.tfファイルを分割しています。
 - vCenterの接続情報を記述`vsphere.tf`
 - GuestVMの情報を記述した`vmname01.tf`,`vmname02.tf`

## 2.1.vCenterの接続情報
接続するvCenterの接続情報を設定します。
なお、`terrafrom plan`実行時にx509エラーが出る場合はワークアラウンドとして
`allow_unverified_ssl  = true`を設定すること回避でました。
エラーについては後述します。
また、user名とpasswordについてはセキュリティ上の考慮が必要だと思います。
恐らく同社のvaultが使えるのではと思いますが調べきれていません。

変数についてはお使いの環境に合わせて適宜変更してください。

``` variables.tf
//-------------------------------------------------------------------
// VMware vsphere vCenter settings
//-------------------------------------------------------------------

variable "vsphere_user" {
    default = "root"
}

variable "vsphere_password" {
    default = "yourpassword"
}

variable "vsphere_server" {
    default = "192.168.33.100"
}
```

``` vsphere.tf
# Configure the VMware vSphere Provider
provider "vsphere" {
    user           = "${var.vsphere_user}"
    password       = "${var.vsphere_password}"
    vsphere_server = "${var.vsphere_server}"
    allow_unverified_ssl  = true
}
```

## 2.2.GuestVMの情報
GuestVM単位で.tfを作成していますが、１つの.tfファイルにまとめて記載しても大丈夫です。
なお、IPaddressなどお使いの環境に合わせて適宜変更してください。

``` vmname01.tf
resource "vsphere_virtual_machine" "vmname01" {

  datacenter             = "DataCenter01"
  name                   = "vmname01"
  vcpu                   = 2
  memory                 = 2048

  disk {
      datastore          = "datastorename"
      template           = "tmplatename"
      type               = "thin"
  }

  dns_servers            = ["8.8.8.8","8.8.4.4"]

  network_interface {
      label              = "VM Network"
      ipv4_gateway       = "192.168.33.1"
      ipv4_address       = "192.168.33.101"
      ipv4_prefix_length = 24
  }
}
```

``` vmname02.tf
resource "vsphere_virtual_machine" "vmname02" {

  datacenter             = "DataCenter01"
  name                   = "vmname02"
  vcpu                   = 2
  memory                 = 2048

  disk {
      datastore          = "datastorename"
      template           = "tmplatename"
      type               = "thin"
  }

  dns_servers            = ["8.8.8.8","8.8.4.4"]

  network_interface {
      label              = "VM Network"
      ipv4_gateway       = "192.168.33.1"
      ipv4_address       = "192.168.33.102"
      ipv4_prefix_length = 24
  }
}
```

## 実行コマンド例
以下コマンド例です。
.tfファイルのあるディレクトリ上で実施します。

```
#計画作成
terraform plan
#VM作成
terraform apply
#VM削除
terraform destory
```

## 4．Tips.
### 4.1.ハマりどころ
ちなみに自環境では、`terraform plan`実行時に
API SDK呼出部分で x509 認証エラーでハマりましたが
ワークアラウンドとしてvCenterの設定を記述しているvsphere.tfへ
以下を加えることで解消しました。

`allow_unverified_ssl  = true`

``` x509_error.msg
# terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.

Error refreshing state: 1 error(s) occurred:

* Error setting up client: Post https://192.168.33.100/sdk: x509: certificate is valid for xxx.xxx.xxx.xxx, fe80::20c:29ff:fe28:1c47, not 192.168.33.100
```
### 4.2.VMwareカスタマイズ仕様とWindows VMについて
テンプレート等からのVMクローン時にホスト名やIPアドレスなどを変更できる
VMwareカスタマイズ仕様についてVagrantのvsphere-pluginでは指定できたのですが、
terraformでは、設定を見つけることができませんでした。

custom_configuration_parametersを駆使すれば設定できそうではあるのですが、うまくいきませんでした。
ただしWindows関連のオプションとして以下も用意されており、
VM作成毎に新規に**SID**が振られているようなので、カスタマイズ仕様が使えなくても何とかなる印象です。

```
The windows_opt_config block supports:
product_key - (Optional) Serial number for new installation of Windows. This serial number is ignored if the original guest operating system was installed using a volume-licensed CD.
admin_password - (Optional) The password for the new administrator account. Omit for passwordless admin (using "" does not work).
domain - (Optional) Domain that the new machine will be placed into. If domain, domain_user, and domain_user_password are not all set, all three will be ignored.
domain_user - (Optional) User that is a member of the specified domain.
domain_user_password - (Optional) Password for domain user, in plain text.
```

## 5.その他
以下試してみた感想です。
Vagrantと同様にCLIで操作可能なので、以下OSSツール等を連携させると
VM作成からプロビジョニング、テストまで一連の処理を自動化可能です。
[Chat(Mattermost) * Jenkins](http://qiita.com/tbuchi888/items/fa02a10728999520e1a0#_reference-d460a84a757739de0e7f) * GitLab * Digdag * terrform/Ansible/ServerSpec 

以上