自由気ままに書いちゃおう

好きなことをつらつらと・・・

【Terraform】(初心者向け)for_eachの使い方(実例つき)

terraformのfor_eachについてです。

 

■ for_eachとは(公式サイト)

The for_each Meta-Argument - Configuration Language | Terraform | HashiCorp Developer

上記を読んでも私はピンとこない。。。
そのため、備忘を兼ねなるべくわかりやすく書いてみようと思います。

■ for_eachとは(toset利用時)

for_eachを使うのは繰り返し処理を行うときです。

例えば、

① 10.20.0.0/16

② 10.30.0.0/16

③ 10.40.0.0/16

④ 10.50.0.0/16

の4つのVPCを作成する場合、

resource "aws_vpc" "vpc1" {}
resource "aws_vpc" "vpc2" {}
resource "aws_vpc" "vpc3" {}
resource "aws_vpc" "vpc4" {}

のように4つ書くのは少し辛いです。

 

なので、以下の通りlocals変数に4つ分を定義しておき

locals {
  vpcs_list = ["10.20", "10.30","10.40","10.50"]
}

VPC作成部分は以下の通り記載します。

resource "aws_vpc" "vpcs_list" {
  for_each   = toset(local.vpcs_list)
  cidr_block = "${each.key}.0.0/16"
}

 

こうすることで、4つ分のVPCを作成できます。

※ toset とか each.key については後述致します。

■ toset 、 each.key について

さきほど以下の通りtosetとeach.keyを使っていますが、その説明です。

resource "aws_vpc" "vpcs_list" {
  for_each   = toset(local.vpcs_list)
  cidr_block = "${each.key}.0.0/16"
}

■ toset について

ここも最初は少しわかりづらいところだと思います。

for_eachを利用する際、for_eachが受け取れる値は「map」か「set」のみです。

※「map」については後述

locals変数でvpcs_list というリストを指定している為、

locals {
  vpcs_list = ["10.20", "10.30","10.40","10.50"]
}

toset関数(リスト形式をset形式に変換する関数)を使っています。

toset - Functions - Configuration Language | Terraform | HashiCorp Developer

これにより、はじめてfor_eachで処理できる形になるということです。

■ each.key について

for_eachで受け取った値(ここでは、local.vpcs_listをセットとして受け取った値)を使いたいときには、each.keyを使います。

こちらも少しわかりづらいですが、、、

for_eachの値をtosetで受け取った場合には、

each.key も each.value も同じ値となります。(key , valueのどちらを使っても構いません。お好みで!)

resource "aws_vpc" "vpcs_list" {
  for_each   = toset(local.vpcs1_list)
  cidr_block = "${each.key}.0.0/16"
}

そのため、上記${each.key} は ${each.value}と書いてもOKです。

※key, valueを使い分ける必要があるのは、for_eachをmapで受け取った時です。後述します。

  cidr_block = "${each.key}.0.0/16"

の通り、${each.key} には

① 10.20

② 10.30

③ 10.40

④ 10.50

が代入されます。

 

■ for_eachとは(map利用時)

今までは、list形式の値をfor_eachに渡してましたがmapも渡せます。

tosetの時に説明している内容と重複する箇所は割愛しますが、今回利用するコードは以下のものです。

locals {
  vpcs1_list = ["10.20", "10.30"] # こっちはtoset用
  vpcs2_map = {   # こっちはMap用
    "dev" = "10.40"
    "stg" = "10.50"
  }
}

resource "aws_vpc" "vpcs1_list" {  # こっちはtoset利用時
  for_each   = toset(local.vpcs1_list)
  cidr_block = "${each.key}.0.0/16"
}

resource "aws_vpc" "vpcs2_map" {   # こっちはMap利用時
  for_each   = local.vpcs2_map
  cidr_block = "${each.value}.0.0/16"

  tags = {
    "Name" = "${each.key}"
  }
}

 

for_each(toset利用時)の内容がわかると、for_each(map利用時)もすんなり理解できるかと。

あえて説明するとすれば、

each.key と each.valueのところぐらいだと思います。

locals {
  vpcs1_list = ["10.20", "10.30"]
  vpcs2_map = {
    "dev" = "10.40"
    "stg" = "10.50"
  }
}

vpcs2_mapでは、マップ形式でlocal変数を定義しています。

for_eachにマップ形式を渡す際には、

resource "aws_vpc" "vpcs2_map" {
  for_each   = local.vpcs2_map

のように

    "dev" = "10.40"
    "stg" = "10.50"

上記部分の記載は不要です。

each.key , each.valueがどの部分に該当するかは以下を参照ください。

 

以上です。