8

I'm trying to create target groups and attach multiple machines to the target groups using terraform script.

I'm not able to attach multiple target_id please help me to achieve this.

Prathyush P
  • 413
  • 2
  • 4
  • 13
  • Show us what you've tried? It looks simple enough according to the docs. You create a target group and then create attachments to the ARN of the group. – d1ll1nger Jun 12 '17 at 13:48
  • Yeah, I'm talking terraform resources here. It's achieved in the same way. – d1ll1nger Jun 13 '17 at 06:35
  • Manually I've tried in AWS and it is working fine for me. I wanted to automate this with the help of terraform script. I'm trying to add multiple target_id in aws_alb_target_group_attachment. resource "aws_alb_target_group_attachment" "test" { target_group_arn = "${aws_alb_target_group.test.arn}" port = 8080 target_id = "${aws_instance.inst1.id}" target_id = "${aws_instance.inst2.id}" target_id = "${aws_instance.inst3.id}" } This is not giving me any error but it just adds only the last instance that is inst3 to the target group test. – Prathyush P Jun 13 '17 at 06:38
  • There is an open pull request to support multiple target_ids. https://github.com/hashicorp/terraform/pull/9986 There appears to be some concern about making sure the change is backwards compatible. It's unclear to me why they don't add target_ids and use the list syntax that's been used elsewhere. e.g. target_ids = ["target1.id","target2.id"] – jorfus Sep 21 '17 at 20:48

6 Answers6

13

As of Terraform 0.12, this could simply be

resource "aws_alb_target_group_attachment" "test" {
  count = length(aws_instance.test)
  target_group_arn = aws_alb_target_group.test.arn
  target_id = aws_instance.test[count.index].id
}

assuming aws_instance.test returns a list.

https://blog.gruntwork.io/terraform-tips-tricks-loops-if-statements-and-gotchas-f739bbae55f9 is an excellent reference.

Map
  • 399
  • 4
  • 9
5

Below code actually works for me.

resource "aws_alb_target_group_attachment" "test" {
  count = 3 #This can be passed as variable.
  target_group_arn = "${aws_alb_target_group.test.arn}"
  target_id         = "${element(split(",", join(",", aws_instance.web.*.id)), count.index)}"
}

Ref:

https://github.com/terraform-providers/terraform-provider-aws/issues/357 https://groups.google.com/forum/#!msg/terraform-tool/Mr7F3W8WZdk/ouVR3YsrAQAJ

mohit
  • 2,325
  • 23
  • 48
2

Thanks for your quick reply.

Actually giving seperate tag like test1 and test2 for aws_alb_target_group_attachment helped me to add multiple target instances inside one taget group.

resource "aws_alb_target_group_attachment" "test1" {
  target_group_arn = "${aws_alb_target_group.test.arn}"
  port             = 8080
  target_id        = "${aws_instance.inst1.id}"
}
resource "aws_alb_target_group_attachment" "test2" {
  target_group_arn = "${aws_alb_target_group.test.arn}"
  port             = 8080
  target_id        = "${aws_instance.inst2.id}"
}
Prathyush P
  • 413
  • 2
  • 4
  • 13
  • 4
    You can use it when you have a fixed number of instances. Any way to use it with multiple instances which is variable. – mohit Oct 24 '18 at 20:37
2

I created an EMR from terraform and attached multiple "CORE" type EC2 instances to a target group.

The first step would be to retrieve existing instances (which are in "running" state)

data "aws_instances" "core_instances" {

  instance_state_names = ["running"]

  instance_tags = {
    "aws:elasticmapreduce:instance-group-role" = "CORE"
    "terraform" = "true"
  }

}

Next, retrieve an existing VPC

data "aws_vpc" "test_vpc" {
  filter {
    name   = "tag:Name"
    values = ["your-vpc-name"]
  }
}

Use the above data to create a target group and then attach instances to it:

resource "aws_lb_target_group" "core_lb" {
  name        = "core-emr-target-group"
  port        = 8765
  protocol    = "TCP"
  target_type = "instance"
  vpc_id      = data.aws_vpc.test_vpc.id
}

resource "aws_lb_target_group_attachment" "core_lb_instances" {
  for_each         = toset(data.aws_instances.core_instances.ids)
  target_group_arn = aws_lb_target_group.core_lb.arn
  target_id        = each.value
}

Note that you would have to convert the value returned by aws_instances, which is a list, to a set.

Saurabh
  • 5,176
  • 4
  • 32
  • 46
1

Try creating a list of instance ID's and then iterate over using the count index.

For example:

variable "instance_list" {
  description = "Push these instances to ALB"
  type = "list"
  default = ["i00001", "i00002", "i00003"]
}

resource "aws_alb_target_group_attachment" "test" {
  count            = "${var.instance_list}"
  target_group_arn = "${aws_alb_target_group.test.arn}"
  target_id        = "${element(var.instance_list, count.index)}"
  port             = 80
}
d1ll1nger
  • 1,571
  • 12
  • 16
  • This is not working for me. It is adding up only 1 instance out of 3 of a list. If I am using interpolation variable like this. "${element(aws_instance.web.*.id, count.index)}" – mohit Oct 24 '18 at 19:36
  • I'd missed the "count" on the target group resource. Edited answer for future reference. – d1ll1nger Oct 30 '18 at 15:26
0

From my side I found this solution:

  1. Define a data to collect EC2 IDs from an autoscaling security group:
data "aws_instances" "team_deployment" {
  instance_tags = {
    Name = local.ec2_name
  }

  instance_state_names = ["running"]
}

And be sure that instances IDs are the right ones with and evidence (like output)

output "autoscaling_group_ec2_ids" {
  value = data.aws_instances.team_deployment.ids
}
  1. Create as many attachments as IDs has found. Use count parameter:
resource "aws_lb_target_group_attachment" "team_deployment" {
  count = length(data.aws_instances.team_deployment.ids)

  target_group_arn  = data.terraform_remote_state.common_resources.outputs.target_group_api.arn
  target_id         = data.aws_instances.team_deployment.ids[count.index]
  port              = var.ecr_image_port

  depends_on              = [data.aws_instances.team_deployment]
}

And problem solved!

Dan Oliva
  • 11
  • 3