如何将模块调用置于循环中并将列表的项传递给模块调用?我试过使用count和count。索引,但由于模块名称冲突而失败。模块名必须唯一
尝试使用for_each。我最近遇到了一个类似的挑战,for_each比count更适合我。
https://developer.hashicorp.com/terraform/language/meta-arguments/for_each
文档中的示例用法:
module "bucket" {
for_each = toset(["assets", "media"])
source = "./publish_bucket"
name = "${each.key}_bucket"
}
Terraform有一种声明性语言,所以它没有"循环"。从某种意义上说,您可能熟悉命令式编程语言。
但是,它确实有可能使用单个resource
或module
块声明资源或模块的多个实例,具有两个不同的变体:
for_each
为一个map值或一组字符串值的每个元素声明一个资源或模块实例。在这种情况下,将使用所提供的映射中的键或所提供的集合中的元素来跟踪实例。count
声明了特定数量的实例,这些实例不需要与另一个集合中的元素有任何关联。在这种情况下,实例将仅使用数字索引进行跟踪,类似于列表的元素。
下面是一个使用for_each
和module
块的人为示例:
variable "example" {
type = map(object({
thing_type = string
}))
}
module "example" {
source = "./modules/example"
for_each = var.example
thing_type = each.value.thing_type
}
如果将var.example
设置为以下值…
{
"a" = {
thing_type = "foo"
}
"b" = {
thing_type = "bar"
}
}
…然后这将声明模块的两个实例:
module.example["a"]
withthing_type = "foo"
module.example["b"]
withthing_type = "bar"
注意,["a"]
和["b"]
成为模块实例的唯一地址的一部分,因此也是模块内声明的任何资源的唯一地址的一部分。如果你在地图上添加了一个新的元素"c"
,那么它会声明一个额外的模块实例,但是如果你改变了现有元素"b"
的thing_type
,那么Terraform会理解为改变已经存在的模块实例的配置,而不是声明一个新的。