Azure
Terraform
CloudShell

azureのCloudShellでterraformでvmをたてる

ポータルの右上の[>_]をクリックしてコンソールを操作。
azとterraformコマンドが何もしなくても使えるのとサービスプリンシパルでログインする必要がなくなる
ただしCloudShellは落ちるたびにグローバルIPアドレスが変わるので外部のgitlab等につなぎたい等ある場合はssh-proxyか何か仕込むのがよさそう。

使いたいイメージ(Ubuntu16)の情報を特定してtfvarsファイル等を編集する
$ az vm image list --location "japanwest"
  {
    "offer": "UbuntuServer",
    "publisher": "Canonical",
    "sku": "16.04-LTS",
    "urn": "Canonical:UbuntuServer:16.04-LTS:latest",
    "urnAlias": "UbuntuLTS",
    "version": "latest"
  },
$ cat terraform.tfvars
default_user = "myuser"
default_password = "*********"
resouce_group_name = "my-resouce-group"
location = "Japan West"
azurerm_virtual_network_name = "mynet01VNET"
azurerm_virtual_network_address_space = "10.0.0.0/16"
azurerm_subnet_name = "myPub01Subnet"
azurerm_subnet_address_prefix = "10.0.0.0/23"
virtual_machine_name_test = "vm01"
storage_account = "mystrageaccountname"
account_tier = "Standard"
account_replication_type = "LRS"
vm_size = "Standard_DS1_v2"
storage_image_reference_publisher = "Canonical"
storage_image_reference_offer = "UbuntuServer"
storage_image_reference_sku = "16.04-LTS"
storage_image_reference_version = "latest"
tfファイルを編集する
$ cat terraform.tf
variable "default_user" {}
variable "default_password" {}
variable "resouce_group_name" {}
variable "location" {}
variable "azurerm_virtual_network_name" {}
variable "azurerm_virtual_network_address_space" {}
variable "azurerm_subnet_name" {}
variable "azurerm_subnet_address_prefix" {}
variable "virtual_machine_name_test" {}
variable "storage_account" {}
variable "account_tier" {}
variable "account_replication_type" {}
variable "vm_size" {}
variable "storage_image_reference_publisher" {}
variable "storage_image_reference_offer" {}
variable "storage_image_reference_sku" {}
variable "storage_image_reference_version" {}
provider "azurerm" {
}
resource "azurerm_resource_group" "test" {
  name = "${var.resouce_group_name}"
  location = "${var.location}"
}
resource "azurerm_virtual_network" "test" {
  name = "${var.azurerm_virtual_network_name}"
  address_space = ["${var.azurerm_virtual_network_address_space}"]
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
}
resource "azurerm_subnet" "test" {
  name = "${var.azurerm_subnet_name}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  virtual_network_name = "${azurerm_virtual_network.test.name}"
  address_prefix = "${var.azurerm_subnet_address_prefix}"
}
resource "azurerm_public_ip" "test" {
    name = "${var.virtual_machine_name_test}-PIP"
    location = "${azurerm_resource_group.test.location}"
    resource_group_name = "${azurerm_resource_group.test.name}"
    public_ip_address_allocation = "static"
    domain_name_label = "${var.virtual_machine_name_test}"
    tags {
        environment = "test"
    }
}
resource "azurerm_network_interface" "test" {
  name = "${var.virtual_machine_name_test}-nic1"
  location = "${azurerm_resource_group.test.location}"
  resource_group_name = "${azurerm_resource_group.test.name}"
  ip_configuration {
      name = "${var.virtual_machine_name_test}-ip"
      subnet_id = "${azurerm_subnet.test.id}"
      private_ip_address_allocation = "dynamic"
      public_ip_address_id = "${azurerm_public_ip.test.id}"
  }
}
resource "azurerm_storage_account" "test" {
    name = "${var.storage_account}"
    resource_group_name = "${azurerm_resource_group.test.name}"
    location = "${azurerm_resource_group.test.location}"
    account_tier = "${var.account_tier}"
    account_replication_type = "${var.account_replication_type}"
    tags {
        environment = "staging"
    }
}
resource "azurerm_storage_container" "test" {
    name = "vhds"
    resource_group_name = "${azurerm_resource_group.test.name}"
    storage_account_name = "${azurerm_storage_account.test.name}"
    container_access_type = "private"
}
resource "azurerm_virtual_machine" "test" {
  name                  = "${var.virtual_machine_name_test}"
  location              = "${azurerm_resource_group.test.location}"
  resource_group_name   = "${azurerm_resource_group.test.name}"
  network_interface_ids = ["${azurerm_network_interface.test.id}"]
  vm_size               = "${var.vm_size}"
  storage_image_reference {
    publisher = "${var.storage_image_reference_publisher}"
    offer = "${var.storage_image_reference_offer}"
    sku = "${var.storage_image_reference_sku}"
    version = "${var.storage_image_reference_version}"
  }
  storage_os_disk {
    name              = "${var.virtual_machine_name_test}-osdisk1"
    vhd_uri = "${azurerm_storage_account.test.primary_blob_endpoint}${azurerm_storage_container.test.name}/${var.virtual_machine_name_test}-osdisk1.vhd"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    os_type           = "linux"
  }
  storage_data_disk {
    name              = "${var.virtual_machine_name_test}-datadisk1"
    vhd_uri = "${azurerm_storage_account.test.primary_blob_endpoint}${azurerm_storage_container.test.name}/${var.virtual_machine_name_test}-datadisk1.vhd"
    create_option     = "Empty"
    lun               = 0
    disk_size_gb      = "32"
  }
  os_profile {
    computer_name  = "${var.virtual_machine_name_test}"
    admin_username = "${var.default_user}"
    admin_password = "${var.default_password}"
  }
  os_profile_linux_config {
    disable_password_authentication = false
  }
  tags {
    environment = "test"
  }
}
plan打って確認

$ terraform plan

applyする

$ terraform apply

showで実行結果を標準出力

$ terraform show

あとはポータルから確認しつつNSGをNicに紐づける等をする。

terraformの感想ですが、手間的にはマニュアル眺めまわさないといけないことからazコマンド等と変わらなくて見える化と使いまわす場合に若干便利になります。
マルチクラウドっていってもそれぞれのクラウドプロバイダのマニュアルガン見しないといけなくて個々のクラウドに詳しくなくて大丈夫なんてうまい話はなくアップデート多く追随するのが楽しい人向けでマイナーなクラウドは人柱確定な印象でした。(cloud-stackがヤバかったかな)

参考

https://aimless.jp/blog/archives/2017-09-16-use-terraform-without-serviceprincipal/
https://www.terraform.io/docs/providers/azurerm/r/storage_blob.html
https://snickerjp.blogspot.jp/2015/06/ssh-proxycommand.html