组合“count”和“for_each”是不可能的

问题描述 投票:0回答:3

这是我的代码来源

resource "aws_s3_bucket_object" "object" {
  count               = var.s3_create[1] ? 1 : 0 
  depends_on          = [aws_s3_bucket.bucket_backup]
  for_each            = local.buckets_and_folders 
    bucket            = each.value.bucket_backup
    key               = format("%s/", each.value.folder)
  force_destroy       = true
} 

换句话说,我正在尝试创建对象

aws_s3_bucket_object
取决于变量
s3_create
...如果为true则创建,否则不创建。

问题:我无法在创建 terraform 资源时使用以下语法的组合,我明白了:

Error: Invalid combination of "count" and "for_each"
│
│   on ..\s3\resources.tf line 51, in resource "aws_s3_bucket_object" "object":
│   51:   for_each            = local.buckets_and_folders
│
│ The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.
terraform terraform-provider-aws
3个回答
23
投票

count 和 for_each 都适用于整个块。在 for_each 下面缩进行不会影响任何东西,只会影响人类可读性。

尝试使用三元运算符与 for_each 而不是计数。如果值为 false,则返回空集。

resource "aws_s3_bucket_object" "object" {
  for_each       = var.s3_create[1] ? tomap({local.buckets_and_folders}) : {}
  bucket         = each.value.bucket_backup
  key            = format("%s/", each.value.folder)
  depends_on     = [aws_s3_bucket.bucket_backup]
  force_destroy  = true
} 

3
投票

for_each
的规则是您应该为其分配一个映射或集合,其元素数量与您要声明的实例数量相同。

从这个角度考虑您的目标,解决方案将涉及在您不想声明任何实例的情况下使您的地图为空。从集合中过滤元素的典型方法是使用

an 
for 子句
编写 [a 
if
表达式]。

从您在示例中分享的内容来看,我无法判断

local.buckets_and_folders
是地图还是一组字符串,因此我将展示两者的示例...

如果是地图:

  for_each = tomap({
    for k, v in local.buckets_and_folders : k => v
    if var.s3_create[1]
  })

如果是一套:

  for_each = toset([
    for v in local.buckets_and_folders : v
    if var.s3_create[1]
  ])

在这两种情况下,

if
子句意味着如果
var.s3_create[1]
为假,结果将是一个空集合。

可能还有其他方法来设计模块,以便输入和派生表达式可以更简单,但是在您上面分享的相对有限的示例中工作是对您的问题的最直接答案。如果您想讨论简化此操作的可能方法,您可以在 Stack Overflow 上提出一个新问题,并包含当前代码的更完整示例以及该模块旨在满足的基本要求。


0
投票

可以在 terraform 资源块中组合“count”和“for_each”

但你必须对此保持“活力”

这是我已经到位(和正在工作)的示例

resource "azurerm_network_security_group" "nsg-001" {
count               = var.nsg-deploy.deploy ? 1 : 0

dynamic "security_rule" {
    for_each = local.nsg_001_ruleset_001
    content {}
}

干杯

-=A=-

.

© www.soinside.com 2019 - 2024. All rights reserved.