-3

While creating auto_scaling_group with terraform, error showing:

omkar@kws MINGW64 ~/repo/kiwi-infra (main)
$ terraform validate
╷
│ Error: Unsupported attribute
│
│   on main.tf line 46, in module "asg":
│   46:   tg = "${module.alb.tg}"
│     ├────────────────
│     │ module.alb is a list of object
│
│ Can't access attributes on a list of objects. Did you mean to access attribute "tg" for a specific element of the list, or across all elements of the list?

and my code goes as below:

alb module:

resource "aws_lb_target_group" "kiwi-dev-tg" {
  health_check {
    interval            = 10
    path                = "/"
    protocol            = "HTTP"
    timeout             = 5
    healthy_threshold   = 3
    unhealthy_threshold = 2
  }

  name        = "${var.project}-dev-tg"
  port        = 80
  protocol    = "HTTP"
  target_type = "instance"
  vpc_id      = "${var.vpc-id}"
}

asg module:

resource "aws_autoscaling_group" "asg" {
  launch_configuration = "${aws_launch_configuration.launch-conf.name}"
  vpc_zone_identifier  = ["${var.sn1}","${var.sn2 }"]
  target_group_arns    = "${var.tg}"
  health_check_type    = "ELB"

asg variables:

variable "tg" {}

alb output file:

output "tg" {
  value = aws_lb_target_group.kiwi-dev-tg.arn
}

main.tf

module "asg" {
  source = "./modules/asg"
  project = "${var.project}"
  app-sg = "${module.vpc.app-sg}"
  sn1 = "${module.vpc.sn1}"
  sn2 = "${module.vpc.sn2}"
  tg = "${module.alb.tg}"
}

ALB

module "alb" {
  source    = "./modules/alb"
  project = "${var.project}"
  vpc-id = "${module.vpc.vpc-id}"
  count = "${length(module.ec2.app)}"
  app = "${element(module.ec2.app, count.index)}" 
  #app01 = "${module.ec2.app01}"
  #app02 = "${module.ec2.app02}"
  alb-sg = "${module.vpc.alb-sg}"
  sn1 = "${module.vpc.sn1}"
  sn2 = "${module.vpc.sn2}"
}
Marko E
  • 13,362
  • 2
  • 19
  • 28
Omkar
  • 1
  • 2
  • 2
    Please make sure you add all the relevant code and the complete error to the question. – Marko E Apr 12 '23 at 06:56
  • 1
    You haven't explained what `module.alb` is, nor even provided full error message. Please add **full** error message showing exact line where the error occurs. – Marcin Apr 12 '23 at 06:58
  • Thanks for responding guys, updated now. – Omkar Apr 12 '23 at 07:07
  • @Omkar Are you sure you have added the correct output definition to the question? Because the error is for an output which is a list and the one in your question isn't a list. – Marko E Apr 12 '23 at 07:09
  • Hi @MarkoE, this is my issue, how can I add tg arns to asg. – Omkar Apr 12 '23 at 07:40
  • The issue here is you haven't added the module call for ALB to the question, because the error is pretty clear: `module.alb is a list of object`. – Marko E Apr 12 '23 at 07:48
  • You have this line in your ALB module: `count = "${length(module.ec2.app)}"`. That means you will have multiple instances of ALB module created. Do you need to pass the same target group to the ASG module or all of them? – Marko E Apr 12 '23 at 09:00

2 Answers2

2

Since you have a module call to the ALB which is using the count meta-argument, that means you will have to either reference a specific index of the module (because it becomes a list) or you will need to use the same count meta-argument in the module call for ASG. For example:

module "asg" {
  source = "./modules/asg"
  project = "${var.project}"
  app-sg = "${module.vpc.app-sg}"
  sn1 = "${module.vpc.sn1}"
  sn2 = "${module.vpc.sn2}"
  tg = "${module.alb[0].tg}" # or any other index that falls into [0, length(module.ec2.app) - 1]
}

If you need a separate ASG for every TG and app, then you need this:

module "asg" {
  count = "${length(module.ec2.app)}"
  source = "./modules/asg"
  project = "${var.project}"
  app-sg = "${module.vpc.app-sg}"
  sn1 = "${module.vpc.sn1}"
  sn2 = "${module.vpc.sn2}"
  tg = "${module.alb[count.index].tg}"
}

As a side note, you are using the old terraform interpolation syntax, which should be changed to:

module "asg" {
  count = length(module.ec2.app)
  source = "./modules/asg"
  project = var.project
  app-sg = module.vpc.app-sg
  sn1 = module.vpc.sn1
  sn2 = module.vpc.sn2
  tg = module.alb[count.index].tg
}

Additionally, the target_group_arns argument is supposed to be a list, so you would have to update the ASG module as well to take that into account:

resource "aws_autoscaling_group" "asg" {
  launch_configuration = "${aws_launch_configuration.launch-conf.name}"
  vpc_zone_identifier  = ["${var.sn1}","${var.sn2 }"]
  target_group_arns     = ["${var.tg}"]
  health_check_type    = "ELB"

  min_size = 2
  max_size = 4

  tag {
    key                 = "name"
    value               = "${var.project}-dev-asg"
    propagate_at_launch = true
  }
}

If you would want to have more than one TG assigned to the ASG, then you would need to update the variable so it can accept a list:

variable "tg" {
  description = "List of TG to attach to the ASG."
  type = list(string)
}

Then, in the module call, the following would change:

module "asg" {
  source = "./modules/asg"
  project = "${var.project}"
  app-sg = "${module.vpc.app-sg}"
  sn1 = "${module.vpc.sn1}"
  sn2 = "${module.vpc.sn2}"
  tg = "${module.alb[*].tg}"
}

With the same general comment about the terraform syntax:

module "asg" {
  source = "./modules/asg"
  project = var.project
  app-sg  = module.vpc.app-sg
  sn1     = module.vpc.sn1
  sn2     = module.vpc.sn2
  tg      = module.alb[*].tg
}
Marko E
  • 13,362
  • 2
  • 19
  • 28
1

You are trying to pass a string interpolated version of the output as a variable that is to be read as a list in module.asg. So the output is fine, but you need to change how it is passed to then used in module.asg. The main issues are that your are not referencing the specific instance of module.alb (implemented with count) and you are passing a single string for target_group_arns where a list is expected.

The module implementation in main.tf should look like:

module "asg" {
  source  = "./modules/asg"
  project = var.project
  app-sg  = module.vpc.app-sg
  sn1     = module.vpc.sn1
  sn2     = module.vpc.sn2
  tg      = module.alb[*].tg
}

Then the resource in modules/asg/asgmod.tf should look like:

resource "aws_autoscaling_group" "asg" {
  launch_configuration = aws_launch_configuration.launch-conf.name
  vpc_zone_identifier  = [var.sn1, var.sn2]
  target_group_arns    = var.tg # or [var.tf] if you pass single
  health_check_type    = "ELB"

  min_size = 2
  max_size = 4

  tag {
    key                 = "name"
    value               = "${var.project}-dev-asg"
    propagate_at_launch = true
  }
}

Notice the [var.tg] because aws_autoscaling_group target_group_arns expects a list. So if you choose module.alb[0].tg for example [var.tg] will be needed, but if you use module.alb[*].tg, then var.tg will work.


In addition, I think it would be a bit more clear to have in module/alb/outputs.tf:

output "target_group_arn" {
  value = aws_lb_target_group.kiwi-dev-tg.arn
}

Then in modules/asg/vars.tf:

variable "target_group_arns" {
  type    = list(string)
  default = []
}

In modules/asg/asgmod.tf:

resource "aws_autoscaling_group" "asg" {
  launch_configuration = aws_launch_configuration.launch-conf.name
  vpc_zone_identifier  = [var.sn1, var.sn2]
  target_group_arns    = var.target_group_arns
  health_check_type    = "ELB"

  min_size = 2
  max_size = 4

  tag {
    key                 = "name"
    value               = "${var.project}-dev-asg"
    propagate_at_launch = true
  }
}

And lastly, in main.tf:

module "asg" {
  source            = "./modules/asg"
  project           = var.project
  app-sg            = module.vpc.app-sg
  sn1               = module.vpc.sn1
  sn2               = module.vpc.sn2
  target_group_arns = module.alb[*].target_group_arn
}

That seems more clear to me.

theherk
  • 6,954
  • 3
  • 27
  • 52
  • It's not related to interpolation it seems. – Marko E Apr 12 '23 at 08:59
  • @MarkoE: No, that is just a note really. The main issue, I believe, is that a single value is passed where a list is expected. I think the error may have been generated from a different version of code than is currently at HEAD in the repository linked. – theherk Apr 12 '23 at 09:04
  • Ah, true, I need to update my answer as well. – Marko E Apr 12 '23 at 09:08
  • I didn't even catch the `count` issue. :) – theherk Apr 12 '23 at 09:17
  • Ah, well, the error led me to it. :) – Marko E Apr 12 '23 at 09:19
  • 1
    Thanks MarkoE theherk, It tg = module.alb[*].tg working. I was trying like tg = module.alb.tg[*] (notice the [*]). And it helped me alot. Thank you once again. – Omkar Apr 12 '23 at 13:41