简体   繁体   English

Terraform 带 for_each 的条件数量

[英]Terraform conditional quantity with for_each

I need an if statement with for_each.我需要一个带有 for_each 的 if 语句。 If it is non-prod create resource in a single su.net, if production create resources in both su.nets:如果是非生产,则在单个 su.net 中创建资源,如果是生产,则在两个 su.net 中创建资源:

locals {
  zone_data = {
    a = {
      subnet_id = data.aws_cloudformation_export.subnet1.value
    }
    b = {
      subnet_id = data.aws_cloudformation_export.subnet2.value
    }
  }
}

module "batch_server" {
     for_each = var.env_name == "non-prod" ? local.zone_data.a : local.zone_data
...

I get an error:我得到一个错误:

|----------------
    | local.zone_data is object with 2 attributes
    | local.zone_data.a is object with 1 attribute "subnet_id"

The true and false result expressions must have consistent types.
The given expressions are object and object, respectively.

I tried this:我试过这个:

for_each = var.env_name == "non-prod" ? [local.zone_data.a] : [local.zone_data]

and am getting similar error:并且出现类似的错误:

|----------------
    | local.zone_data is object with 2 attributes
    | local.zone_data.a is object with 1 attribute "subnet_id"

The true and false result expressions must have consistent types.
The given expressions are tuple and tuple, respectively.

Tried changing types but nothing seems to work尝试更改类型但似乎没有任何效果

I would suggest reworking the local variables a bit so you can use them based on the environment, eg:我建议稍微修改局部变量,以便您可以根据环境使用它们,例如:

locals {
  non_prod = {
    a = {
      subnet_id = data.aws_cloudformation_export.subnet1.value
    }
  }
  prod = {
    a = {
      subnet_id = data.aws_cloudformation_export.subnet1.value
    }
    b = {
      subnet_id = data.aws_cloudformation_export.subnet2.value
    }
  }
}

Then, in the module call you would do the following:然后,在模块调用中,您将执行以下操作:

module "batch_server" {
     for_each = var.env_name == "non-prod" ? local.non_prod : local.prod
...

Alternatively, you could still use the same local variables, but adjust it to something like:或者,您仍然可以使用相同的局部变量,但将其调整为类似以下内容:

module "batch_server" {
     for_each = var.env_name == "non-prod" ? { for k, v in local.zone_data: k => v if k == "a" } : local.zone_data
...

How about a lookup with var.env_name as the key?var.env_name为键查找怎么样?

variable "env_name" {
  type = string
  default = "non_prod"
}

locals {
  zone_data = {
    prod = {
      a = {
        subnet_id = data.aws_cloudformation_export.subnet1.value
      }
      b = {
        subnet_id = data.aws_cloudformation_export.subnet2.value
      }
    },
    non_prod = {
      a = {
        subnet_id = data.aws_cloudformation_export.subnet1.value
      }
    }
  }
}

module "batch_server" {
     for_each = lookup(local.zone_data, var.env_name)
...

for_each expects a map with one element for each instance you want to declare. for_each需要一个 map,其中每个要声明的实例都有一个元素。 That means that if you want to declare only one instance then you need to produce a one-element map.这意味着如果您只想声明一个实例,那么您需要生成一个单元素 map。

Here's one way to do that:这是一种方法:

  for_each = var.env_name == "non-prod" ? tomap({a = local.zone_data.a}) : local.zone_data

This can work because both arms of the conditional produce a map of objects.这是可行的,因为条件的两个分支都会产生 map 个对象。 The true arm produces a single-element map while the second produces the whole original map. true的 arm 产生单个元素 map,而第二个产生整个原始 map。

Another option to avoid the inline map construction would be to factor out a per-environment lookup table into a separate local value:避免内联 map 构造的另一种选择是将每个环境的查找表分解为单独的本地值:

locals {
  all_zones = tomap({
    a = {
      subnet_id = data.aws_cloudformation_export.subnet1.value
    }
    b = {
      subnet_id = data.aws_cloudformation_export.subnet2.value
    }
  })
  env_zones = tomap({
    non-prod = tomap({
      for k, z in local.all_zones : k => z
      if k == "a"
    })
  })
}

module "batch_server" {
  for_each = try(local.env_zones[var.env_name], local.all_zones)

  # ...
}

The try function call here means that local.all_zones is the fallback to use if var.env_name doesn't match one of the keys in local.env_zones .此处的try function 调用意味着local.all_zones是在local.env_zonesvar.env_name中的键之一不匹配时使用的回退。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM