Terraform Moduleの使い方をAzure仮想マシンで学ぶ

Azure,Terraform,Virtual Machine

Azure仮想マシンを例にTerraform Moduleの使い方やモジュールの再利用について試してみました。

Terraform関連の記事一覧はこちらになります。併せて見て頂けると大変有難いです。 

Terraform 記事一覧

スポンサーリンク

Terraform moduleとは

Terraform moduleって何

Module Blocks

公式サイト記載の内容を要約するとこんな感じかなぁと思います。

    • モジュールとは同一ディレクトリにあるTerraform 構成ファイル一式
    • 複数のモジュールで構成する事が出来る
    • ルートモジュールから子モジュールを呼び出して使う事が出来る。
    • リソース構成をパッケージ化する事で再利用できる。

Terraform Moduleの使い方やメリットが理解しにくかったのでAzure仮想マシンを例にモジュール化して確認してみます。

Terraform Moduleの使い方

モジュールの呼び出し方法はmoduleブロックを作成して参照するモジュールの相対パスを指定します。
参照先のリソースに引き渡す引数とセットで利用する事が出来ます。
Output値を利用する事でルートモジュールから参照先の値を利用する事も可能です

構成ファイル

モジュールを参照する場合

module “ローカル名" {
  source      = “モジュールの参照先パス(相対パス)"(例;./modules/rg)
  引数名     = “参照先のリソースに引き渡す値"(例;"terraform-rg")
}

他のモジュールの値を参照する場合(output値を利用する)

rg-name     = module.参照したいモジュールのローカル名.アウトプット値のローカル名

モジュール化せずに仮想マシン(Azure VM)をデプロイ

まず最初にTerraform でモジュール化せずに仮想マシンをデプロイしてみます。

仮想マシン(Azure VM)の主な構成(モジュール化前)

今回はこんな感じの設定でWindows 2019 Datecenterをデプロイしています。

区分 項目 設定値
リソースグループ リソースブロックローカル名 terraform-test-rg
リソースグループ名
terraform-rg
場所
eastus2
仮想ネットワーク リソースブロックローカル名
terraform-test-vnet
仮想ネットワーク名
terraform-vent
アドレス空間
10.0.0.0/16
サブネット リソースブロックローカル名
terraform-test-subnet
サブネット名
terraform-internal
サブネットアドレス空間
10.0.2.0/24
ネットワークインターフェース リソースブロックローカル名 terraform-test-nif
ネットワークインターフェース名
terraform-test-vm-nic
仮想マシン リソースブロックローカル名
terraform-test-vm
仮想マシン名
terra-testvm-1
管理者ユーザー名
adminuser
管理者パスワード
P@$$w0rd1234!

※今回はモジュール設定の確認用なので最低限の設定にしています。

Terraform構成ファイル一覧

仮想マシンを1つのテンプレートファイルにしています。

作成したファイル
Terraform自体の設定
main.tf required_providersを指定しています。
TerraformがAzureを利用するように指定しています。
provider.tf デプロイするproviderを指定しています。
Azureのリソースをデプロイする事を宣言しています。
version.tf Terraform自体のVersionを指定しています。
リソースに関するテンプレート
vm.tf 仮想マシンに関するテンプレートファイル

※Terraform 自体の設定に関するファイルについてはこちらを参照ください。

ディレクトリ構成(モジュール化前)

仮想マシンデプロイ時(モジュール化前)のディレクトリ構成です。

ディレクトリ構成

ディレクトリ: C:\terraform\module_test

Mode LastWriteTime Length Name
—- ————- —— —-
-a—- 2021/05/07 17:17 131 main.tf
-a—- 2021/05/07 17:17 40 provider.tf
-a—- 2021/05/07 17:10 46 version.tf
-a—- 2022/05/29 10:10 1899 VM .tf

Azure仮想マシン用のTerraform構成ファイル

Terraform レジストリのテンプレートを使い仮想マシン(Azure VM)を作成してみます。

azurerm_windows_virtual_machine

構成ファイル

【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-1"
  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"
  }
}

デプロイ後の確認

Terraform Applyで仮想マシンをデプロイします。
デプロイ後にAzure Portal上で確認すると仮想マシンがデプロイされている事が分かります。

仮想マシン作成結果

Azure仮想マシンのテンプレートをモジュール化してみた

Azure仮想マシンをモジュール化してみる

まずAzure仮想マシンを作成した際の構成ファイルをリソース単位に分解してみます。
大きく分けると3つのリソースセクションに分かれている事が分かります。

    • リソースグループ
    • 仮想ネットワーク(仮想ネットワーク、サブネット)
    • 仮想マシン(仮想マシン、ネットワークインターフェース)
仮想マシンテンプレート

これをモジュールに分解して各リソースごとにディレクトリを分けていきます。

    • ルートディレクトリ
    • モジュール関連
      • リソースグループ
      • 仮想マシン
      • 仮想ネットワーク

モジュール化した後のディレクトリ構成はこのような形になります。

ディレクトリ構成

※仮想マシン2台作成時のディレクトリ構成になります。ルートディレクトリにVM-01.tf、VM-02.tfの2つあるのはその為です。

モジュール化時のブロック構成

モジュール化時のリソースブロック名です。

区分 ローカル名
リソースグループ rg
仮想ネットワーク
vnet
仮想マシン
vm

モジュール化の進め方

モジュール化の目的の1つに再利用可能な事があります。
リソースの変数化を進める事で再利用性を高める事が出来ますので併せて実施しています。
リソースグループ部分のモジュール化はこのように進めてみました。

    • ルートモジュールにあったvm.tfのリソースグループ部分をrg.tfとして分割
      • コピーして/modules/rg/rg.tfとして新規ファイルを作成
    • ルートモジュールのvm.tfをvf-01.tfとしリソースグループのモジュールを参照するように変更
    • rg.tfのリソースグループ名、場所を変数化
      • var.rg-nameと変更(場所も同様)
      • variable.tfを作成しvariable “rg-name" {}として変数を定義(場所も同様)
    • ルートモジュールのvf-01.tfでモジュール化されたrg.tfに渡す変数を定義
    • output.tfを作成
      • ルートモジュールで参照する為にアウトプット値を定義

※ファイル名の変更(vm.tf→vm-01.tf)は作業上区別を行う為に実施しています。変更しなくても問題ありません。

Terraform での変数についてはこちら。併せて見て頂けると大変有難いです。

リソースグループをモジュール化

モジュール化の進め方に基づき作成したリソースグループの構成ファイルです。

構成ファイル

【ルートモジュール】vf-01.tf(リソースグループ部分のみを抜粋)

module “rg" {
  source      = “./modules/rg"
  rg-name     = “terraform-rg"
  rg-location = “eastus2"
}

【リソースグループモジュール】rg.tf

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

【リソースグループモジュール】variable.tf

/*リソースグループ*/
variable “rg-name" {}
variable “rg-location" {}

【リソースグループモジュール】output.tf

output “terraform-test-rg-name" {
  value = azurerm_resource_group.terraform-test-rg.name
}
output “terraform-test-rg-location" {
  value = azurerm_resource_group.terraform-test-rg.location
}

仮想ネットワークをモジュール化

モジュール化の進め方に基づき作成した仮想ネットワークの構成ファイルです。
リソースグループの引数はリソースグループモジュールのOutput値を利用しています。

設定ファイル

【ルートモジュール】vf-01.tf(仮想ネットワーク部分のみを抜粋)

module “vnet" {
  source      = “./modules/vnet"
  rg-name     = module.rg.terraform-test-rg-name
  rg-location = module.rg.terraform-test-rg-location
  vnet-name   = “terraform-vent"
  subnet-name = “terraform-internal"
}

【仮想ネットワークモジュール】vnet.tf

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

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

【仮想ネットワークモジュール】variable.tf

/*リソースグループ*/
variable “rg-name" {}
variable “rg-location" {}

/*仮想ネットワーク*/
variable “subnet-name" {}
variable “vnet-name" {}

【仮想ネットワークモジュール】output.tf

output “terraform-test-subnet_id" {
  value = azurerm_subnet.terraform-test-subnet.id
}

仮想マシンをモジュール化

モジュール化の進め方に基づき作成した仮想マシンの構成ファイルです。
リソースグループやsubnet_idの引数は各モジュールのOutput値を利用しています。

設定ファイル

【ルートモジュール】vf-01.tf

module “rg" {
  source      = “./modules/rg"
  rg-name     = “terraform-rg"
  rg-location = “eastus2"
}

module “vnet" {
  source      = “./modules/vnet"
  rg-name     = module.rg.terraform-test-rg-name
  rg-location = module.rg.terraform-test-rg-location
  vnet-name   = “terraform-vent"
  subnet-name = “terraform-internal"
}

module “vm-01" {
  source         = “./modules/vm"
  rg-name        = module.rg.terraform-test-rg-name
  rg-location    = module.rg.terraform-test-rg-location
  nic-name       = “terraform-test-vm-1-nic"
  subnet_id      = module.vnet.terraform-test-subnet_id
  vm-name        = “terra-testvm-1"
  admin_username = “adminuser"
  admin_password = “P@$$w0rd1234!"
}

【仮想マシンモジュール】vm.tf

resource “azurerm_network_interface" “terraform-test-nif" {

  name                = var.nic-name
  location            = var.rg-location
  resource_group_name = var.rg-name

  ip_configuration {
    name                          = “internal"
    subnet_id                     = var.subnet_id
    private_ip_address_allocation = “Dynamic"
  }
}

resource “azurerm_windows_virtual_machine" “terraform-test-vm" {
  name                = var.vm-name
  resource_group_name = var.rg-name
  location            = var.rg-location
  size                = “Standard_B2ms"
  admin_username      = var.admin_username
  admin_password      = var.admin_password
  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" {}

/*ネットワークIF*/
variable “nic-name" {}
variable “subnet_id" {}

/*仮想マシン*/
variable “vm-name" {}
variable “admin_username" {}
variable “admin_password" {
    sensitive = true
}

デプロイ後の確認

Terraform Applyで仮想マシンをデプロイします。
デプロイ後にAzure Portal上で確認すると仮想マシンがデプロイされている事が分かります。

仮想マシン作成結果

モジュールを利用して2台目の仮想マシンを作成する

追加で作成したファイルは1つだけ

モジュール化のメリットには再利用が容易な事があります。
モジュールの再利用を確認する為にもう1台仮想マシン(terra-testvm-2)を作成してみます。
追加で作成した構成ファイルはVM-02.tfのみです。その他のファイルは何も変更していません。

ディレクトリ構成
 

ディレクトリ: C:\terraform\module_test

Mode LastWriteTime Length Name
—- ————- —— —-
d—– 2022/05/28 17:01 modules
-a—- 2021/05/07 17:17 131 main.tf
-a—- 2021/05/07 17:17 40 provider.tf
-a—- 2021/05/07 17:10 46 version.tf
-a—- 2022/05/29 10:36 658 VM-01.tf
-a—- 2022/05/29 10:36 333 VM-02.tf

作成した構成ファイル

作成したVM-02.tfになります。
同じモジュール名は利用できない為vm-2としています。
設定しているのは引数のみでリソースブロックは何も指定してません。

構成ファイル
module “vm-2" {
  source         = “./modules/vm"
  rg-name        = module.rg.terraform-test-rg-name
  rg-location    = module.rg.terraform-test-rg-location
  nic-name       = “terraform-test-vm-2-nic"
  subnet_id      = module.vnet.terraform-test-subnet_id
  vm-name        = “terra-testvm-2"
  admin_username = “adminuser"
  admin_password = “P@$$w0rd1234!"
}

デプロイ後の確認

Terraform Applyで仮想マシン2をデプロイします。
デプロイ後にAzure Portal上で確認すると仮想マシン2がデプロイされている事が分かります。
モジュール化する事でリソースブロックを都度指定する事無く再利用できる事が分かりました。

仮想マシン作成結果

最後に

今回はAzure仮想マシンを例にモジュール化を試してみました。
同じようなリソースを作成する場合にModuleを作成しておくと、ルートモジュールで変数を定義するだけで非常に簡単にデプロイ出来る事が分かりました。
モジュール化は環境単位で分けたり色々活用できるそうです。Terraform について今後も色々試してみたい所です。

Terraform関連の記事一覧はこちらになります。併せて見て頂けると大変有難いです。 

Terraform 記事一覧