Terraform for_each 变量用于创建多个 AWS 侦听器规则并设置唯一的 target_group_arn

Mil*_*erC 2 variables resources amazon-web-services amazon-elastic-beanstalk terraform

我正在尝试使用 terraform 制定 aws 容器设置,使用 terraforms for_each 选项根据特定端口将流量从 ALB 路由到目标组。我有一个 for_each 设置,它根据我的变量创建我期望的侦听器规则

variable "tenant_data" {
  type = "map"
  default = {
    tenant1 = {
      port              = 32768
      listener_priority = 986
      tenantName        = "tenant1"
    }
    tenant2 = {
      port              = 32769
      listener_priority = 987
      tenantName        = "tenant2"
    }
    tenant3 = {
      port              = 32770
      listener_priority = 988
      tenantName        = "tenant3"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我不确定是否可以让 for_each 资源使用target_group_arn侦听器规则中的唯一属性,该规则将由我正在使用的目标组的类似 for_each 设置创建。我也不确定这是否是实现这一目标的最佳方式。我可以创建每个资源,但最终我将查看大约 30 个独立的侦听器和目标组,因此我想看看是否可以找到一种方法来利用单个变量来处理资源创建。

resource "aws_alb_listener_rule" "java_dev" {
  for_each     = var.tenant_data
  listener_arn = data.terraform_remote_state.alb.outputs.alb_https_listener_arn
  priority     = each.value.listener_priority

  action {
    type             = "forward"
    target_group_arn = each.value.target_group_arn - what I'm trying to set
  }

  condition {
    field  = "host-header"
    values = ["${each.value.tenantName}.my-site.com"]
  }

  condition {
    field  = "path-pattern"
    values = ["/some-value/*"]
  }
}
Run Code Online (Sandbox Code Playgroud)

最初我想我可以尝试使用目标组的输出值并将它们添加到我的变量中,但这似乎不可能。除此之外,我仍在尝试想出一种可行的方法。

我花了半天时间寻找解决方法,但没有发现任何有用的东西。如果任何人有任何资源或想法,他们都会非常有帮助。

编辑:如果没有 for_each 每个侦听器和目标将如下所示

resource "aws_alb_listener_rule" "alpha3" {
  listener_arn = listener_arn
  priority     = 987

  action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.group.arn
  }

  condition {
    field  = "host-header"
    values = ["one.my-site.com"]
  }

  condition {
    field  = "path-pattern"
    values = ["/path/*"]
  }
}

# Target Group
resource "aws_alb_target_group" "group" {
  name        = "ct-tgt-grp"
  port        = 32769
  protocol    = "HTTP"
  vpc_id      = vpc_id
  target_type = "instance"

  health_check {
    interval            = 30
    port                = 5000
    protocol            = "HTTP"
    timeout             = 10
    healthy_threshold   = 3
    unhealthy_threshold = 5
    path                = "/health"
    matcher             = 200
  }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ins 5

我从问题中了解到的是, 的每个元素应该有一个目标组和一个侦听器规则var.tenant_data,并且每个侦听器规则应引用相应的目标组。

通过使用for_each这两个资源,它们最终都会得到由相同键标识的实例,因此您可以使用 进行交叉引用each.key,如下所示:

variable "tenant_data" {
  type = map(object({
    port              = number
    listener_priority = number
  }))
}

resource "aws_alb_target_group" "tenant" {
  for_each = var.tenant_data

  name        = "ct-${each.key}"
  port        = each.value.port
  protocol    = "HTTP"
  vpc_id      = var.vpc_id
  target_type = "instance"

  health_check {
    interval            = 30
    port                = 5000
    protocol            = "HTTP"
    timeout             = 10
    healthy_threshold   = 3
    unhealthy_threshold = 5
    path                = "/health"
    matcher             = 200
  }
}

resource "aws_alb_listener_rule" "tenant" {
  for_each = var.tenant_data

  listener_arn = var.listener_arn
  priority     = each.value.listener_priority

  action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.tenant[each.key].arn
  }

  condition {
    field  = "host-header"
    values = ["one.my-site.com"]
  }

  condition {
    field  = "path-pattern"
    values = ["/path/*"]
  }
}
Run Code Online (Sandbox Code Playgroud)

上面的关键部分在这里,强调一下:

    target_group_arn = aws_alb_target_group.tenant[each.key].arn
Run Code Online (Sandbox Code Playgroud)

由于这两个资源块具有相同的for_each,因此我们可以使用each.key交叉引用来查找与每个侦听器规则对应的单个目标组。