Terrraformの定義ファイルで繰り返し処理と型を使用する

Terraformでは、繰り返し処理を使用することで、1つのブロックでまとめて複数のリソースを作成することが可能です。

繰り返し処理を使用しない場合、リソースの数だけブロックを作成しないといけなくなり、管理が大変になります。

今回は、繰り返し処理(メタ引数)と型(map)を使用して解決していきます。

メタ引数

メタ引数の種類は複数あり、利用用途によって使い分けをします。Terraformで利用できるメタ引数は以下の通りです。

※ 依存関係を処理するdepends_onもメタ引数の一種です。

今回は、そんなメタ引数の一種であるfor_eachを使用していきます。for_eachは全リソースタイプで使用可能です。

developer.hashicorp.com

Terraformでは、リソースを作成しようと思えばするほど定義ファイル・変数ファイル共に長くなってしまいますが、型を使用することで整理が可能です。

今回はmapを使用して、変数ファイルを作成します。 developer.hashicorp.com

定義ファイル記載例

main.tf

プロバイダー情報、作成先サブスクリプション、状態格納用ストレージを記載します。

provider "azuread" {
  subscription_id = var.subscription_id
  tenant_id       = var.tenant_id
}

# Azure Provider
terraform {
  required_providers {
    azuread = {
      source  = "hashicorp/azuread"
      version = "~>3.110.0"
    }
  }

  # Store Terraform state in Azure Storage
  backend "azurerm" {
    resource_group_name  = "状態格納用ストレージアカウントがあるリソースグループ名"
    storage_account_name = "ストレージアカウント名"
    container_name       = "BLOBコンテナー名"
    # Statment File Name
    key = "任意のファイル名"
  }
}

variables.tf

定義ファイル内で使用するリソース名、変数を指定します。

#-------------------------------
# 基本変数定義
#-------------------------------

# サブスクリプション
variable "subscription_id" {}

# テナントID
variable "tenant_id" {}

#-------------------------------
# Resource Group
#-------------------------------

# Resource Group Name01
variable "resource_groups" { 
  description = "Deploy 3 Resource Groups"
  type = map(any) #map(any)を指定することで自動的に最適な型をセットする
  default = {
    rg1 = { #リソース毎にまとめる
      name     = "test-rg01" 
      location = "Japan East"
    }
    rg2 = {
      name     = "test-rg02"
      location = "Japan East"
    }
    rg3 = {
      name     = "test-rg03"
      location = "Japan East"
    }
  }
}

rg.tf

変数ファイルで指定したリソースグループを定義します。 既定の記載方法で上記のリソースを作成する場合は、リソースブロックが3つ必要ですが、1つでまとまっています。

#-------------------------------
# Resource Group
#-------------------------------

# Resource Group - ACR Japan East
resource "azurerm_resource_group" "rg1-3" {
  for_each = var.resource_groups #どの変数を使用するか指定
  name     = each.value.name  
  location = each.value.location
}

Terraform実行

定義が完了したので、Terrformを実行していきます。 terraform initを実行し、初期化していきます。

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Using previously-installed hashicorp/azurerm v3.110.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

terraform planを実行し、エラーがないことを確認します。

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.rg1-3["rg1"] will be created
  + resource "azurerm_resource_group" "rg1-3" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "test-rg01"
    }

  # azurerm_resource_group.rg1-3["rg2"] will be created
  + resource "azurerm_resource_group" "rg1-3" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "test-rg02"
    }

  # azurerm_resource_group.rg1-3["rg3"] will be created
  + resource "azurerm_resource_group" "rg1-3" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "test-rg03"
    }

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

───────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

terraform applyを実行し、リソースを作成します。

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.rg1-3["rg1"] will be created
  + resource "azurerm_resource_group" "rg1-3" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "test-rg01"
    }

  # azurerm_resource_group.rg1-3["rg2"] will be created
  + resource "azurerm_resource_group" "rg1-3" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "test-rg02"
    }

  # azurerm_resource_group.rg1-3["rg3"] will be created
  + resource "azurerm_resource_group" "rg1-3" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "test-rg03"
    }

Plan: 3 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_resource_group.rg1-3["rg3"]: Creating...
azurerm_resource_group.rg1-3["rg1"]: Creating...
azurerm_resource_group.rg1-3["rg2"]: Creating...
azurerm_resource_group.rg1-3["rg3"]: Creation complete after 9s [id=*****/*****/*****/resourceGroups/test-rg03]
azurerm_resource_group.rg1-3["rg2"]: Creation complete after 9s [id=*****/*****/*****/resourceGroups/test-rg02]
azurerm_resource_group.rg1-3["rg1"]: Creation complete after 10s [id=*****/*****/*****/resourceGroups/test-rg01]

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

リソースの確認

[リソースグループ]から対象リソースグループ名を検索し、作成されているか確認します。

実行結果

最後に

最後まで閲覧ありがとうございます。

実際にはAzure仮想マシンやネットワークインターフェースなどを複数作成するケースなどで有用な考え方となります。

この記事を見て、Terraformの処理や型に興味を持っていただければ幸いです。

執筆担当者プロフィール
佐藤 宏樹

佐藤 宏樹(日本ビジネスシステムズ株式会社)

クラウドソリューション事業本部に所属しています。主にMicrosoft Azureに携わっています。バイク乗りです。

担当記事一覧