How to Configure a Single AWS ELB for Multiple Web Apps Using Host-Based Routing


2 views

When managing multiple web applications (let's say 5 distinct apps) deployed across paired EC2 instances (total 10 instances), a common infrastructure question arises: can we efficiently route traffic using just one Elastic Load Balancer instead of maintaining N separate ELBs?

AWS Application Load Balancer (ALB) provides the perfect solution through host-based routing rules. Here's how it works:

# Sample Terraform configuration for ALB with host-based routing
resource "aws_lb" "multi_app_alb" {
  name               = "multi-app-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb_sg.id]
  subnets            = [aws_subnet.public.*.id]

  enable_deletion_protection = false
}

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.multi_app_alb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type = "fixed-response"
    fixed_response {
      content_type = "text/plain"
      message_body = "No matching host route"
      status_code  = "404"
    }
  }
}

resource "aws_lb_listener_rule" "app1" {
  listener_arn = aws_lb_listener.http.arn
  priority     = 100

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app1.arn
  }

  condition {
    host_header {
      values = ["app1.example.com"]
    }
  }
}

Key components of this setup:

  • Single ALB fronting all applications
  • Target Groups for each application pair
  • Host-based routing rules mapping domains to correct target groups
  • Health checks per target group

While consolidating to one ALB reduces management overhead, consider:

  • ALB has a soft limit of 100 routing rules (can be increased via support ticket)
  • All applications share the same ALB capacity units
  • SSL certificates must cover all hosted domain names

For more complex scenarios, you might consider:

  1. Using path-based routing if applications share a domain
  2. Implementing a reverse proxy (Nginx/HAProxy) on EC2 instances
  3. Exploring AWS API Gateway for HTTP APIs

When managing multiple web applications (let's say app1.example.com, app2.example.com, etc.) each running on separate instance pairs in AWS, traditional load balancing approaches often lead to inefficient resource usage. The core requirement is to:

  • Maintain high availability with 2 instances per application
  • Route traffic based on the HTTP Host header
  • Minimize infrastructure costs by avoiding multiple ELBs

We can achieve this using an Application Load Balancer (ALB) with host-based routing rules. Here's the configuration flow:

ALB → Listener Rules → Target Groups (per app) → EC2 Instances

1. Create Target Groups

aws elbv2 create-target-group \
    --name app1-tg \
    --protocol HTTP \
    --port 80 \
    --vpc-id vpc-123456 \
    --health-check-path /health

aws elbv2 create-target-group \
    --name app2-tg \
    --protocol HTTP \
    --port 80 \
    --vpc-id vpc-123456 \
    --health-check-path /health

2. Register Instances

aws elbv2 register-targets \
    --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/app1-tg/1234567890123456 \
    --targets Id=i-1234567890abcdef0 Id=i-0987654321abcdef0

aws elbv2 register-targets \
    --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/app2-tg/1234567890123456 \
    --targets Id=i-abcdef12345678901 Id=i-fedcba0987654321

3. Configure Listener Rules

aws elbv2 create-rule \
    --listener-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/my-load-balancer/1234567890123456/1234567890123456 \
    --priority 10 \
    --conditions Field=host-header,Values='app1.example.com' \
    --actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/app1-tg/1234567890123456

aws elbv2 create-rule \
    --listener-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/my-load-balancer/1234567890123456/1234567890123456 \
    --priority 20 \
    --conditions Field=host-header,Values='app2.example.com' \
    --actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/app2-tg/1234567890123456

For infrastructure-as-code users:

resource "aws_lb_listener_rule" "app1" {
  listener_arn = aws_lb_listener.front_end.arn
  priority     = 100

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app1.arn
  }

  condition {
    host_header {
      values = ["app1.example.com"]
    }
  }
}

resource "aws_lb_listener_rule" "app2" {
  listener_arn = aws_lb_listener.front_end.arn
  priority     = 101

  action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.app2.arn
  }

  condition {
    host_header {
      values = ["app2.example.com"]
    }
  }
}
  • ALB can handle up to 100 listener rules by default (can be increased via support ticket)
  • Rule evaluation is ordered by priority number (lowest evaluated first)
  • Wildcard host headers are supported (e.g., *.example.com)

Compared to running N Classic ELBs ($18.25/month each):

Number of Apps Classic ELB Cost ALB Solution Cost
5 $91.25 $16.50 + $0.008 per LCU
10 $182.50 $16.50 + $0.016 per LCU