Home > Mobile >  How to show all alb tg resources in output using terraform?
How to show all alb tg resources in output using terraform?

Time:10-30

My main.tf has following code:

resource "aws_lb_target_group" "dev-ext-test-msvc1-pub" {
  name                 = "dev-ext-test-msvc1-pub"
  port                 = "14003"
  protocol             = "HTTP"
  target_type          = "instance"
  vpc_id               = data.aws_vpc.vpc.id
  protocol_version     = "HTTP1"
  deregistration_delay = 10
  health_check {
      enabled             = true
      interval            = 10
      path                = "/health"
      port                = "32767"
      healthy_threshold   = 2
      unhealthy_threshold = 2
      timeout             = 2
      protocol            = "HTTP"
      matcher             = "200"
  }

  tags = {
      environment = "dev"
      project     = "ext test 2"
      Name        = "dev-ext-test-msvc1-pub"
  }
}

resource "aws_lb_target_group" "dev-ext-test-msvc2-pub" {
  name                 = "dev-ext-test-msvc2-pub"
  port                 = "14004"
  protocol             = "HTTP"
  target_type          = "instance"
  vpc_id               = data.aws_vpc.vpc.id
  protocol_version     = "HTTP1"
  deregistration_delay = 10
  health_check {
      enabled             = true
      interval            = 10
      path                = "/health"
      port                = "32767"
      healthy_threshold   = 2
      unhealthy_threshold = 2
      timeout             = 2
      protocol            = "HTTP"
      matcher             = "200"
  }

  tags = {
      environment = "dev"
      project     = "ext test 2"
      Name        = "dev-ext-test-msvc2-pub"
  }
}

resource "aws_lb_target_group" "dev-ext-test-msvc5-pub" {
  name                 = "dev-ext-test-msvc5-pub"
  port                 = "14002"
  protocol             = "HTTP"
  target_type          = "instance"
  vpc_id               = data.aws_vpc.vpc.id
  protocol_version     = "HTTP1"
  deregistration_delay = 10
  health_check {
      enabled             = true
      interval            = 10
      path                = "/health"
      port                = "32767"
      healthy_threshold   = 2
      unhealthy_threshold = 2
      timeout             = 2
      protocol            = "HTTP"
      matcher             = "200"
  }

  tags = {
      environment = "dev"
      project     = "ext test 2"
      Name        = "dev-ext-test-msvc5-pub"
  }
}


resource "aws_lb_target_group" "dev-ext-test-msvc4-pub" {
  name                 = "dev-ext-test-msvc4-pub"
  port                 = "14001"
  protocol             = "HTTP"
  target_type          = "instance"
  vpc_id               = data.aws_vpc.vpc.id
  protocol_version     = "HTTP1"
  deregistration_delay = 10
  health_check {
      enabled             = true
      interval            = 10
      path                = "/health"
      port                = "32767"
      healthy_threshold   = 2
      unhealthy_threshold = 2
      timeout             = 2
      protocol            = "HTTP"
      matcher             = "200"
  }

  tags = {
      environment = "dev"
      project     = "ext test 2"
      Name        = "dev-ext-test-msvc4-pub"
  }
}

And output.tf is :

output "lb_dns" {
    value = module.dev-ext-test-pub-2-alb.lb_dns_name
}
output "lb_security_group" {
    value = module.dev-ext-test-pub-2-alb-sg.security_group_id
}
output "lb_target_groups" {
    value = aws_lb_target_group.*.name
}
output "lb_target_groups_arns" {
    value = aws_lb_target_group.*.arn
}
output "worker_ami" {
    value = data.aws_ami.k8s_msvcs_custom_ami.id
}
output "worker_security_group" {
    value = data.aws_security_group.worker_k8s_sg.id
}
output "worker_subnet_id" {
    value = data.aws_subnet.worker-subnet.id
}

But the aws_lb_target_group.*.name is unable to fetch all target groups. Though I can do something like this to fetch the values:

output "lb_target_groups" {
    value = [aws_lb_target_group.dev-ext-test-msvc1-pub.name, aws_lb_target_group.dev-ext-test-msvc4-pub.name,]
}
output "lb_target_groups_arns" {
    value = [aws_lb_target_group.dev-ext-test-msvc1-pub.arn, aws_lb_target_group.dev-ext-test-msvc4-pub.arn,]
}

But is there a more efficient way to fetch all target groups?

CodePudding user response:

But is there a more efficient way to fetch all target groups?

Sadly, no due to your code design, as your are defining fully distinct aws_lb_target_group resources.

But if you were to re-organize your code to use only single block aws_lb_target_group with count or for_each, then there wouldn't be any issues getting all names using spat expressions.

For example:

variable "tgs" {
    default = {
        "dev-ext-test-msvc1-pub" = {
            port = 14003
        },
        "dev-ext-test-msvc2-pub" = {
            port = 14004
        }
        # the rest
    }
}


resource "aws_lb_target_group" "tgs" {

  for_each             = var.tgs

  name                 = each.key
  port                 = each.value.port
  protocol             = "HTTP"
  target_type          = "instance"
  vpc_id               = data.aws_vpc.vpc.id
  protocol_version     = "HTTP1"
  deregistration_delay = 10
  health_check {
      enabled             = true
      interval            = 10
      path                = "/health"
      port                = "32767"
      healthy_threshold   = 2
      unhealthy_threshold = 2
      timeout             = 2
      protocol            = "HTTP"
      matcher             = "200"
  }

  tags = {
      environment = "dev"
      project     = "ext test 2"
      Name        = each.key
  }
}

then

output "lb_target_groups" {
    value = values(aws_lb_target_group.tgs)[*].name
}

CodePudding user response:

Since you're not creating your tg through a loop, it's not possible to index or use the splat as you tried.

You have two choices, create a variable type object with your tg data and iterate over that variable and then use the splat or create a local with the attributes that you want, and then iterate over it, something like this

locals {
  all_tg = [ resource.aws_lb_target_group.dev-ext-test-msvc1-pub,
             resource.aws_lb_target_group.dev-ext-test-msvc2-pub,
             resource.aws_lb_target_group.dev-ext-test-msvc5-pub,
             resource.aws_lb_target_group.dev-ext-test-msvc4-pub
  ]

output "all_tg_names" {
  value = [ for tg in tolist(local.all_tg) : tg.name ]
} 

Here an example:

terraform {

}

provider "random" {}

resource "random_pet" "a" {}
resource "random_pet" "b" {}
resource "random_pet" "c" {}

locals {
  pet = [ resource.random_pet.a,
          resource.random_pet.b,
          resource.random_pet.c
        ]
}

output "name" {
  value = [for pet in tolist(local.pet) : pet.id]
}

Then, after apply it will produce something like this

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Outputs:

name = [
  "mint-reptile",
  "uncommon-coyote",
  "in-mutt",
]

Of course, this solution could be much better if you rethink the way you're building the same resource.

I hope it helps.

  • Related