概要
Terraformで2つの配列間で重複したデータのみを変数に格納する方法をまとめます。
事前実装される関数による実装
@rakiさんからいただいたコメントのほうがスマートでしたので、そちらを掲載させていただきます。ご助言ありがとうございました!
locals {
dataset_a = ["Apple", "Grape", "Orange"]
dataset_b = ["Apple", "Orange"]
}
output "all" {
value = [local.dataset_a, local.dataset_b]
}
output "dup" {
value = [setintersection(local.dataset_a, local.dataset_b)]
}
output "unique" {
value = [setsubtract(local.dataset_a, local.dataset_b)]
}
転置による実装
以下のように実装すると2つの配列に登録されたデータのうち重複したデータのみを絞り込むことが可能です。
locals {
dataset_a = ["Apple","Grape", "Orange"]
dataset_b = ["Apple","Orange"]
result = [ for k,v in transpose({foo=local.dataset_a, bar=dataset_b}): k if length(v)==2]
}
$ echo "local.result" | terraform console
[
"Apple",
"Orange",
]
簡単な動作の説明をします
transpose関数はmapのKeyとValueを入れ替える動きをします。 https://developer.hashicorp.com/terraform/language/functions/transpose
そのため、処理前はKeyに"foo"と"bar"が入っていましたが、処理後はKeyに"Apple"や"Grape"、"Orange"が格納され、Valuleに"foo"と"bar"が格納されるようになります。
したがって、処理後のValueの要素数が2になっているKeyについてはデータが重複していると判断できます。
応用例
重複したいデータを排除したい場合の例を以下記載します。
以下の例ではresultの判定部分をlength(v)==1 && !contanis(v, "bar")]
に変更しています。
これにより、要素数が1(片方の変数のみにしか値が存在しない)かつdataset_bにはデータが存在していないことを確認し、結果的にdataset_aのみに含まれるデータを保存しています。
locals {
dataset_a = ["Apple","Grape", "Orange"]
dataset_b = ["Apple","Orange"]
result = [ for k,v in transpose({foo=local.dataset_a, bar=dataset_b}): k if length(v)==1 && !contains(v, "bar")]
}
$ echo "local.result" | terraform console
[
"Grape",
]
まとめ
このページでは重複したデータのみ、あるいは重複していないデータのみを保存する方法をまとめました。
この記法を利用すると例えばGoogleCloudでのCustomRole作成時にある特定のPermissionは確実に除外するようことが可能になります。ガバナンスを効かせたい場合などにうまく活用可能です。
# custom_roleモジュール側でxx.xx.setIamPolicyを除外するように設定
module "foo_custom_role"{
source = "../modules/project/iam/custom_role"
name = "foo_custom_role"
permissions = ["xx.xx.get","xx.xx.setIamPolicy"]
}
Terraformでは事前に提供される便利な関数が複数存在するため、うまく活用して管理しやすいコードを作っていきましょう!