4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

記事投稿キャンペーン 「2024年!初アウトプットをしよう」

【Terraform】変数でよく見るmap(object)って?

Posted at

よく変数の定義でmap(object())となっているのを見るので、どういうことなのかを調べた結果を共有。

結論

Object型で構造化した変数を、mapでコレクションとして扱っている。このようにすることで変数の管理がしやすくなり、少ない記述でたくさんのリソースを一気にプロビジョニングできる。

前提

oci_core_instance(https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance)
の一部で説明。

Objectを用いないとどうなるか

Objectを用いず変数を羅列すると、variables.tfは以下のようになる。

variable "availability_domain" {
  type = string
}
variable "display_name" {
  type = string
}
variable "shape" {
  type = string
}
variable "source_details_source_type" {
  type = string
}
variable "source_details_source_id" {
  type = string
}
variable "create_vnic_details_assign_public_ip" {
  type = bool
}
variable "create_vnic_details_subnet_id" {
  type = string
}
variable "shape_config_baseline_ocpu_utilization" {
  type = string
}
variable "shape_config_memory_in_gbs" {
  type = string
}
variable "shape_config_ocpus" {
  type = string
}
variable "metadata_ssh_authorized_keys" {
  type = string
}
variable "metadata_user_data" {
  type = string
}

たくさんの変数が羅列されており、どの変数とどの変数が関連するものかがぱっと見でわかりにくく、管理が難しくなる。

Objectを用いると...

上記のような変数たちを、Objectを用いて書き直すと以下のようにできる。

variable "instances" {
  type = object({
    availability_domain = string
    display_name        = string
    shape               = string
    source_details = object({
      source_id = string
    })
    create_vnic_details = object({
      assign_public_ip = bool
      subnet_id        = string
    })
    shape_config = object({
      baseline_ocpu_utilization = string
      memory_in_gbs             = string
      ocpus                     = string
    })
    metadata = object({
      ssh_authorized_keys = string
      user_data           = string
    })
  })
}

これで、各変数がどういった値なのかがぱっと見でわかるようになった。

mapを用いないとどうなるか

ではこの状態でインスタンスを二つプロビジョニングすることを考えてみる。すると、下記のようにvariables.tfを書く必要がある。

variable "instance1" {
  type = object({
    availability_domain = string
    display_name        = string
    shape               = string
    source_details = object({
      source_id = string
    })
    create_vnic_details = object({
      assign_public_ip = bool
      subnet_id        = string
    })
    shape_config = object({
      baseline_ocpu_utilization = string
      memory_in_gbs             = string
      ocpus                     = string
    })
    metadata = object({
      ssh_authorized_keys = string
      user_data           = string
    })
  })
}
variable "instance2" {
  type = object({
    availability_domain = string
    display_name        = string
    shape               = string
    source_details = object({
      source_id = string
    })
    create_vnic_details = object({
      assign_public_ip = bool
      subnet_id        = string
    })
    shape_config = object({
      baseline_ocpu_utilization = string
      memory_in_gbs             = string
      ocpus                     = string
    })
    metadata = object({
      ssh_authorized_keys = string
      user_data           = string
    })
  })
}

これでは明らかに冗長になっている。

mapを用いると...

上記の冗長な変数を、mapを用いてきれいに書き直してみる。

variable "instances" {
  type = map(object({
    availability_domain = string
    display_name        = string
    shape               = string
    source_details = object({
      source_id = string
    })
    create_vnic_details = object({
      assign_public_ip = bool
      subnet_id        = string
    })
    shape_config = object({
      baseline_ocpu_utilization = string
      memory_in_gbs             = string
      ocpus                     = string
    })
    metadata = object({
      ssh_authorized_keys = string
      user_data           = string
    })
  }))
}

変数の定義はObject型の定義にmap()を追加するだけでOK。変数の中身を設定するときは、以下のように設定できる。

instances = {
  instance01 = {
    availability_domain = ....
    display_name = ....
    shape = ....
    source_details = {
      source_id = ....
      source_type = ....
    }
    shape_config = {
      baseline_ocpu_utilization = ....
      memory_in_gbs = ....
      ocpus = ....
    }
    metadat = {
      ssh_authorized_keys = ....
      user_data = ....
    }
  }
  instance02 = {
    #同様に記述
  }
}

このようにすることで、モジュールを呼び出すときは、以下のように呼び出せる。

module "instance" {
 source         = #モジュールの場所
 compartment_id = #各モジュール共通の変数は切り出す
 instances      = var.instances
}

このように、モジュール呼び出しの部分が非常にシンプルに記述できる。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?