terraform で 各 Iaas の仮想インスタンスを作成 (Microsoft Azure)

# 概要
terraform で各 IaaS ベンダーの仮想マシンを作成する

今回は Microsoft Azure のベースとなる tf ファイルを作成

対象ベンダー
- Microsoft Azure
- Google Cloud
- DigitalOsean
- CloudStack

※AWSは今更なので割愛


#事前準備
- Microsoftアカウント取得
- 以下にアクセスして publish settings file をダウンロード  
https://manage.windowsazure.com/publishsettings  
- ダウンロードしたファイル名を credentials.publishsettings に変更して tf ファイルの場所に保存

#手順
tf ファイルを作成

```:provider.tf
provider "azure" {
  publish_settings = "${file("credentials.publishsettings")}"
}
```

```:hosted_service.tf
resource "azure_hosted_service" "default" {
    name = "${var.hosted_service_name}"
    location = "${var.location}"
    ephemeral_contents = false
}
```

```:virtual_network.tf
resource "azure_virtual_network" "default" {
  name = "${var.virtual_network_name}"
  address_space = ["${var.virtual_network_address}"]
  location = "${var.location}"

  subnet {
    name = "public"
    address_prefix = "${var.public_address}"
  }
  subnet {
    name = "private"
    address_prefix = "${var.private_address}"
  }
}
```

```:storage_service.tf
resource "azure_storage_service" "default" {
  name = "${var.storage_service_name}"
  location = "${var.location}"
  account_type = "${var.storage_service_account_type}"
}
```

```:instance.tf
resource "azure_instance" "default" {
  hosted_service_name = "${azure_hosted_service.default.name}"
  storage_service_name = "${azure_storage_service.default.name}"
  name = "${var.instance_name}"
  image = "${var.image}"
  size = "${var.size}"
  location = "${var.location}"
  virtual_network = "${azure_virtual_network.default.name}"
  subnet = "${var.subnet}"
  username = "${var.username}"
  password = "${var.password}"
  security_group = "${azure_security_group.public.name}"

  endpoint {
    name = "SSH"
    protocol = "tcp"
    public_port = 22
    private_port = 22
  }
}
```

```:security_group.tf
resource "azure_security_group" "public" {
  name = "public"
  location = "${var.location}"
}

resource "azure_security_group" "private" {
  name = "private"
  location = "${var.location}"
}

resource "azure_security_group_rule" "public_ssh" {
  name = "public_ssh"
  security_group_names = ["${azure_security_group.public.name}"]
  type = "Inbound"
  action = "Allow"
  priority = 100
  source_address_prefix = "${var.ssh_source_address}"
  source_port_range = "*"
  destination_address_prefix = "${var.public_address}"
  destination_port_range = "22"
  protocol = "TCP"
}

resource "azure_security_group_rule" "private_ssh" {
  name = "private_ssh"
  security_group_names = ["${azure_security_group.private.name}"]
  type = "Inbound"
  action = "Allow"
  priority = 100
  source_address_prefix = "${var.public_address}"
  source_port_range = "*"
  destination_address_prefix = "${var.private_address}"
  destination_port_range = "22"
  protocol = "TCP"
}
```

```:output.tf
output "azure_instance_pip_address" {
  value = "${azure_instance.default.ip_address}"
}

output "azure_instance_vip_address" {
  value = "${azure_instance.default.vip_address}"
}
```

```:variables.tf
variable "location" {
  default = "Japan West"
}
variable hosted_service_name {}
variable instance_name {}
variable image {}
variable size {}
variable username {}
variable password {}
variable storage_service_name {}
variable storage_service_account_type {
  default = "Standard_LRS"
}
variable virtual_network_name {}
variable virtual_network_address {
  default = "10.0.0.0/16"
}
variable "public_address" {
  default = "10.0.1.0/24"
}
variable "private_address" {
  default = "10.0.2.0/24"
}
variable subnet {
  default = "public"
}
variable ssh_source_address {}
```

tfvars は以下の通り

```:terraform.tfvars
## hosted service
hosted_service_name = "*****"

## instance
instance_name = "*****"
image = "Ubuntu Server 14.04 LTS"
size = "Basic_A0"
username = "*****"
password = "**********"

## storage service
storage_service_name =  "*****"

## virtual network
virtual_network_name = "*****"

## ssh source address
ssh_source_address = "***.***.***.***/**"
```

#結果
```
$ terraform apply

Outputs:
...snip...
  azure_instance_pip_address = 10.0.1.4
  azure_instance_vip_address = ***.***.***.***
```
azure_instance_vip_address に表示されたIPにSSH接続できればOK
SSHユーザー、パスワードは tfvars に記載した内容


**作成されたリソース**
```
$ terraform graph | dot -Tpng > graph.png
```
![graph.png](https://qiita-image-store.s3.amazonaws.com/0/105824/2b1231ba-33c4-e4a0-68a2-35d944e542b8.png)



# その他
terraform 0.6.8 では、データディスク作成でエラーとなる
https://github.com/hashicorp/terraform/issues/3428

```:data_disk.tf
variable data_disk_size {}
resource "azure_data_disk" "default" {
  lun = "0"
  size = "${var.data_disk_size}"
  storage_service_name = "${azure_storage_service.default.name}"
  virtual_machine = "${azure_instance.default.id}"
}
```

```
$ terraform apply
...snip...
Error applying plan:

1 error(s) occurred:

* azure_data_disk.default: Error adding data disk 0 to instance **********: Error response from Azure. Code: ResourceNotFound, Message: The deployment name '**********' does not exist.
```