Search code examples
amazon-web-servicesterraformterraform-provider-awsaws-application-load-balancer

Terraform and AWS multiple weighted target groups ALB listeners


I am new to Terraform and I have difficulties in changing our existing config to match our AWS config. It kinda gives me headaches. The original config was created by someone who left the company and I'm trying to update it with the latest changes. I updated different stuff and got to this point where I got stuck. It also seems like I can't handle the Terraform documention wery well /sad_face

I'm using

terraform --version
Terraform v0.14.8
+ provider registry.terraform.io/hashicorp/aws v3.33.0

Goal: create an ALB with a listener on port 443 that needs to redirect traffic to multiple weighted target groups, 2 or 3 targetgroups, with webservers behind. In the below example, it will be with 2 target groups, weight 1 for for each TG (50% of the traffic goes to the firt TG, 50% goes to the second TG). The ALB also has a listener on port 80 that redirects all traffic to 443, but that terraform config works OK. Only the 443 listener gives me headaches.

I will post some of my config here (not all, to not spam with huge block of text), let me know if you want more. I tried changing a lot of stuff, the below config is the last try. This is the ALB TF file

    # Manage company-alb-int-publish-NEW

## Load balancer and FQDN
module "publish-alb" {
  source                           = "../../../../modules/load_balancer"
  # ALB
  alb_name                         = "${var.project_code}-alb-${var.environment}-publish-NEW"
  alb_internal                     = false
  lb_type                          = "application"
  idle_timeout                     = 600

  # Route 53
  .......


## Target group 1
module "publish-target-group" {
  source                           = "../../../../modules/target_group"

  target_group_name                = "company-${var.environment}-Publ1-Apache"
  target_group_port                = 443
  target_group_protocol            = "HTTPS"
  ............
}

# ## Target group 2
module "publish-target-group_2" {
  source                           = "../../../../modules/target_group"

  target_group_name                = "company-${var.environment}-Publ2-Apache"
  target_group_port                = 443
  ..........
}

## Listeners
module "listener-http-https" {
  source                           = "../../../../modules/listener_multiple_weighted_target_groups"

  alb_arn                          = module.publish-alb.alb_arn
  target_group_arn_1               = module.publish-target-group.target_group_arn_1
  target_group_arn_2               = module.publish-target-group.target_group_arn_2
  security_policy                  = var.security_policy
  ssl_certificate                  = var.ssl_certificate
  #listener_action                  = "forward"
  stickiness_duration              = 7200
  stickiness_enabled               = true
}

and this is the module for the ALB listener with multiple weighted target groups I tried to create.

# Traffic over HTTP listener
resource "aws_alb_listener" "http" {
  load_balancer_arn = var.alb_arn
  port              = 80
  protocol          = "HTTP"

  default_action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

# Traffic over HTTPS listener
resource "aws_alb_listener" "https" {
  load_balancer_arn = var.alb_arn
  port              = 443
  protocol          = "HTTPS"
  ssl_policy        = var.security_policy
  certificate_arn   = var.ssl_certificate

  default_action {
    forward {

            target_group_arn {
                target_group_arn    = var.target_group_arn_1
                weight = 1
            }
            target_group_arn {
                target_group_arn    = var.target_group_arn_2
                weight = 1
            }
        }
  }
}

This is the output I get when running "terraform plan"

terraform plan

Error: Unsupported attribute

  on company-alb-int-publish-NEW.tf line 107, in module "listener-http-https-publish":
 107:   target_group_arn_1               = module.publish-target-group.target_group_arn_1

This object does not have an attribute named "target_group_arn_1".


Error: Unsupported attribute

  on company-alb-int-publish-NEW.tf line 108, in module "listener-http-https-publish":
 108:   target_group_arn_2               = module.publish-target-group.target_group_arn_2

This object does not have an attribute named "target_group_arn_2".


Error: Missing required argument

  on ../../../../modules/listener_multiple_weighted_target_groups/main.tf line 28, in resource "aws_alb_listener" "https":
  28:   default_action {

The argument "type" is required, but no definition was found.


Error: Unsupported block type

  on ../../../../modules/listener_multiple_weighted_target_groups/main.tf line 31, in resource "aws_alb_listener" "https":
  31:             target_group_arn {

Blocks of type "target_group_arn" are not expected here.


Error: Unsupported block type

  on ../../../../modules/listener_multiple_weighted_target_groups/main.tf line 35, in resource "aws_alb_listener" "https":
  35:             target_group_arn {

Blocks of type "target_group_arn" are not expected here.

Does anyone have an ideea what I'm doing wrong here?

Thanks!


Solution

  • You should be using default_action.target_group rather than default_action.target_group_arn. The default_action.target_group block then has arn and weight as parameters:

    resource "aws_alb_listener" "https" {
      load_balancer_arn = var.alb_arn
      port              = 443
      protocol          = "HTTPS"
      ssl_policy        = var.security_policy
      certificate_arn   = var.ssl_certificate
    
      default_action {
        type = "forward"
    
        forward {
          target_group {
            arn    = var.target_group_arn_1
            weight = 1
          }
    
          target_group {
            arn    = var.target_group_arn_2
            weight = 1
          }
        }
      }
    }