我正在尝试在 terraform 中使用嵌套循环。我有两个列表变量list_of_allowed_accounts
and list_of_images
,并希望遍历 list list_of_images
,然后遍历 list list_of_allowed_accounts
。
这是我的地形代码。
variable "list_of_allowed_accounts" {
type = "list"
default = ["111111111", "2222222"]
}
variable "list_of_images" {
type = "list"
default = ["alpine", "java", "jenkins"]
}
data "template_file" "ecr_policy_allowed_accounts" {
template = "${file("${path.module}/ecr_policy.tpl")}"
vars {
count = "${length(var.list_of_allowed_accounts)}"
account_id = "${element(var.list_of_allowed_accounts, count.index)}"
}
}
resource "aws_ecr_repository_policy" "repo_policy_allowed_accounts" {
count = "${length(var.list_of_images)}"
repository = "${element(aws_ecr_repository.images.*.id, count.index)}"
count = "${length(var.list_of_allowed_accounts)}"
policy = "${data.template_file.ecr_policy_allowed_accounts.rendered}"
}
这相当于我正在尝试做的事情。
for image in alpine java jenkins
do
for account_id in 111111111 2222222
do
// call template here using variable 'account_id' and 'image'
done
done
Terraform 没有直接支持这种嵌套迭代,但我们可以用一些算术来伪造它。
由于我们要为帐户和图像的每个组合创建一个策略模板,
count
因此template_file
数据块上的 是两者相乘。然后,我们可以使用除法和模运算来返回count.index
每个列表的单独索引。由于我没有您的策略模板的副本,因此我只使用了占位符;因此,这种配置给出了以下计划:
每个策略实例适用于不同的帐户 ID 和图像对,涵盖所有组合。
这里的答案确实有效(我最初使用它们),但我认为使用 Terraform 的setproduct函数有更好的解决方案。我还没有看到很多它在互联网上使用的例子,但是 setproduct 需要两个集合(或更重要的是,两个列表)并生成一个包含每个输入排列的集合列表。就我而言,我正在创建 SSM 参数:
这将创建名为:
我的小脑袋可以比其他答案中的模魔法更容易地解析这个!
仅供参考,如果有人从谷歌来这里,如果你使用的是 terraform 0.12,你将需要在你做划分的任何地方使用 floor 函数,否则你会收到关于部分索引的错误。
虽然在某些情况下使用setproduct和使用模数的解决方案有效,但还有一个更优雅的解决方案:使用terraform 模块(不要与模运算符混淆)。通过使用 terraform 模块,出现了使用 count 元参数的额外机会。
如果不是所有输入组合都适用,则此解决方案特别有用。例如,我使用这个解决方案来处理一个项目列表,其中每个项目都有一个独特角色的列表。
例如,在顶层你可以使用这个:
../accounts
然后在包含此内容的目录中添加一个额外的 terraform 模块。我发现这种方法更容易理解。
基本上问题出在数据“template_file”中,无法按照您认为的方式设置 account_id,因为您的情况下的计数只是另一个永远不会增加/更改的 var。只是说因为我想看看你的问题到底是什么。
我没有足够的声誉点来为@Martin Atkins提供的答案添加评论,所以我发布了他的答案并稍作修改,这适用于Terraform 问题 20567