Search code examples
amazon-web-servicesamazon-ec2terraform

Issue is with alb listener rules now- Task is to add a target grp to each service, target grp attachment, ALB, ALB_listener and rules (terraform aws)


I have 3 microservices (heating, lighting and status), with each one in an ec2 and each ec2 is in a public subnet. I am trying to use path-based-routing with one application load balancer only. I will add auto-scaling later for each microservice-related ec2 instance

resource "aws_lb_target_group" "microservicesgrp"{
  count = length(var.ec2instance_ids)
  name = "${element(["${var.lighting-tgName}","${var.heating-tgName}","${var.status-tgName}"],count.index)}"
  port             = 3000
  protocol         = "HTTP"
  vpc_id           =  var.vpc_id
  target_type      = "instance"
  protocol_version = "HTTP1"
  health_check {
    path     = "/health-check"
    protocol = "HTTP"
  }
}

resource "aws_lb_target_group_attachment" "microservices_attachmnt" {
   count  = length(var.ec2instance_ids)
   target_group_arn = aws_lb_target_group.microservicesgrp[count.index].arn
   target_id = var.ec2instance_ids[count.index]
}

 resource "aws_lb" "proj-alb" {
      name = var.alb_name
      internal = false
      load_balancer_type = "application"
      subnets = var.public_subnet_ids
      security_groups= var.security_group_ids

      tags = {
         Name = "${var.alb_name}-for microservices"
      }
 }

 resource "aws_lb_listener" "alb-portlistener" {
   count = length(var.ec2instance_ids)
   load_balancer_arn = aws_lb.proj-alb.arn
    port              = 80 +count.index
    protocol          = "HTTP"
   default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.microservicesgrp[count.index].arn
     #the alb listener has to access the arns of all 3 microservices
   }
 }

###Issue with this section with the listeners
resource "aws_lb_listener_rule" "heating_lighting_rule" {
  count = length(var.ec2instance_ids)
  listener_arn = aws_lb_listener.alb-portlistener[count.index].arn
  priority     = 100

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.microservicesgrp[count.index].arn
  }

  condition {
    path_pattern {
       values = ["/api/lights/","/api/lights/switch","/api/heating/","/api/heating/zone/:id","/api/heating/zone"]
    }
  }

  condition {
    host_header {
        #list of dns for ec2 instances
        values = var.host_headers
    }
  }
}


resource "aws_lb_listener_rule" "status_rule" {
  count = length(var.ec2instance_ids)
  listener_arn = aws_lb_listener.alb-portlistener[count.index].arn
  priority     = 100

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.microservicesgrp[count.index].arn
  }

  condition {
    path_pattern {
       values = ["/api/status","/api/status/health"]
    }
  }

   condition {
    host_header {
        #list of dns for ec2 instances
        values = var.host_headers
    }
  }

}
#Issue with this section with the listeners

I have edited this question after one of the commentators below correctly mentioned a fix for the alb listener of port = 80 + count.index to remove the duplicate listener error. But now I need help with the alb listener rule paths if they have been done incorrectly. I would like 2 listener rules at least for the paths to my microservices (relevant paths are in the values keys) Now I get this error below. I am new on path-based routing so I did look on AWS but the syntax on writing correct endpoints/url paths to the microservices is not explained in depth

I am getting this error related to the condtion blocks

 Error: creating ELBv2 Listener Rule: ValidationError: A rule can only have '5' condition values
│       status code: 400, request id: 6baa515a-336a-4d35-89ef-4726edfc0f66
│ 
│   with module.load_balancing.aws_lb_listener_rule.heating_lighting_rule[2],
│   on modules/load_balancing/main.tf line 46, in resource "aws_lb_listener_rule" "heating_lighting_rule":
│   46: resource "aws_lb_listener_rule" "heating_lighting_rule" {

Solution

  • You can't have 3 listeners on the same port of 80. Each listener must be on different port. Thus, modify your code to use different ports for each listener, e.g.:

    port              = 80 + count.index