🐯
Terraformで条件分岐とループ処理(count, for_each)
はじめに
Terraformではリソースに対してcountで条件分岐やfor_eachでループ処理のようなものができる。
ただし、countやfor_eachはメタ要素(Terraformリソースにあたえる要素)なので、if文やfor文のように書くことはできないことに注意!
Terraformリソースに真偽値やループ要素を渡すとよしなにリソースを作ってくれるイメージ
countによる条件分岐
名前からして、ループ処理を行いそうで実際にループも行えるが、for_eachがあるため主に条件分岐に使う
-
countが0のとき、リソースを作らない -
countが1のとき、リソースを作る
main.tf
variable "region" {
default = "ap-northeast-1"
}
resource "aws_iam_user" "account" {
count = var.region == "ap-northeast-1" ? 1 : 0
name = "account"
}
プラン結果
# aws_iam_user.account[0] will be created
+ resource "aws_iam_user" "account" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "account"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
countによるループ処理
resourceかmodule内でcountに数値を渡すことで可能
要素のインデックスはcount.indexでアクセスできる
main.tf
resource "aws_iam_user" "accounts-by-count" {
count = 4
name = "account-${count.index}"
}
terraform内でのリソース名はaws_iam_user.accounts-by-count[0]のようになる
プラン結果
# aws_iam_user.accounts-by-count[0] will be created
+ resource "aws_iam_user" "accounts-by-count" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "account-0"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
...省略...
# aws_iam_user.accounts-by-count[3] will be created
+ resource "aws_iam_user" "accounts-by-count" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "account-3"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
for_eachによるループ処理
terraformリソースに、ループ要素を渡すイメージ
1重ループしかできない(多重ループは後述)
resourceかmodule内でfor_eachにmapまたはsetを渡すことで可能
渡した要素のキーはeach.key、値はeach.valueでアクセスできる
(setの場合、キーと値は同じものとなる)
listはそのままでは渡せないので、toset()を用いる
main.tf
resource "aws_iam_user" "accounts-by-foreach" {
for_each = toset(["Todd", "James", "Alice", "Dottie"])
name = each.key
}
terraform内でのリソース名はaws_iam_user.test-accounts["Todd"]のようになる
プラン結果
# aws_iam_user.accounts-by-foreach["Alice"] will be created
+ resource "aws_iam_user" "accounts-by-foreach" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "Alice"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
# aws_iam_user.accounts-by-foreach["Dottie"] will be created
+ resource "aws_iam_user" "accounts-by-foreach" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "Dottie"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
...省略...
リストlistをローカル変数にすることもできます
main.tf
locals {
list=["Todd", "James", "Alice", "Dottie"]
}
resource "aws_iam_user" "accounts-by-foreach" {
for_each = toset(local.list)
name = each.key
}
for_eachによる多重ループ処理
moduleの中でfor_eachを使い、さらにresourceの中でfor_eachを使う
main.tf
locals {
list = {
"group_A" = ["Todd", "James", "Alice"],
"group_B" = ["Todd", "Dottie"]
}
}
module "module-for-accounts" {
for_each = local.list
source = "./module"
group = each.key
name_list = each.value
}
module/iam.tf
variable "group" {
type = string
}
variable "name_list" {
type = list(string)
}
resource "aws_iam_user" "accounts-by-module" {
for_each = toset(var.name_list)
name = "${var.group}-${each.key}"
}
プラン結果
...省略...
# module.module-for-accounts["group_A"].aws_iam_user.accounts-by-module["Todd"] will be created
+ resource "aws_iam_user" "accounts-by-module" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "group_A-Todd"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
...省略...
# module.module-for-accounts["group_B"].aws_iam_user.accounts-by-module["Dottie"] will be created
+ resource "aws_iam_user" "accounts-by-module" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "group_B-Dottie"
+ path = "/"
+ tags_all = (known after apply)
+ unique_id = (known after apply)
}
...省略...
参考
Discussion