Terraformのmoduleでcount/for_eachが使えない問題

またTerraformのはなし。環境は Terraform v0.12.24 です。

count and for_each for modules · Issue #17519 · hashicorp/terraform“にある通り、いまのところ count, for_each を用いて複数の module セクションを定義することはできない。 これをどうにかしたい。

問題の概要

いまのところ count, for_each を用いて複数の module セクションを定義することはできない。これをどうにかしたい。

私の場合は module でループを使いたいのはリソースの間に 1:n の対応があるような階層的なイテレーションを行いたかったからでした。 たとえば下のような変数を使って2種類のリソース(クラスタとプール)を定義したいときがある。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
locals {
    specs = [
        {
            cluster_name = "name_a",
            pool = [
                { type = "small" },
                { type = "big" },
            ]
        }
    ]
}

クラスタの定義は count, for_each の利用で素直に解決できる。

問題はプール側で単純に count は使えない。 全てのプールを flatten() を使いつつ count しても嬉しくない。 名前は外側の値を使いたいため。で、ここでプール定義を module に分離して specs[count.index].pool を渡すようなことをしたくなっていた。

最初に書いたけどこれは今のところできない。なのでこれを解決する。

解決策の概要

問題の説明で整理したことで、解決策はほぼ自明になった。 flatten() 関数を使うときに必要な値をまとめれば良い。

この対処はモジュール内から出したくないので locals セクションを使う。 リスト内包表記でリストのリストを作って flatten() 関数で平滑化する。

ちなみに for で得られた値のインデックス値は index() 関数で取得できる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
locals {
  pools = flatten([
    for s in var.example :
    [ for p in s.pool : {
      location: s.cluster,
      pool_id: index(s.pool, p),
      machine_type: p.type,
    } ]
  ])
}

めでたしめでたし。

comments powered by Disqus