繁体   English   中英

Terraform 带 for_each 的条件数量

[英]Terraform conditional quantity with for_each

我需要一个带有 for_each 的 if 语句。 如果是非生产,则在单个 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
...

我得到一个错误:

|----------------
    | 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.

我试过这个:

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

并且出现类似的错误:

|----------------
    | 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.

尝试更改类型但似乎没有任何效果

我建议稍微修改局部变量,以便您可以根据环境使用它们,例如:

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
    }
  }
}

然后,在模块调用中,您将执行以下操作:

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

或者,您仍然可以使用相同的局部变量,但将其调整为类似以下内容:

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
...

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需要一个 map,其中每个要声明的实例都有一个元素。 这意味着如果您只想声明一个实例,那么您需要生成一个单元素 map。

这是一种方法:

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

这是可行的,因为条件的两个分支都会产生 map 个对象。 true的 arm 产生单个元素 map,而第二个产生整个原始 map。

避免内联 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)

  # ...
}

此处的try function 调用意味着local.all_zones是在local.env_zonesvar.env_name中的键之一不匹配时使用的回退。

暂无
暂无

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

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