浅草橋青空市場

Microsoft Azure のニュースや情報を中心にあれこれと

TerraformでAzure仮想マシンを作成する(Managed Disks編)

Terraformを使って、Managed Disksの付いた仮想マシンを作る簡単な手順です。 UnManaged Disksの場合はこちらの記事をどうぞ。

バーチャルマシンを ARM対応の Terraform を使ってプロビジョンしてみる - Qiita

ではさっそく。

Terraformのダウンロード

公式サイトから自分の環境用のバイナリを取得してパスの通った場所に置いて下さい。バイナリ1つで動作するのでセットアップの手間いらずでとても楽ですね。

Download Terraform - Terraform by HashiCorp

サービスプリンシパルの作成

Terraformを実行するためのアカウントのようなものですね。 CLI2.0で作るのが簡単なので、ポータルのAzure Cloud Shell から実行しましょう。 サブスクリプションが1つの環境であれば1行目は無くても大丈夫です。

az account set --subscription "[サブスクリプションID]"
az ad sp create-for-rbac --name "[アプリケーション名]" --role Contributor

2行目を実行したあとのレスポンスが大切です。以下の3項目はあとで使います。特に「password」はあとから参照できませんのでしっかり記録しておきましょう(パスワードリセットは可能です)。

  • appId
  • password
  • tenant

サービスプリンシパルそのものについての説明はこちらへどうぞ。

AzureのサービスプリンシパルをCLI2.0から発行する - 浅草橋青空市場

Terraformの設定ファイルを書く

ここからが本番です。「.tf」という拡張子のファイルにどんどん書いていきます。
サービスプリンシパルやOSアカウントなどの認証情報は「.tfvars」に外出しして .gitignore に入れておくのが良いでしょう。.tfvars のデフォルトは「terraform.tfvars」です。これ以外のファイル名の場合は、terraformコマンド実行時にオプションで明示的に指定する必要があります。

ではまず.tfvarsの書式から。

default_user = "OSユーザー名"
default_password = "OSパスワード"
subscription_id = "AzureのサブスクリプションID"
client_id       = "AzureのサービスプリンシパルのクライアントID(appId)"
client_secret   = "Azureのサービスプリンシパルのパスワード(password)"
tenant_id       = "AzureのサービスプリンシパルのテナントID(tenant)"

続いて.tfのコード例。
Azure側で用意されているUbuntu16.04LTSの最新版から、データディスク付きのVMを作ります。 ストレージはもちろんManaged Disks。
ほぼ公式のサンプルを踏襲していますので、IPアドレスにタグが付いていたりしますのでお好みで。

variable "default_user" {}
variable "default_password" {}
variable "subscription_id" {}
variable "client_id" {}
variable "client_secret" {}
variable "tenant_id" {}

provider "azurerm" {
  subscription_id = "${var.subscription_id}"
  client_id       = "${var.client_id}"
  client_secret   = "${var.client_secret}"
  tenant_id       = "${var.tenant_id}"
}

resource "azurerm_resource_group" "test" {
  name = "harayTerraformDemo"
  location = "Japan East"
}

resource "azurerm_virtual_network" "test" {
  name = "tfvnet1"
  address_space = ["10.0.0.0/16"]
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
}

resource "azurerm_subnet" "test" {
  name = "tfsubnet1"
  resource_group_name = "${azurerm_resource_group.test.name}"
  virtual_network_name = "${azurerm_virtual_network.test.name}"
  address_prefix = "10.0.2.0/24"
}

resource "azurerm_public_ip" "test" {
    name = "haraytfvm01PIP"
    location = "${azurerm_resource_group.test.location}"
    resource_group_name = "${azurerm_resource_group.test.name}"
    public_ip_address_allocation = "static"
    domain_name_label = "haraytfvm01"
    tags {
        environment = "test"
    }
}


resource "azurerm_network_interface" "test" {
  name = "haraytfvm01nic1"
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"

  ip_configuration {
      name = "haraytfvm01ip"
      subnet_id = "${azurerm_subnet.test.id}"
      private_ip_address_allocation = "dynamic"
      public_ip_address_id = "${azurerm_public_ip.test.id}"
  }
}

resource "azurerm_virtual_machine" "test" {
  name                  = "haraytfvm01"
  location              = "${azurerm_resource_group.test.location}"
  resource_group_name   = "${azurerm_resource_group.test.name}"
  network_interface_ids = ["${azurerm_network_interface.test.id}"]
  vm_size               = "Standard_DS1_v2"

  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04-LTS"
    version   = "latest"
  }

  storage_os_disk {
    name              = "myosdisk1"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
  }

  storage_data_disk {
    name              = "datadisk_new"
    managed_disk_type = "Standard_LRS"
    create_option     = "Empty"
    lun               = 0
    disk_size_gb      = "32"
  }

  os_profile {
    computer_name  = "haraytfvm01"
    admin_username = "${var.default_user}"
    admin_password = "${var.default_password}"
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }

  tags {
    environment = "test"
  }
}

Terraformコマンドを実行する

.tf と .tfvars を同じディレクトリに置いてください。 まず全体像はこんな感じです。

- terraform plan : いわゆるdry-runを実行します。
- terraform apply : 実際プロビジョニングを行います。
- terraform plan -destroy : リソース削除のdry-runです。
- terraform destroy :  リソースを削除します。

plan オプションで確認してから実行、という流れですね。 .tfvars のファイル名が「terraform.tfvars」じゃない場合には、ファイル名を明示的に指定して下さい。

terraform plan -var-file myvmvars.tfvars

Managed Disks の場合、ストレージアカウントを考慮する必要がなくなりますのでより扱いやすくなりますね。