概要

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

その他

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.