3

I'm trying to set up a listener rule on my ALB that should route the /api path to a specified Target Group but for some reason I can't seem to get this to work.

This is my set up:

resource "aws_lb" "main" {
  name               = "${var.name}-alb-internal-${var.environment}"
  internal           = false
  load_balancer_type = "application"
  security_groups    = var.alb_security_groups
  subnets            = var.subnets.*.id

  tags = {
    Name        = "${var.name}-alb-${var.environment}"
    Environment = var.environment
  }
}

resource "aws_alb_target_group" "api" {
  name        = "${var.name}-tg-api-${var.environment}"
  port        = 8080
  protocol    = "HTTP"
  vpc_id      = var.vpc_id
  target_type = "ip"

  health_check {
    healthy_threshold   = "3"
    interval            = "30"
    protocol            = "HTTP"
    matcher             = "200"
    timeout             = "3"
    path                = var.health_check_path
    unhealthy_threshold = "2"
  }

  depends_on = [
    aws_lb.main,
  ]

  tags = {
    Name        = "${var.name}-tg-api-${var.environment}"
    Environment = var.environment
  }
}

resource "aws_alb_listener" "api" {
  load_balancer_arn = aws_lb.main.id
  port              = 80
  protocol          = "HTTP"

  default_action {
    type            = "fixed-response"

    fixed_response {
      status_code   = "404"
      content_type  = "text/plain"
      message_body  = "Hello world"
    }
  }
}

resource "aws_alb_listener_rule" "api_rule" {
  listener_arn = aws_alb_listener.api.arn
  priority     = 100

  action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.api.arn
  }

  condition {
    path_pattern {
      values = ["/api/*"]
    }
  }
}

In this set up I'm trying to forward every requests that starts with /api to my API target group. I have set up a fixed response as the default action for my listener and I have made the response body "Hello world" on purpose to differentiate.

My API service (that runs in ECS) returns Forbidden when GET / is performed. So, if the listener rule works I would expect that visiting *.elb.amazonaws.com/api would return Forbidden. However, these are the results I'm getting:

*.elb.amazonaws.com/ -> Hello World (correct)

*.elb.amazonaws.com/api -> Hello World (expecting "Forbidden", i.e. the response of the root path of my API service)

*.elb.amazonaws.com/api/health -> Not Found (expecting "OK", the /health path exists on my API ECS service and return 200)

I have successfully tested that my ECS API service works correctly by not using the listener rule and have the listener default action directly go to my Target Group.

How can I successfully forward any /api requests with my listener rule to my Target Group?

Luke
  • 20,878
  • 35
  • 119
  • 178

1 Answers1

2

I don't see anything wrong with your setup. I think all works as expected:

  • '/' works as expected. Nothing unusual here.
  • /api will default to /, so you will see "Hello World" as you are observing.
  • /api/health will require on your ecs service /api/health, not /health. So if your ECS does not have /api/health, you will get Not Found.
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • Hmm. Interesting. From your last point I get the impression that this listener rule is not really doing a forwarding (as e.g. Nginx does with a proxy pass) but that it's more a "mapping"... This means that my ECS service actually need to be configured with the same base path as in the listener rule for this to actually work correctly... – Luke Aug 03 '20 at 11:18
  • @Luke I don't think you can perform complex redirections as you can on nginx. – Marcin Aug 03 '20 at 12:04