Terraform変数の使い方をAzure VMで学んでみた

Azure,Terraform,Virtual Machine

Terraformでは変数を扱う事が出来ます。
変数にはローカル変数とインプット変数があります。
1つの場所で値を管理する事が出来るので、ファイルを読みやすくしたり変更時のメンテナンスを容易にする事が出来ます。
またデプロイ時にリソースの値まを指定する事が出来ます。

今回はローカル変数やインプット変数を使ってAzure VMをデプロイしてみます。

スポンサーリンク

Terraform の変数

変数にはローカル変数とインプット変数の2つある

Terraform の変数には大きく分けてローカル変数とインプット変数の2つあります。

    • ローカル変数(Local Values(Terraform))
      • localsブロックで定義される
      • ローカル変数へ同一モジュール内で定義される
      • ローカル変数が使えるのはモジュール内のみ
      • resourceブロックからはlocal.変数名で参照できる
    • インプット変数(Input Variables(Terraform))
      • variableブロックで定義される
      • 外部から値を指定する事が可能
        • applay時に値を指定(applyコマンドで指定や対話形式での指定)
        • ファイルで値を指定(デフォルトではterraform.tfvars)
        • 環境変数で値を指定(TF_VAR_変数名="値")
      • インプット変数は別モジュールから参照可能
      • resourceブロックからはvar.変数名で参照できる

今回の流れ

同じ構成のAzure VMを変数使うように変更しながら確認したいと思います。

    • 変数を利用せずにAzure VMをデプロイ
    • ローカル変数を利用してAzure VMをデプロイ
    • インプット変数を利用してAzure VMをデプロイ
      • .tfvarsで指定
      • apply時に指定

変数を利用せずにAzure VMをデプロイ

最初は変数を利用せずにTerraformでAzure VMをデプロイしてみます。

Azure VM(Azure VM)の主な構成

Windows 2019 DatecenterのAzure VMをデプロイしています。
Terraform のazurerm_windows_virtual_machineを利用します。
変数に関わる設定値はこちらの通りになります。

区分 項目 設定値
リソースグループ リソースブロックローカル名 terraform-test-rg
リソースグループ名
terraform-rg
場所
eastus2
仮想ネットワーク リソースブロックローカル名
terraform-test-vnet
仮想ネットワーク名
terraform-vent
サブネット リソースブロックローカル名
terraform-test-subnet
サブネット名
terraform-internal
ネットワークインターフェース リソースブロックローカル名 terraform-test-nif
ネットワークインターフェース名
terraform-test-vm-nic
Azure VM リソースブロックローカル名
terraform-test-vm
Azure VM名
terra-testvm

main.tf

main.tfでrequired_version、required_providers、providerの指定を行っています。
今回はmain.tfとそれぞれ作成したファイルでデプロイを行っています。

main.tf
terraform {
  required_version = “>= 0.12"
  required_providers {
    azurerm = {
      source  = “hashicorp/azurerm"
      version = “=2.46.0"
    }
  }
}

provider “azurerm" {
  features {}
}

※そのままコピペすると空白が入ってエラーになる事がありますので、適時vs code等で修正をお願いします。

変数を利用せずにTerraformを使ってAzure VMをデプロイ

vm.tfと言う名前でファイルを保存します。
各設定値はファイル内にべた書きする形になります。
同じディレクトリにmain.tfとvm.tfを配置しTerraform applyし仮想マシンをデプロイします。

vm.tf
resource “azurerm_resource_group" “terraform-test-rg" {
  name     = “terraform-rg"
  location = “eastus2"
}

resource “azurerm_virtual_network" “terraform-test-vnet" {
  name                = “terraform-vent"
  address_space       = [“10.0.0.0/16"]
  location            = azurerm_resource_group.terraform-test-rg.location
  resource_group_name = azurerm_resource_group.terraform-test-rg.name
}

resource “azurerm_subnet" “terraform-test-subnet" {
  name                 = “terraform-internal"
  resource_group_name  = azurerm_resource_group.terraform-test-rg.name
  virtual_network_name = azurerm_virtual_network.terraform-test-vnet.name
  address_prefixes     = [“10.0.2.0/24"]
}
resource “azurerm_network_interface" “terraform-test-nif" {
  name                = “terraform-test-vm-nic"
  location            = azurerm_resource_group.terraform-test-rg.location
  resource_group_name = azurerm_resource_group.terraform-test-rg.name

  ip_configuration {
    name                          = “internal"
    subnet_id                     = azurerm_subnet.terraform-test-subnet.id
    private_ip_address_allocation = “Dynamic"
  }
}

resource “azurerm_windows_virtual_machine" “terraform-test-vm" {
  name                = “terra-testvm"
  resource_group_name = azurerm_resource_group.terraform-test-rg.name
  location            = azurerm_resource_group.terraform-test-rg.location
  size                = “Standard_B2ms"
  admin_username      = “adminuser"
  admin_password      = “P@$$w0rd1234!"
  network_interface_ids = [
    azurerm_network_interface.terraform-test-nif.id,
  ]

  os_disk {
    caching              = “ReadWrite"
    storage_account_type = “Standard_LRS"
  }

  source_image_reference {
    publisher = “MicrosoftWindowsServer"
    offer     = “WindowsServer"
    sku       = “2019-Datacenter"
    version   = “latest"
  }
}

※そのままコピペすると空白が入ってエラーになる事がありますので、適時vs code等で修正をお願いします。

作成された仮想マシンを確認

Azure Portalで作成されたリソースを確認してみます。
指定したパラメータ通り仮想マシンが作成されている事が分かります。

Azure Portalで確認

ローカル変数を使ってAzure VMをデプロイ

ローカル変数を使ってAzure VMをデプロイしてみます。

ローカル変数の使い方

Local Values(Terraform)

ローカル変数はLocalsブロックで定義されます。
同じモジュール内で参照が可能です。

ローカル変数の使い方

ローカル変数の定義

locals {
  変数名     = “設定値"
}

ローカル変数を参照する場合

resource “リソースタイプ名" “ローカル名" {
  リソース定義(name等)     = local.変数名
}

※localsブロックは複数設定する事が可能です。

ローカル変数を使ってAzure VMをデプロイ

先ほど作成したVM.tfをローカル変数を使うように変更してみます。VM_local.tfとして保存しています。
最初にlocalsブロックでリソース作成時に使用するリソースグループ名や仮想マシン名を定義しています。

VM_local.tf
locals {
  rg_name     = “terraform-rg"
  rg_location = “eastus2"
  vnet_name   = “terraform-vent"
  subnet_name = “terraform-internal"
  nic_name    = “terraform-test-vm-nic"
  vm_name     = “terra-testvm"
}

resource “azurerm_resource_group" “terraform-test-rg" {
  name     = local.rg_name
  location = local.rg_location
}

resource “azurerm_virtual_network" “terraform-test-vnet" {
  name                = local.vnet_name
  address_space       = [“10.0.0.0/16"]
  location            = azurerm_resource_group.terraform-test-rg.location
  resource_group_name = azurerm_resource_group.terraform-test-rg.name
}

resource “azurerm_subnet" “terraform-test-subnet" {
  name                 = local.subnet_name
  resource_group_name  = azurerm_resource_group.terraform-test-rg.name
  virtual_network_name = azurerm_virtual_network.terraform-test-vnet.name
  address_prefixes     = [“10.0.2.0/24"]
}
resource “azurerm_network_interface" “terraform-test-nif" {
  name                = local.nic_name
  location            = azurerm_resource_group.terraform-test-rg.location
  resource_group_name = azurerm_resource_group.terraform-test-rg.name

  ip_configuration {
    name                          = “internal"
    subnet_id                     = azurerm_subnet.terraform-test-subnet.id
    private_ip_address_allocation = “Dynamic"
  }
}

resource “azurerm_windows_virtual_machine" “terraform-test-vm" {
  name                = local.vm_name
  resource_group_name = azurerm_resource_group.terraform-test-rg.name
  location            = azurerm_resource_group.terraform-test-rg.location
  size                = “Standard_B2ms"
  admin_username      = “adminuser"
  admin_password      = “P@$$w0rd1234!"
  network_interface_ids = [
    azurerm_network_interface.terraform-test-nif.id,
  ]

  os_disk {
    caching              = “ReadWrite"
    storage_account_type = “Standard_LRS"
  }

  source_image_reference {
    publisher = “MicrosoftWindowsServer"
    offer     = “WindowsServer"
    sku       = “2019-Datacenter"
    version   = “latest"
  }
}

※そのままコピペすると空白が入ってエラーになる事がありますので、適時vs code等で修正をお願いします。

Terraform apply時にローカル変数を確認

Terraform applyで確認してみるとlocationやnameにローカル変数の値が設定されている事が分かります。

ローカル変数確認(リソースグループ)
 # azurerm_resource_group.terraform-test-rg will be created
+ resource “azurerm_resource_group" “terraform-test-rg" {
+ id = (known after apply)
+ location = “eastus2"
+ name = “terraform-rg"
}

作成された仮想マシンを確認

Azure Portalで作成されたリソースを確認してみます。
ローカル変数指定した場合と変数を使わない場合と同じパラメータで仮想マシンが作成されている事が分かります。

Azure Portalで確認

※全く同じ構成でデプロイしているので同じ画面となります。(OSのディスク名が違うだけです。)

インプット変数を使ってAzure VMをデプロイ

インプット変数を使ってAzure VMをデプロイしてみます。

インプット変数の使い方

Input Variables(Terraform)

インプット変数はvariableブロックで定義されます。
variableブロックではデフォルト値やtype制約を指定する事が出来ます。
defaultを使用するとインプット変数の入力値が指定されない場合はその値が使用されます。
nullable引数を使うとnull値を許可しない設定が可能です。
変数に割り当てる設定値はデプロイ時に指定やファイルで指定する事が出来ます。

インプット変数の使い方

インプット変数の定義

variable “変数名"{
  default = “デフォルト値"
 type = string
}

ファイルでインプット変数を設定する場合(variable.tf、var.tf等)

resource “リソースタイプ名" “ローカル名" {
  リソース定義(name等)     = var.変数名
}

ファイルで設定値を割り当てる(terraform.tfvars等)

変数名     = “設定値"

インプット変数を使ってAzure VMをデプロイする

最初に作成したvm.tfをインプット変数使うように変更してみます。
インプット変数定義、引き渡す値について、それぞれ別ファイルを参照する形で作成しています。

  • 作成したファイル(main.tfを除く)
    • VM_variable.tf(resourceブロックでAzure VMを定義)
    • variable.tf(variableブロックでAzure VM作成時のインプット変数を定義)
    • terraform.tfvars(変数の設定値を割り当て)

※今回はインプット変数のデフォルト値等は設定していません。

構成ファイル

【VM_variable.tf】

resource “azurerm_resource_group" “terraform-test-rg" {
  name     = var.rg_name
  location = var.rg_location
}

resource “azurerm_virtual_network" “terraform-test-vnet" {
  name                = var.vnet_name
  address_space       = [“10.0.0.0/16"]
  location            = azurerm_resource_group.terraform-test-rg.location
  resource_group_name = azurerm_resource_group.terraform-test-rg.name
}

resource “azurerm_subnet" “terraform-test-subnet" {
  name                 = var.subnet_name
  resource_group_name  = azurerm_resource_group.terraform-test-rg.name
  virtual_network_name = azurerm_virtual_network.terraform-test-vnet.name
  address_prefixes     = [“10.0.2.0/24"]
}
resource “azurerm_network_interface" “terraform-test-nif" {
  name                = var.nic_name
  location            = azurerm_resource_group.terraform-test-rg.location
  resource_group_name = azurerm_resource_group.terraform-test-rg.name

  ip_configuration {
    name                          = “internal"
    subnet_id                     = azurerm_subnet.terraform-test-subnet.id
    private_ip_address_allocation = “Dynamic"
  }
}

resource “azurerm_windows_virtual_machine" “terraform-test-vm" {
  name                = var.vm_name
  resource_group_name = azurerm_resource_group.terraform-test-rg.name
  location            = azurerm_resource_group.terraform-test-rg.location
  size                = “Standard_B2ms"
  admin_username      = “adminuser"
  admin_password      = “P@$$w0rd1234!"
  network_interface_ids = [
    azurerm_network_interface.terraform-test-nif.id,
  ]

  os_disk {
    caching              = “ReadWrite"
    storage_account_type = “Standard_LRS"
  }

  source_image_reference {
    publisher = “MicrosoftWindowsServer"
    offer     = “WindowsServer"
    sku       = “2019-Datacenter"
    version   = “latest"
  }
}

【variable.tf】

/*リソースグループ*/
variable “rg_name" {}
variable “rg_location" {}

/*仮想ネットワーク*/
variable “vnet_name" {}
variable “subnet_name" {}

/*Azure VM*/
variable “nic_name" {}
variable “vm_name" {}

【terraform.tfvars】

/*リソースグループ*/
rg_name     = “terraform-rg"
rg_location = “eastus2"

/*仮想ネットワーク*/
vnet_name   = “terraform-vent"
subnet_name = “terraform-internal"

/*Azure VM*/
nic_name = “terraform-test-vm-nic"
vm_name  = “terra-testvm"

※そのままコピペすると空白が入ってエラーになる事がありますので、適時vs code等で修正をお願いします。

Terraform apply時にインプット変数を確認

Terraform applyで確認してみるとlocationやnameにterraform.tfvarsで設定したインプット変数の値が割り当てられている事が分かります。

ローカル変数設定確認(リソースグループ)
 # azurerm_resource_group.terraform-test-rg will be created
+ resource “azurerm_resource_group" “terraform-test-rg" {
+ id = (known after apply)
+ location = “eastus2"
+ name = “terraform-rg"
}

作成された仮想マシンを確認

Azure Portalで作成されたリソースを確認してみます。
ローカル変数指定した場合と変数を使わない場合と同じパラメータで仮想マシンが作成されている事が分かります。

Azure Portalで確認

※全く同じ構成でデプロイしているので同じ画面となります。(OSのディスク名が違うだけです。)

Terraform apply時に-varで変数を指定する事も出来る

Terraform apply時に変数を指定する事も出来ます。
リソースグループ名をterraform-rg-01と指定してterraform applyを実行してみます。
リソース作成計画を確認するとterraform-rg-01となっている事が確認出来ました。

-varで変数を指定(リソースグループ)

PS C:\terraform\TEST> terraform apply -var="rg_name=terraform-rg-01″

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_resource_group.terraform-test-rg will be created
+ resource “azurerm_resource_group" “terraform-test-rg" {
+ id = (known after apply)
+ location = “eastus2"
+ name = “terraform-rg-01"
}

対話形式でデプロイ

変数に引き渡す値を指定しない場合(かつデフォルト値を指定しない場合)、対話形式での入力となります。

リソース作成計画を確認するとterraform-rg-01となっている事が確認出来ました。

対話形式で変数を指定(リソースグループ)

PS C:\terraform\TEST>terraform apply

var.rg_name
Enter a value: test-rg-02

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_resource_group.terraform-test-rg will be created
+ resource “azurerm_resource_group" “terraform-test-rg" {
+ id = (known after apply)
+ location = “eastus2"
+ name = “test-rg-02"
}

最後に

Terraform の変数について基本的な部分について、学習した内容を纏めてみました。
変数を使うとどこで値を設定しているのか非常に分かりやすく、リソースの管理も簡単になりとても便利かと思います。
今後も引き続き色々試して行きたいと思います。

Terraform関連の記事一覧がこちらになります。モジュール等でも変数を使っておりますので併せて見て頂ければ幸いです。

Terraformの記事一覧

スポンサーリンク