Terraform 嵌套循环 for.each 示例

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

我正在尝试创建嵌套循环来迭代每个环境(dev、qa、uat),并为与每个环境关联的目标 IP 构建目标组附件。

这是我到目前为止所拥有的:

variable "qlink_target_ids" {
  type    = map(list(string))
  default = {
    dev = ["10.10.10.10", "10.10.10.20"]
    qa  = ["10.100.10.101"]
    uat = ["10.105.10.106", "10.10.10.217", "10.100.10.201"]
  }
}

variable "environments" {
  type    = set(string)
  default = ["dev", "qa", "uat"]
}
resource "aws_lb_target_group_attachment" "nlb_to_tg_qlink_attachments" {
  for_each           = { for env in var.environments : env => var.qlink_target_ids[env][0] }
  target_group_arn  = aws_lb_target_group.nlb_qlink_target_groups[each.key].arn
  target_id         = each.value
  availability_zone = "all"
  port              = 10001
}

但是,我遇到一个问题,它只分配 target_ids 中的第一个 IP,并且不会迭代循环来处理每个环境的 target_ids 中的所有 IP。 target_id 属性只接受字符串而不接受列表,这使情况变得复杂。

我尝试了几种方法来解决此问题,包括使用动态块来迭代每个 IP,但我遇到了错误,表明需要 target_id 属性。

任何有关如何解决此问题的见解或建议将不胜感激。谢谢!

尝试#1

resource "aws_lb_target_group_attachment" "nlb_to_tg_qlink_attachments" {
  for_each = {
    for env, ids in var.qlink_target_ids : env => ids
  }

  target_group_arn = aws_lb_target_group.nlb_qlink_target_groups[each.key].arn

  dynamic "attachment" {
    for_each = each.value

    content {
      target_id         = attachment.value
      availability_zone = "all"
      port              = 10001
    }
  }
}

错误:未指定必需的属性“target_id”:此处需要名为“target_id”的属性Terraform 意外的块:这里不需要“动态”类型的块Terraform

尝试#2

resource "aws_lb_target_group_attachment" "nlb_to_tg_postsql_attachments" {
  for_each = {
    for env, ids in var.postsql_target_ids : env => ids
  }

  target_group_arn  = aws_lb_target_group.nlb_postsql_target_groups[each.key].arn
  availability_zone = "all"
  port              = 10001

  dynamic "target_id" {
    for_each = each.value
    content {
      target_id = target_id.value
    }
  }
}

错误:未指定必需的属性“target_id”:此处需要名为“target_id”的属性

尝试#3

resource "aws_lb_target_group_attachment" "nlb_to_tg_qlink_attachments" {
  for_each = {
    for env, ids in var.qlink_target_ids : env => ids
  }

  target_group_arn = aws_lb_target_group.nlb_qlink_target_groups[each.key].arn

  dynamic "attachment" {
    for_each = each.value

    content {
      target_id         = attachment.value
      availability_zone = "all"
      port              = 10001
    }
  }
}

错误:未指定必需的属性“target_id”:此处需要名为“target_id”的属性

尝试#4

resource "aws_lb_target_group_attachment" "nlb_to_tg_postsql_attachments" {
  for_each = {
    for env, ids in var.postsql_target_ids : env => ids
  }

  target_group_arn  = aws_lb_target_group.nlb_postsql_target_groups[each.key].arn
  target_id         = each.value
  availability_zone = "all"
  port              = 5432
}

错误:╷ │ 错误:属性值类型不正确 │ │ 在 nlb.tf 第 149 行,资源“aws_lb_target_group_attachment”“nlb_to_tg_postsql_attachments”中: │ 149:target_id =each.value │ ├──────────────── │ │ every.value 是包含 2 个元素的字符串列表 │ │ 属性“target_id”的值不合适:需要字符串。

terraform nested-loops terraform-provider-aws foreach-loop-container
1个回答
0
投票
  • 首先,我觉得你同时处理所有环境很奇怪。理想情况下,您应该运行 terraform plan 并一次申请一个环境。例如,
    terraform plan -var 'environment=dev'
    ,您可以修改类似于以下的资源块
resource "aws_lb_target_group_attachment" "nlb_to_tg_qlink_attachments" {
  count             = length(lookup(var.qlink_target_ids, var.environment))
  target_group_arn  = aws_lb_target_group.nlb_qlink_target_groups[var.environment].arn
  target_id         = element(lookup(var.qlink_target_ids, var.environment), count.index)
  availability_zone = "all"
  port              = 10001
}
  • 其次,要回答您的原始查询,一种方法是反转地图并在其上运行 for_each 。这是代码:
resource "aws_lb_target_group_attachment" "nlb_to_tg_qlink_attachments" {
  for_each          = merge([
    for env, ips in var.qlink_target_ids : {
      for ip in ips : ip => env
    }
  ]...)
  target_group_arn  = aws_lb_target_group.nlb_qlink_target_groups[each.value].arn
  target_id         = each.key
  availability_zone = "all"
  port              = 10001
}

for_each 循环中的表达式将生成如下所示的映射

{
  "10.10.10.10"   = "dev"
  "10.10.10.20"   = "dev"
  "10.100.10.101" = "qa"
  .....
  .....
}
© www.soinside.com 2019 - 2024. All rights reserved.