Home > Mobile >  Add multiple target group attachments using values from variables in terraform
Add multiple target group attachments using values from variables in terraform

Time:07-30

I am trying to create a target group and attach it to 2 instances. I was able to achieve this by using the below code.

locals {
  app_servers = {

    "server1" = "${aws_instance.server1.id}",
    "server2" = "${aws_instance.server2.id}"
    }

  resource "aws_lb_target_group" "internal" {
  name             = "internal-tg"
  port             = 9550
  protocol         = "HTTPS"
  vpc_id           = aws_vpc.main.id
  protocol_version = "HTTP1"

  health_check {
    healthy_threshold   = 5
    interval            = 15
    protocol            = "HTTPS"
    unhealthy_threshold = 2
    timeout             = 5
    matcher             = "200"
    path                = "/login"
  }

}

resource "aws_lb_target_group_attachment" "internal" {
  for_each         = local.app_servers
  target_group_arn = aws_lb_target_group.internal.arn
  port             = aws_lb_target_group.internal.port
  target_id        = each.value
}

Now I want to add many target groups and attach it to the same 2 instances. The properties that will change with each target group are name, port and matcher. I tried adding another variable as a map under locals like below

  locals {
  app_servers = {

    "server1" = "${aws_instance.server1.id}",
    "server2" = "${aws_instance.server2.id}"
    }

  target_groups = {
    "internal" = {
      port = 9550
      matcher = "200"
    },
    "dev1" = {
      port = 9152
      matcher = "302"
    },
    "sso" = {
      port = 9154
      matcher = "302"
    },
    "terra-test" = {
      port = 9360
      matcher = "200"
    }
  }

This doesn't seem to work. Need some guidance on how to achieve this. Thanks

CodePudding user response:

You could use setproduct() to obtain a list with all the combinations and use it for the attachment resources. For example, as follows:

locals {
  app_servers = {
    "server1" = "${aws_instance.server1.id}",
    "server2" = "${aws_instance.server2.id}"
  }

  target_groups = {
    "internal" = {
      port = 9550
      matcher = "200"
    },
    "dev1" = {
      port = 9152
      matcher = "302"
    },
    "sso" = {
      port = 9154
      matcher = "302"
    },
    "terra-test" = {
      port = 9360
      matcher = "200"
    }
  }
  product = setproduct(keys(local.target_groups), values(local.app_servers))
}

resource "aws_lb_target_group" "main" {
  for_each = local.target_groups
  
  name             = "${each.key}-tg"
  port             = each.value["port"]
  protocol         = "HTTPS"
  vpc_id           = aws_vpc.main.id
  protocol_version = "HTTP1"

  health_check {
    healthy_threshold   = 5
    interval            = 15
    protocol            = "HTTPS"
    unhealthy_threshold = 2
    timeout             = 5
    matcher             = each.value["matcher"]
    path                = "/login"
  }
}

resource "aws_lb_target_group_attachment" "main" {
  count = length(local.product)

  target_group_arn = aws_lb_target_group.main[local.product[count.index][0]].arn
  port             = aws_lb_target_group.main[local.product[count.index][0]].port
  target_id        = local.product[count.index][1]
}

Your product would be:

[
    [
        "dev1",
        "<ID_1>",
    ],
    [
        "dev1",
        "<ID_2>",
    ],
    [
        "internal",
        "<ID_1>",
    ],
    [
        "internal",
        "<ID_2>",
    ],
    [
        "sso",
        "<ID_1>",
    ],
    [
        "sso",
        "<ID_2>",
    ],
    [
        "terra-test",
        "<ID_1>",
    ],
    [
        "terra-test",
        "<ID_2>",
    ],
]
  • Related