この記事はTerraform Advent Calendar 2021の11日目です。
これはなに
- Terraformのlist, map, objectの結合メソッドがいくつかあるので整理したい
for_each
で複数リソース良さげに作ろうとした際、この辺で格闘した思い出
結合系のメソッド
-
concat
- 複数のlistを結合して1つのlistにする
- https://www.terraform.io/docs/language/functions/concat.html
-
flatten
- 1つのlist内にあるlistの要素を全て同階層に並べる
- https://www.terraform.io/docs/language/functions/flatten.html
-
merge
- 複数のMap、Objectを結合して1つのMap、Objectにする
- https://www.terraform.io/docs/language/functions/merge.html
試す
terraform console
で対話モードに入って各メソッドの動作検証
concat
とflatten
基本的な使い方
> concat([0, 1, 2], ["a", "", "c"])
[
0,
1,
2,
"a",
"",
"c",
]
> flatten([[0, 1, 2], ["a", "", "c"]])
[
0,
1,
2,
"a",
"",
"c",
]
空のlistを結合するパターン
空のlistは結果に含まれない
> concat(["a", "b"], [], ["c"])
[
"a",
"b",
"c",
]
> flatten([["a", "b"], [], ["c"]])
[
"a",
"b",
"c",
]
多次元listを結合するパターン
concatは結果の要素にlistが含まれるが、flattenは含まれない
> concat(["a", "b"], [["ca", "cb"], [], ["da"]])
[
"a",
"b",
[
"ca",
"cb",
],
[],
[
"da",
],
]
> flatten([["a", "b"], [["ca", "cb"], [], ["da"]]])
[
"a",
"b",
"ca",
"cb",
"da",
]
merge
基本的な使い方
結果はkeyでソートされる
> merge({"b"="bb"}, {"a"="aa", "c"="cc", ""="dd"}, {"0"=00, "1"=11})
{
"" = "dd"
"0" = 0
"1" = 11
"a" = "aa"
"b" = "bb"
"c" = "cc"
}
ダブルクォートで囲んでないkeyを持つmap、objectが含まれるパターン
結果はkeyがダブルクォートで囲まれる
valueはそのまま
> merge({a="aa", b="bb"}, {1=11, 2=22})
{
"1" = 11
"2" = 22
"a" = "aa"
"b" = "bb"
}
空のmap, objectを結合するパターン
空のは結果に含まれない
> merge({"a"="aa", "b"="bb"}, {}, {"c"="cc"})
{
"a" = "aa"
"b" = "bb"
"c" = "cc"
}
重複keyの扱い
後続のkey, valueで上書きされていく(後続のものが優先される)
> merge({"a"="aa"}, {"a"="ab", "b"="bb"})
{
"a" = "ab"
"b" = "bb"
}
# keyにダブルクォートなしでも同じ
> merge({"a"="aa"}, {a="ab", "b"="bb"})
{
"a" = "ab"
"b" = "bb"
}
0の扱い
ダブルクォートで囲まないと不要な0は除去される
# 0が除去される
> merge({01=011}, {2=22, 3=33})
{
"1" = 11
"2" = 22
"3" = 33
}
# 0が除去されるので後続のkey, valueが優先される
> merge({01=011}, {1=12}, {2=22, 3=33})
{
"1" = 12
"2" = 22
"3" = 33
}
# 文字列扱いならば除去されない
> merge({"01"="011"}, {2=22, 3=33})
{
"01" = "011"
"2" = 22
"3" = 33
}