初めてのTerraform(Azure VMをデプロイしてみた)

初めてTerraformでAzureのリソースを作成してみた!!シリーズの2回目になります。

前回は、TerraformのインストールからAzure リソースグループの作成という所までやってみました。今回は仮想マシン(Azure VM)の作成をやってみます。

今回の設定作業にあたっては、こちらのサイトを参考に実施しております。

Terraform を使用して Azure に Linux VM とインフラストラクチャを作成する(MS社公式)

Azure Provider(HashiCorp)

※今回はすべてのファイルをローカルにおいて作業しております。実際の案件等でご利用の際にはストレージアカウント等共有ディレクトリにファイルを置いて実施する事が推奨されています。
※Terraform v0.15.3を使用しております。

目次 

スポンサーリンク

Terraformのインストールからリソースグループ作成まで

前回実施した内容になりますので、こちらの記事を参照願います。

仮想マシン(Azure VM)の構成やTerraformでのリソース作成順序

作成した仮想マシン(Azure VM)の主な構成

今回は以下のような仮想マシン(Azure VM)を作成しました。リソースグループは前回作業で作成済みのものを利用しています。

      • リソースグループ:test-rg
      • リージョン:米国東部2
      • 仮想マシン名:test-vm-01
      • 仮想マシンサイズ:Standard B1ms
      • 仮想ネットワーク:vnet-01/subnet-01
      • パブリックIP:あり(pubip-01)
      • OS:Cent OS 7.7
      • ログイン方法:ユーザー名とパスワードによるログイン
      • ブート診断:有効(自身が作成したストレージアカウントを利用)

※ネットワークセキュリティグループはサブネットに割り当てています。

リソースの作成順序

今回は以下の順番でアイテムを作成しております。今回は1個1個確認しながら作成しています。

      • ネットワークセキュリティグループ(NSG)作成
      • 仮想ネットワーク(V-NET)、サブネット作成
      • パブリックIP作成
      • ストレージアカウント作成
      • ネットワークインターフェース作成
      • 仮想マシン作成

※すべてのリソースを纏めて作成する事も可能ですし、そちらの方が一般的かと思います。

作成したTerraformの設定ファイル一覧

今回作成したファイルは表の通りとなります。主にTerraform自体の設定ファイル、変数に関するファイル、実際に作成するAzureリソース関連のテンプレートファイルで構成されています。今回作成したファイルはすべて同じディレクトリに配置しています。

実際に利用したファイルはGithubにおいてあります。

作成したファイル
Terraform自体の設定ファイル

main.tf(前回作成済み)

required_providersを指定しています。Terraformがどのプロバイダー(Azure等)を利用するのか指定します。

Provider Requirements(Terraform)

※0.13以降で登場したようです。

provider.tf(前回作成済み)

デプロイするproviderを指定しています。Azureのリソースをデプロイする事を宣言しています。

デプロイするサブスクリプションやテナントをはproviderの宣言の中で指定します。

version.tf(前回作成済み) Terraform自体のVersionを指定しています。Terraform自体がVerにより挙動が異なる為、このVerを使用しているよと指定します。
変数定義や設定値関連の設定ファイル

variable.tf

変数を定義しています。今回はVM名、リソースグループ名、仮想ネットワーク名やストレージアカウント名等作成するリソースに関する変数を定義しています。

terraform.tfvars

設定値を記載しています。今回はVM名、リソースグループ名、仮想ネットワーク名やストレージアカウント名等作成するリソースに関する設定値を記載しています。

※Terraformデフォルトの変数設定ファイル名がterraform.tfvarsになります。デプロイ時にファイル名指定しなくても読み込んでくれます。ファイル名を指定する場合は、-var-fileを使ってファイル名を指定します。

リソースに関するテンプレートファイル
resourcegroup.tf リソースグループに関するテンプレートファイル。
nsg.tf ネットワークセキュリティグループに関するテンプレートファイル。
vnet.tf 仮想ネットワークに関するテンプレートファイル。
pubip.tf パブリックIPに関するテンプレートファイル。
storageaccount.tf ストレージアカウントに関するテンプレートファイル。
networkif.tf ネットワークインターフェースに関するテンプレートファイル。
vm.tf 仮想マシンに関するテンプレートファイル。

Terraformでリソースをデプロイする際に利用したコマンド

今回利用したコマンドはapply、 destroyになります。前回の継続での実施を想定していますのでinitコマンドは除いています。

Terraformのコマンド

terraform apply

Terraformを利用してリソースをデプロイするコマンドになります。

terraform destroy

Terraformを利用してリソースを削除するコマンドになります。

※実際の運用上で利用するコマンドは様々あります。今回はオプションを含めて最低限の利用にしております。

Terraformを使ってネットワークセキュリティグループ(NSG)をデプロイ

事前にAzure CLIでAzureへログインてから作業を実施します。az group listと入力してリソースグループの一覧が表示されればログインが完了しています。(前回の記事も参照ください)

NSGをデプロイする為に作成したTerraformの設定ファイル

まず最初にネットワークセキュリティグループを作成します。利用したファイルはnsg.tf、variable.tf、terraform.tfvarsになります。

設定ファイル
  • 作成条件
    • ネットワークセキュリティグループ名は、NSG-01とする
    • ルール名はSSH-RDP-Permitとし優先順位は1000とする
    • 特定のIP(source_address_prefix)からプロトコルTCP、ポート番号22(SSH)と3389(RDP)で仮想ネットワークへのアクセスを許可するルールを作成する
    • NSG名は変数とする
    • リソースグループは事前に作成済みのtest-rgを指定する

今回作成したテンプレート(nsg.tf)はこんな感じになります。(改行とか崩れているのでGithubのファイルを参照ください)

resource “azurerm_network_security_group" “NSG-01" {
  name                = var.nsg-name
  location            = azurerm_resource_group.test-rg.location
  resource_group_name = azurerm_resource_group.test-rg.name

  security_rule {
    name                       = “SSH-RDP-Permit"
    priority                   = 1000
    direction                  = “Inbound"
    access                     = “Allow"
    protocol                   = “Tcp"
    source_port_range          = “*"
    destination_port_ranges    = [“22", “3389"]
    source_address_prefix      = “XXX.XXX.XXX.XXX"
    destination_address_prefix = “VirtualNetwork"
  }

  tags = {}
}

resource_group_nameをazurerm_resource_group.test-rg.nameと指定しています。これは事前にTerraformを使って作成したリソースグループを指定しています。resourcegroup.tfのresourceに記載されている内容を元に記載しています。(locationも同様になります。)

【resourcegroup.tf】
resource “azurerm_resource_group" “test-rg"

【variable.tf(抜粋)】

variable.tfはこのような形になります。ネットワークセキュリティグループ名をnsg-nameとして変数定義しています。

variable “rg-name" {}
variable “rg-location" {}
variable “nsg-name" {}

※作業順に行を追加しています。

【terraform.tfvars(抜粋)】

terraform.tfvarsはこのような形になります。ネットワークセキュリティグループ名の設定値をNSG-01としています。

rg-location = “eastus2"
rg-name = “test-rg"
nsg-name = “NSG-01"

※作業順に行を追加しています。

Terraformを使ってNSGをデプロイ

terraform applyでデプロイを実行しその結果を確認してみます。

実行結果
  • 実行結果を見るとこのような内容が確認出来ます。
    • Terraform will perform the following actions:以下の所で実際に作成(変更、削除)される内容が表示される
    • Plan: 1 to add, 0 to change, 0 to destroy.の行で作成、変更、削除されるリソース数の情報が表示されます。
    • option指定せずにapplyを実行すると途中で実行確認が表示されます。yesと入力すると実行されます。
    • + createの部分に作成されるリソースの情報が表示されますが指定していない情報も表示されます。ここを見るとこういうパラメータも指定できるんだと言う事が分かったりもします。

※Azureの入力規則に沿わないものなどはapply実行時にエラーになります。Azure Portalで作成してエラーになる設定内容(リソース名やパスワード等)はTerraformを使ってもエラーになります。

 

PS C:\terraform> terraform apply

azurerm_resource_group.test-rg: Refreshing state… [id=/subscriptions/サブスクリプションID/resourceGroups/test-rg]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create

Terraform will perform the following actions:

# azurerm_network_security_group.NSG-01 will be created
+ resource “azurerm_network_security_group" “NSG-01" {
+ id = (known after apply)
+ location = “eastus2"
+ name = “NSG-01"
+ resource_group_name = “test-rg"
+ security_rule = [
+ {
+ access = “Allow"
+ description = “"
+ destination_address_prefix = “VirtualNetwork"
+ destination_address_prefixes = []
+ destination_application_security_group_ids = []
+ destination_port_range = “"
+ destination_port_ranges = [
+ “22",
+ “3389",
]
+ direction = “Inbound"
+ name = “SSH-RDP-Permit"
+ priority = 1000
+ protocol = “Tcp"
+ source_address_prefix = “XXX.XXX.XXX.XXX"
+ source_address_prefixes = []
+ source_application_security_group_ids = []
+ source_port_range = “*"
+ source_port_ranges = []
},
]
}

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes’ will be accepted to approve.

Enter a value: yes

azurerm_network_security_group.NSG-01: Creating…
azurerm_network_security_group.NSG-01: Still creating… [10s elapsed]
azurerm_network_security_group.NSG-01: Creation complete after 12s [id=/subscriptions/サブスクリプションID/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/NSG-01]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Azure Portalで実行後の結果を確認してみます。test-rgにNSG-01という名前でネットワークセキュリティグループが出来ている事が分かります。

リソースグループの画面(Azure Portal)

ネットワークセキュリティグループの画面(Azure Portal)

Terraformを使って仮想ネットワーク(V-NET)をデプロイ

仮想マシンが利用する仮想ネットワークやサブネットを作成します。作成したネットワークセキュリティグループをサブネットへ関連付けします。

仮想ネットワーク(V-NET) デプロイする為に作成した設定ファイル

仮想ネットワーク(V-NET)を作成します。利用したファイルはvnet.tf、variable.tf、terraform.tfvarsになります。

設定ファイル
  • 作成条件
    • 仮想ネットワーク名はvnet-01とする
    • サブネットはSubnet-01、02の2つ作成する
    • vnet-01(“10.0.0.0/16")、Subnet-01(“10.0.1.0/24")、Subnet-02(“10.0.2.0/24")とする
    • Subnet-01に先ほど作成したネットワークセキュリティグループNSG-01を割り当てる
    • 仮想ネットワーク名は変数とする
    • リソースグループは事前に作成済みのtest-rgを指定する

resource “azurerm_virtual_network" “vnet-01" {

  name                = var.vnet-name
  location            = azurerm_resource_group.test-rg.location
  resource_group_name = azurerm_resource_group.test-rg.name
  address_space       = [“10.0.0.0/16"]

  subnet {
    name           = “subnet-01"
    address_prefix = “10.0.1.0/24"
    security_group = azurerm_network_security_group.NSG-01.id
  }

  subnet {
    name           = “subnet-02"
    address_prefix = “10.0.2.0/24"
  }

  tags = {}
}

※改行とか崩れているのでGithubのファイルを参照ください

Subnet01に割り当てるネットワークセキュリティグループはsecurity_group = azurerm_network_security_group.NSG-01.idという形でidを設定しています。

※このidはリソースIDを指します。Azure Portalでリソースを選択しプロパティのメニューを確認できる値です。Terraformの場合はterraform.tfstateで確認出来ます。

【variable.tf(抜粋)】

variable.tfはこのような形になります。仮想ネットワーク名をvnet-nameとして変数定義しています。

variable “rg-name" {}
variable “rg-location" {}
variable “nsg-name" {}
variable “vnet-name" {}

※作業順に行を追加しています。

【terraform.tfvars(抜粋)】

terraform.tfvarsはこのような形になります。仮想ネットワーク名の設定値をvnet-01としています。

rg-location = “eastus2"
rg-name = “test-rg"
nsg-name = “NSG-01"
vnet-name = “vnet-01"

※作業順に行を追加しています。

Terraformを使って仮想ネットワーク(V-NET)をデプロイ

terraform applyでデプロイを実行しその結果を確認してみます。

実行結果(一部省略しています)

PS C:\terraform> terraform apply

+ create

Terraform will perform the following actions:

# azurerm_virtual_network.vnet-01 will be created
+ resource “azurerm_virtual_network" “vnet-01" {
+ address_space = [
+ “10.0.0.0/16",
]
+ guid = (known after apply)
+ id = (known after apply)
+ location = “eastus2"
+ name = “vnet-01"
+ resource_group_name = “test-rg"
+ subnet = [
+ {
+ address_prefix = “10.0.1.0/24"
+ id = (known after apply)
+ name = “subnet-01"
+ security_group = “/subscriptions/サブスクリプションID/resourceGroups/test-rg/providers/Microsoft.Network/networkSecurityGroups/NSG-01"
},
+ {
+ address_prefix = “10.0.2.0/24"
+ id = (known after apply)
+ name = “subnet-02"
+ security_group = “"
},
]
+ vm_protection_enabled = false
}

Plan: 1 to add, 0 to change, 0 to destroy.

Enter a value: yes

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

+ createの部分に作成されるリソースの情報が表示されています。またApply complete! Resources: 1 added, 0 changed, 0 destroyed.となっており仮想ネットワークが作成された事が分かります。

Azure Portalで実行後の結果を確認してみます。vnet-01という名前で仮想ネットワークが出来ている事が分かります。また仮想ネットワークではサブネットが2つ、NSGも割り当てられている事が分かります。

リソースグループの画面(Azure Portal)

仮想ネットワーク(サブネット)の画面(Azure Portal)

Terraformを使ってパブリックIPをデプロイ

ネットワークインターフェース(仮想マシン)に関連付けするパブリックIPを作成します。

パブリックIPをデプロイする為に作成した設定ファイル

パブリックIPを作成します。利用したファイルはpubip.tf、variable.tf、terraform.tfvarsになります。

設定ファイル
  • 作成条件
    • パブリックIP名はpubip-01とする
    • IPは動的とする
    • パブリックIP名は変数とする
    • リソースグループは事前に作成済みのtest-rgを指定する

resource “azurerm_public_ip" “publicip-01" {

  name                = var.pubip-name
  location            = azurerm_resource_group.test-rg.location
  resource_group_name = azurerm_resource_group.test-rg.name
  allocation_method   = “Dynamic"
  tags                = {}
}

※改行とか崩れているのでGithubのファイルを参照ください

仮想マシンとパブリックIPの関連付けは、ネットワークインターフェースとパブリックIPを関連付ける事で実現します。関連付けはネットワークインターフェースのデプロイ時に実施します。

【variable.tf(抜粋)】

variable.tfはこのような形になります。パブリックIP名をpubip-nameとして変数定義しています。

variable “rg-name" {}
variable “rg-location" {}
variable “nsg-name" {}
variable “vnet-name" {}
variable “pubip-name" {}

※作業順に行を追加しています。

【terraform.tfvars(抜粋)】

terraform.tfvarsはこのような形になります。パブリックIP名の設定値をpubip-01としています。

rg-location    = “eastus2"
rg-name        = “test-rg"
nsg-name       = “NSG-01"
vnet-name      = “vnet-01"
pubip-name     = “pubip-01"

※作業順に行を追加しています。

Terraformを使ってパブリックIPをデプロイ

terraform applyでデプロイを実行しその結果を確認してみます。

実行結果(一部省略しています)

PS C:\terraform> terraform apply

azurerm_resource_group.test-rg: Refreshing state… 
azurerm_network_security_group.NSG-01: Refreshing state… 
azurerm_virtual_network.vnet-01: Refreshing state… 

+ create

Terraform will perform the following actions:

# azurerm_public_ip.publicip-01 will be created
+ resource “azurerm_public_ip" “publicip-01" {
+ allocation_method = “Dynamic"
+ fqdn = (known after apply)
+ id = (known after apply)
+ idle_timeout_in_minutes = 4
+ ip_address = (known after apply)
+ ip_version = “IPv4"
+ location = “eastus2"
+ name = “pubip-01"
+ resource_group_name = “test-rg"
+ sku = “Basic"
}

Plan: 1 to add, 0 to change, 0 to destroy.

Enter a value: yes

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

+ createの部分に作成されるリソースの情報が表示されています。またApply complete! Resources: 1 added, 0 changed, 0 destroyed.となっておりパブリックIPが作成された事が分かります。

Azure Portalで実行後の結果を確認してみます。pubip-01という名前でパブリックIPが出来ている事が分かります。

リソースグループ(Azure Portal)

パブリックIP(構成)(Azure Portal)

Terraformを使ってストレージアカウントをデプロイ

ストレージアカウントを作成します。作成したストレージアカウントは仮想マシンの診断設定で利用します。

ストレージアカウントをデプロイする為に作成した設定ファイル

ストレージアカウント作成する為に利用したファイルはstorageaccount.tf、variable.tf、terraform.tfvarsになります。

設定ファイル
  • 作成条件
    • ストレージアカウント名はst0123633658754とする
    • アカウントの種類は"Standard"とする
    • レプリケーションはLRS(ローカル冗長)とする
    • パフォーマンス/アクセス層はStandard/クールとする
    • ストレージアカウント名は変数とする
    • リソースグループは事前に作成済みのtest-rgを指定する

※他のリソースの名称と同様にストレージアカウント名はあくまでもサンプルです。

【storageaccount.tf】

resource “azurerm_storage_account" “storageaccount-01" {

  name                     = var.st-name
  resource_group_name      = azurerm_resource_group.test-rg.name
  location                 = azurerm_resource_group.test-rg.location
  account_replication_type = “LRS"
  account_tier             = “Standard"
  access_tier              = “Cool"
  tags                     = {}
}

※改行とか崩れていますのでGithubのファイルを参照ください。

【variable.tf(抜粋)】

variable.tfはこのような形になります。ストレージアカウント名をst-nameとして変数定義しています。

variable “rg-name" {}
variable “rg-location" {}
variable “nsg-name" {}
variable “vnet-name" {}
variable “pubip-name" {}
variable “st-name" {}

※作業順に行を追加しています。

【terraform.tfvars(抜粋)】

terraform.tfvarsはこのような形になります。ストレージアカウントIP名の設定値をst0123633658754としています。

rg-location    = “eastus2"
rg-name        = “test-rg"
nsg-name       = “NSG-01"
vnet-name      = “vnet-01"
pubip-name     = “pubip-01"
st-name        = “st0123633658754"

※作業順に行を追加しています。

Terraformを使ってストレージアカウントをデプロイ

terraform applyでデプロイを実行しその結果を確認してみます。

実行結果(一部省略しています)

PS C:\terraform> terraform apply

+ create

Terraform will perform the following actions:

# azurerm_storage_account.storageaccount-01 will be created
+ resource “azurerm_storage_account" “storageaccount-01" {
+ access_tier = “Cool"
+ account_kind = “StorageV2"
+ account_replication_type = “LRS"
+ account_tier = “Standard"
+ allow_blob_public_access = false
+ enable_https_traffic_only = true
+ id = (known after apply)
+ is_hns_enabled = false
+ large_file_share_enabled = (known after apply)
+ location = “eastus2"
+ min_tls_version = “TLS1_0"
+ name = “st0123633658754"
+ primary_access_key = (sensitive value)
+ primary_blob_connection_string = (sensitive value)

~実行結果省略~

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

+ create(抜粋しています)の部分に作成されるリソースの情報が表示されています。実行結果を見るとストレージアカウントで指定できるパラメータが分かったりします。

Azure Portalで実行後の結果を確認してみます。st0123633658754という名前でストレージアカウントが出来ている事が分かります。

リソースグループ(Azure Portal)

ストレージアカウント(Azure Portal)

Terraformを使ってネットワークインターフェースをデプロイ

仮想マシンのネットワークインターフェースを作成します。

ネットワークインターフェースをデプロイする為に作成した設定ファイル

ネットワークインターフェース作成する為に利用したファイルはnetworkif.tf、variable.tf、terraform.tfvarsになります。

設定ファイル
  • 作成条件
    • ネットワークインターフェース名は仮想マシン名-nicとする
    • subnet-01に関連付けする
    • パブリックIP(pubip-01)を関連付けする
    • プライベートIPアドレスは動的とする。
    • ネットワークインターフェース名、サブスクリプションは変数とする
    • リソースグループは事前に作成済みのtest-rgを指定する

【networkif.tf】

resource “azurerm_network_interface" “test-vm-01-nic" {
  name                = “${var.vm-name}-nic"
  location            = azurerm_resource_group.test-rg.location
  resource_group_name = azurerm_resource_group.test-rg.name
  ip_configuration {
    name                          = “ipconfig"
    subnet_id                     = “${var.subscription}test-rg/providers/Microsoft.Network/virtualNetworks/${var.vnet-name}/subnets/subnet-01"
    private_ip_address_allocation = “Dynamic"
    public_ip_address_id          = azurerm_public_ip.publicip-01.id
  }

  tags = {}
}

※改行とか崩れていますのでGithubのファイルを参照ください。

subnet_idはサブスクリプションに関する変数と仮想ネットワーク名の変数を組み合わせて指定しています。"${変数名}値"という形で指定します。

public_ip_address_id はazurerm_public_ip.publicip-01.idを指定しています。この部分はpubip.tfを参照して指定しています。

【pubip.tf】

resource “azurerm_public_ip" “publicip-01"

【variable.tf(抜粋)】

variable.tfはこのような形になります。今回は仮想マシン名-nicをネットワークインターフェース名としています。ですので仮想マシン名をvm-nameとして変数定義しています。併せてサブスクリプションの変数も追加しています。

variable “subscription" {}
variable “rg-name" {}
variable “rg-location" {}
variable “nsg-name" {}
variable “vnet-name" {}
variable “pubip-name" {}
variable “st-name" {}
variable “vm-name" {}

※作業順に行を追加しています。

【terraform.tfvars(抜粋)】

terraform.tfvarsはこのような形になりました。仮想マシン名の設定値をtest-vm-01としています。サブスクリプション部分は共通となる部分を設定値としています。

subscription   = “/subscriptions/サブスクリプションID/resourceGroups/"
rg-location    = “eastus2"
rg-name        = “test-rg"
nsg-name       = “NSG-01"
vnet-name      = “vnet-01"
pubip-name     = “pubip-01"
st-name        = “st0123633658754"
vm-name        = “test-vm-01"

※作業順に行を追加しています。

Terraformを使ってネットワークインターフェースをデプロイ

terraform applyでデプロイを実行しその結果を確認してみます。

実行結果(一部省略しています)

PS C:\terraform> terraform apply

+ create

Terraform will perform the following actions:

# azurerm_network_interface.test-vm-01-nic will be created
+ resource “azurerm_network_interface" “test-vm-01-nic" {
+ applied_dns_servers = (known after apply)
+ dns_servers = (known after apply)
+ enable_accelerated_networking = false
+ enable_ip_forwarding = false
+ id = (known after apply)
+ internal_dns_name_label = (known after apply)
+ internal_domain_name_suffix = (known after apply)
+ location = “eastus2"
+ mac_address = (known after apply)
+ name = “test-vm-01-nic"
+ private_ip_address = (known after apply)
+ private_ip_addresses = (known after apply)
+ resource_group_name = “test-rg"
+ virtual_machine_id = (known after apply)

+ ip_configuration {
+ name = “ipconfig"
+ primary = (known after apply)
+ private_ip_address = (known after apply)
+ private_ip_address_allocation = “dynamic"
+ private_ip_address_version = “IPv4"
+ public_ip_address_id = “/subscriptions/サブスクリプションID/resourceGroups/test-rg/providers/Microsoft.Network/publicIPAddresses/pubip-01"
+ subnet_id = “/subscriptions/サブスクリプションID/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-01/subnets/subnet-01"
}

Plan: 1 to add, 0 to change, 0 to destroy.

Enter a value: yes

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

+ createの部分に作成されるリソースの情報が表示されています。実行結果を見るとネットワークインターフェースに関連付けされるパブリックIPやサブネットがIDで指定されている事が分かります。

Azure Portalで実行後の結果を確認してみます。test-vm-01-nicという名前でネットワークインターフェースが出来ている事が分かります。

リソースグループ(Azure Portal)

ネットワークインターフェース(Azure Portal)

プライベートIPが10.0.1.4となっており、subnet-01(10.0.1.0/24)と関連付けされている事が分かります。パブリックIP(pubip-01)がネットワークインターフェースと関連付けされている事が確認出来ます。

Terraformを使って仮想マシン(Azure VM)をデプロイ

事前に作成したリソースを利用して仮想マシン(Azure VM)をデプロイします。

仮想マシン(Azure VM)をデプロイする為に作成した設定ファイル

仮想マシン(Azure VM)を作成する為に利用したファイルはvm.tf、variable.tf、terraform.tfvarsになります。

設定ファイル
  • 作成条件
    • 仮想マシン名はtest-vm-01とする
    • 仮想マシンサイズはStandard B1msとする
    • OSはCent OS 7.7(Market Placeを利用)とする
    • ディスク名は仮想マシン名_OsDiskとする
    • OSディスクはStandard HDDとする
    • ログイン方法はユーザー名とパスワードとする
    • ネットワークインターフェース(test-vm-01-nic)を関連付けする
    • ブート診断は有効としストレージアカウント(st0123633658754)を関連付けする
    • 仮想マシン名、ユーザー名、パスワードは変数とする
    • リソースグループは事前に作成済みのtest-rgを指定する

【vm.tf】

resource “azurerm_linux_virtual_machine" “VM-01" {
  name                  = var.vm-name
  location              = azurerm_resource_group.test-rg.location
  resource_group_name   = azurerm_resource_group.test-rg.name
  network_interface_ids = [azurerm_network_interface.test-vm-01-nic.id]
  size                  = “Standard_B1ms"

  os_disk {
    name                 = “${var.vm-name}_OsDisk"
    caching              = “ReadWrite"
    storage_account_type = “Standard_LRS"
  }

  source_image_reference {
    publisher = “OpenLogic"
    offer     = “CentOS"
    sku       = “7.7"
    version   = “latest"
  }

  computer_name                   = var.vm-name
  admin_username                  = var.admin_username
  admin_password                  = var.admin_password
  disable_password_authentication = false

  boot_diagnostics {
    storage_account_uri = azurerm_storage_account.storageaccount-01.primary_blob_endpoint
  }

  tags = {}
}

※改行とか崩れていますのでGithubのファイルを参照ください。

source_image_referenceではOSのイメージを指定します。指定する設定値の確認方法は色々ありますが、一番簡単なのは実際に作成したVMのテンプレートを確認する事かと思います。Azure Portalの仮想マシンのメニューにテンプレートのエクスポートと言う項目があります。ここでテンプレートが見れます。テンプレート内に以下のような記述がありこれと同じ値を指定します。

“imageReference": {
 "publisher": “OpenLogic",
   “offer": “CentOS",
   “sku": “7.7",
   “version": “latest"
},

【variable.tf(抜粋)】

variable.tfはこのような形になりました。ユーザー名、パスワードを変数定義しています。仮想マシン名はネットワークインターフェース作成時に定義したのをそのまま使います。

variable “subscription" {}
variable “rg-name" {}
variable “rg-location" {}
variable “nsg-name" {}
variable “vnet-name" {}
variable “pubip-name" {}
variable “st-name" {}
variable “vm-name" {}
variable “admin_username" {}
variable “admin_password" {}

※作業順に行を追加しています。

【terraform.tfvars(抜粋)】

terraform.tfvarsはこのような形になりました。ユーザー名、パスワードを設定しています。

subscription   = “/subscriptions/サブスクリプションID/resourceGroups/"
rg-location    = “eastus2"
rg-name        = “test-rg"
nsg-name       = “NSG-01"
vnet-name      = “vnet-01"
pubip-name     = “pubip-01"
st-name        = “st0123633658754"
vm-name        = “test-vm-01"
admin_username = “testuser01"
admin_password = “パスワード"

今回はユーザー名をtestuser01としています。パスワードは任意の値を設定します。ユーザー名、パスワードの値に関する制限はAzure Portalで作成する時と同様にありますのでその点は注意が必要です。

【パスワードに関する制限例】

パスワードには、次のうちの 3 つを含める必要があります: 1 つの小文字、1 つの大文字、1 つの数字、および 1 つの特殊文字。値の長さは 12 ~ 72 文字にする必要があります。

Terraformを使って仮想マシン(Azure VM)をデプロイ

terraform applyでデプロイを実行しその結果を確認してみます。

実行結果(一部省略しています)

PS C:\terraform> terraform apply

+ create

Terraform will perform the following actions:

# azurerm_linux_virtual_machine.VM-01 will be created
+ resource “azurerm_linux_virtual_machine" “VM-01" {
+ admin_password = (sensitive value)
+ admin_username = “testuser01"
+ allow_extension_operations = true
+ computer_name = “test-vm-01"
+ disable_password_authentication = false
+ location = “eastus2"
+ name = “test-vm-01"
+ network_interface_ids = [
+ “/subscriptions/サブスクリプションID/resourceGroups/test-rg/providers/Microsoft.Network/networkInterfaces/test-vm-01-nic",
]
+ priority = “Regular"
+ private_ip_address = (known after apply)
+ private_ip_addresses = (known after apply)
+ provision_vm_agent = true
+ public_ip_address = (known after apply)
+ public_ip_addresses = (known after apply)
+ resource_group_name = “test-rg"
+ size = “Standard_B1ms"
+ virtual_machine_id = (known after apply)
+ zone = (known after apply)

+ boot_diagnostics {
+ storage_account_uri = “https://st0123633658754.blob.core.windows.net/"
}

+ os_disk {
+ caching = “ReadWrite"
+ disk_size_gb = (known after apply)
+ name = “test-vm-01_OsDisk"
+ storage_account_type = “Standard_LRS"
+ write_accelerator_enabled = false
}

+ source_image_reference {
+ offer = “CentOS"
+ publisher = “OpenLogic"
+ sku = “7.7"
+ version = “latest"
}
}

Plan: 1 to add, 0 to change, 0 to destroy.

Enter a value: yes

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

+ createの部分に作成されるリソースの情報が表示されています。

Azure Portalで実行後の結果を確認してみます。test-vm-01という名前で仮想マシンが出来ている事が分かります。

リソースグループ(Azure Portal)

仮想マシン(Azure Portal)

仮想マシンの概要でプロパティを確認すると、指定した設定値通り作成されている事が分かります。

最後に

今回は初めてのTerraformと言う事でAzure 仮想マシンの作成についてやってみました。

あくまでも1例として実施しています。変数化が徹底出来てなかったり、パスワードが平文だったり(SSHキー化もしていない)、作成したリソースが基本設定だったりします。

また説明が至らない点も多くあるかと思います。その編は温かい目で見て頂ければと思います。

最後に作成したリソースはterraform destroyコマンドを利用してリソースグループを削除願います。

PS C:\terraform > terraform destroy -target="azurerm_resource_group.test-rg"

次回はterraform importコマンドを使った既存リソース情報の取り込みをやってみました。