简体   繁体   中英

Terraform for_each variable to create multiple AWS listener rules and set a unique target_group_arn

I'm trying to work out an aws container setup with terraform that routes traffic from my ALB to target groups based on specific ports using terraforms for_each option. I have a for_each setup that's creating the listener rules I'd expect based on my variable

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

I'm not sure if it's possible to get the for_each resource to use a unique target_group_arn in the listener rule that would be created by a similar for_each setup of the target group I'm using. I'm also not sure if this is the best way to go about accomplishing this goal. I could create each resource but in the end I'll be looking at about 30 separate listeners and target groups so I'm seeing if I can figure out a way to make use of a single variable that handles the resource creation.

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/*"]
  }
}

Initially I was thinking I could try and use output values from the target group and add them into my variables but that doesn't seem possible. Aside from that I'm still trying to think of a way this could work.

I've spent half the day looking at work arounds but haven't found anything useful. If anyone has any resources or ideas, they would be very helpful.

Edit: without the for_each each listener and target would look like this

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

What I understood from the question is that there should be one target group and one listener rule per element of var.tenant_data , and that each listener rule should refer to the corresponding target group.

By using for_each with both of these resources, they will both end up with instances identified by the same keys, and so you can make cross-references using each.key , like this:

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/*"]
  }
}

The key part of the above is here, for emphasis:

    target_group_arn = aws_alb_target_group.tenant[each.key].arn

Because both of these resource blocks have the same for_each , we can use each.key to cross-reference, looking up the single target group corresponding to each listener rule.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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