Cont. Various ALB Routing Types of Listeners with Code
Application Load Balancer (ALB) listener rules are essential for routing traffic to appropriate targets based on conditions such as path, headers, IP, and host. These rules provide fine-grained control over how traffic is handled. Below, I’ll walk through the main types of listener rules, their use cases, testing methods, limitations, and combinations with other ALB features like weighted target groups, redirection, and traffic forwarding.
Main Types of ALB Listener Rules
ALB listener rules are conditions set on an ALB to determine how incoming traffic is routed to target groups. These rules can be based on several factors such as:
Path-based routing
Host-based routing
HTTP headers
Source IP address
Each type of listener rule serves different purposes and is useful in various architectures. Let’s go over them in detail:
Path-Based Routing
Description:
Routes requests based on the URL path in the request.
For example, /images, /api, or /docs. This is typically used to direct traffic to different services within the same application based on the request path.
Use Case:
Microservices architecture where different services handle different paths. For example, an API server might handle /api paths, while static content like images might be served from /images.
Load balancing different parts of a web application.
Testing:
Send different requests with specific paths and verify that they are routed to the correct target group.
Tools like curl or Postman can help test path-based routing (curl http://yourdomain.com/api/v1/).
Limitations:
Doesn’t work well if your application doesn’t have well-defined path segments.
Not helpful when you want to route based on something other than the URL path (e.g., IP or headers).
Benefits:
Simplifies management of multiple microservices.
Can direct traffic based on functional components of your app (like APIs, UIs, or image servers).
Disadvantages:
Can be limited if your routing needs are more complex than just URL paths.
Host-Based Routing
Description:
Routes traffic based on the Host header in the request (i.e., the domain name). This is useful when you want to route traffic to different services or target groups based on the domain name, such as www.example.com vs. api.example.com.
Use Case:
Multi-tenant applications where each tenant has a different domain or subdomain.
Directing traffic to different services based on subdomains (e.g., api.example.com to the API server and www.example.com to the web server).
Testing:
You can test host-based routing by sending requests to different domains or subdomains.
Using tools like curl or Postman: curl -H "Host: api.example.com" http://yourALBdnsname.
Limitations:
Requires proper DNS configuration.
Not helpful when routing traffic based on things like IP addresses or headers other than the host.
Benefits:
Simple to implement when routing based on domain or subdomain.
Works well for multi-tenant architectures where each tenant gets its own domain or subdomain.
Disadvantages:
Limited to domain names; cannot be used for routing based on paths or headers.
HTTP Headers
Description:
Routes traffic based on custom HTTP headers in the request, such as User-Agent, X-Forwarded-For, or others. This allows for more fine-grained control over routing based on client-specific data.
Use Case:
Routing based on the client device (e.g., routing requests with a mobile user-agent to a mobile-optimized backend).
A/B testing or canary deployments, where different versions of the application are served based on headers.
Testing:
Send requests with custom headers and verify routing. You can use curl -H to add headers: curl -H "User-Agent: mobile" http://yourALBdnsname.
Limitations:
Only works if the client sends the expected headers.
Not as simple as path or host-based routing for most typical applications.
Benefits:
Allows for very fine-grained control of traffic routing.
Great for testing and gradually rolling out new features to specific client types.
Disadvantages:
Can become overly complex if too many headers are used for routing.
Source IP Address
Description:
Routes traffic based on the source IP address of the client making the request. This is typically used to restrict access to certain target groups based on the client’s geographic location or network.
Use Case:
Geo-based routing where traffic from specific countries or regions is routed to local servers.
Restricting access to certain parts of the application to internal or trusted IP addresses.
Testing:
You can simulate requests from different IP addresses to verify the routing behavior. Tools like ip2location and VPNs can be used to test from different regions.
Limitations:
Requires knowledge of the client’s IP address range or geolocation data.
Less flexible than path or header-based routing.
Benefits:
Useful for restricting access to specific regions or trusted networks.
Enhances security by controlling which IP addresses can access specific resources.
Disadvantages:
Requires careful IP management and may not be flexible if the client’s IP changes frequently.
ALB Listener Rule Combinations with Actions
Listener rules in ALB work together with actions to determine how traffic should be processed once the rule’s conditions are met. There are several combinations of these rules with various actions, such as:
Single Target Group Forwarding
Weighted Target Group Forwarding
Redirection
Fixed Response
Advanced Use Cases (Header Manipulation)
Let’s explore these in detail.
Single Target Group Forwarding
Description:
This is the simplest configuration, where traffic that matches the listener rule (e.g., path-based or host-based) is forwarded to a single target group.
Use Case:
You want to route traffic to a specific set of instances (target group) based on conditions like path or host.
Testing:
Send traffic that matches the rule and verify that it’s forwarded to the correct target group.
Limitations:
Doesn’t support advanced traffic distribution like gradual shifts or canary deployments.
Benefits:
Simple and easy to set up.
Weighted Target Group Forwarding
Description:
This allows traffic to be split between multiple target groups based on assigned weights. For example, you can send 80% of the traffic to one target group and 20% to another.
Use Case:
A/B testing or canary deployments where you want to route a portion of traffic to a new version of your application or infrastructure.
Testing:
Adjust the weights and verify that traffic is distributed according to the specified percentages.
Limitations:
Fine-tuning traffic distribution can be tricky, especially if you want a specific distribution.
Benefits:
Ideal for testing and rolling out new features incrementally.
More flexibility in distributing traffic across different target groups.
Redirection
Description:
Instead of forwarding traffic to a target group, this action redirects traffic to another URL. You can redirect HTTP to HTTPS, or from one domain to another.
Use Case:
HTTP to HTTPS redirection, ensuring secure connections.
Redirect traffic from example.com to www.example.com.
Testing:
Make an HTTP request and verify that it’s redirected to the appropriate location (e.g., HTTPS).
Limitations:
Only for redirection; can’t be used to forward traffic to a target group.
Benefits:
Useful for enforcing HTTPS or canonical URLs.
Fixed Response
Description:
Instead of forwarding or redirecting, the ALB can return a fixed response (such as a custom error message or maintenance page) when the listener rule is matched.
Use Case:
Show a maintenance page when the application is down for updates.
Testing:
Trigger the fixed response and verify that it’s returned as expected.
Limitations:
Can only return simple responses like static HTML or text.
Benefits:
Useful for showing custom error pages or maintenance notifications.
Summary of Rule and Action Combinations
Rule Type - Path-based
Possible Actions - Forward to single/weighted TG, Redirect Microservices.
Use Cases - routing different paths to different services Limited to path routing
Rule Type - Host-based
Possible Actions - Forward to single/weighted TG, Redirect
Use Cases - Multi-tenant apps, routing based on domains Limited to host routing
Rule Type - HTTP Headers
Possible Actions - Forward to single/weighted TG
Use Cases - A/B testing, canary deployments based on headers like User-Agent Requires specific headers
Rule Type - Source IP-based
Possible Actions - Forward to single/weighted TG
Use Cases - Geo-based routing, network-based routing Requires knowledge of source IP addresses
Rule Type - Single TG Forwarding
Possible Actions - Forward to a single target group
Use Cases - Directing all traffic to one target group No traffic distribution
Rule Type - Weighted TG
Possible Actions - Distribute traffic based on weight
Use Cases - Gradual rollouts, A/B testing, blue-green deployments Fine-tuning traffic distribution can be tricky
Rule Type - Redirection
Possible Actions - Redirect to a different URL or protocol
Use Cases - HTTP to HTTPS redirection, domain-level redirection Can’t forward traffic to TG
Rule Type - Fixed Response
Possible Actions - Return a custom message
Use Cases - Maintenance pages, custom error pages Can only return static responses like text or simple HTML
Benefits:
Fine-Grained Control: You can route traffic based on many different conditions, giving you full control over how your application responds to requests.
Flexibility: Weighted forwarding allows for incremental rollouts, while redirection ensures seamless user experience.
Security: Path-based or host-based routing can be combined with IP-based rules to restrict access based on geographic or network factors.
Disadvantages:
Complexity: Setting up and maintaining multiple listener rules can become complex, especially in large applications.
Limited Action Combinations: Some rules (like HTTP headers) can only forward traffic and can’t be used for actions like redirection or fixed responses.
By combining the different types of listener rules and actions, you can create a robust and flexible traffic routing system tailored to your application’s needs.
main.tf code in ALB module for Different Routing Types
The below resource blocks will be added to file apart from resource block like aws_security_group, aws_lb…
Header Based Routing -1 HTTP, Two Target Groups
```plaintext resource "aws_security_group" "sg-alb" {
description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }
ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true
tags = { Name = "instance-alb" } }
resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id
health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 }
tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id
health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 }
tags = { Name = "tg2" } }
resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP"
default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = ".... this is default response ...." status_code = 200 } } }
resource "aws_lb_listener_rule" "header_based_routing_example" { listener_arn = aws_lb_listener.http.arn priority = 100
action { type = "forward" target_group_arn = aws_lb_target_group.tg1.arn } condition { http_header { http_header_name = "X-Custom-Header" values = ["custom-value"] } } }
resource "aws_lb_listener_rule" "header_based_routing_user-agent" { listener_arn = aws_lb_listener.http.arn priority = 400 action { type = "forward" target_group_arn = aws_lb_target_group.tg2.arn } condition {
http_header { http_header_name = "User-Agent" values = ["Mozilla/*"] } } }
First, attach half (or roughly half) of the instances to the first target group
resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 }
Attach the remaining instances to the second target group
resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 }
/* testing Host-based Routing:
Test for example.com
curl -H "Host: example.com" http://
Test for api.example.com
curl -H "Host: api.example.com" http://
http-header
Header-based Routing
Test with custom header
curl -H "X-Custom-Header: custom-value" http://
Test with User-Agent header
curl -A "Mozilla/5.0" http://
Path-based Routing:
Test path-based routing for /api
curl http:///api/some-endpoint
Test path-based routing for /static
curl http:///static/some-static-content */
2. Header Based Routing -2 Two Target Group
Multi Httpd Header Condition blocks
```plaintext
resource "aws_security_group" "sg-alb" {
description = "example"
vpc_id = var.vpc_id
tags = {
Name = "sns-sg-ec2"
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_lb" "main" {
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.sg-alb.id]
subnets = var.public_subnet_ids
enable_deletion_protection = false
enable_cross_zone_load_balancing = true
tags = {
Name = "instance-alb"
}
}
resource "aws_lb_target_group" "tg1" {
name = "tg1"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
path = "/"
interval = 10
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
}
tags = {
Name = "tg1"
}
}
resource "aws_lb_target_group" "tg2" {
name = "tg2"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
path = "/"
interval = 10
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
}
tags = {
Name = "tg2"
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
message_body = ".... this is default response ...."
status_code = 200
}
}
}
resource "aws_lb_listener_rule" "header_based_routing_example-1-tg1" {
listener_arn = aws_lb_listener.http.arn
priority = 10
action {
type = "forward"
target_group_arn = aws_lb_target_group.tg1.arn
}
condition {
http_header {
http_header_name = "X-Custom-Header"
values = ["custom-value"]
}
}
}
resource "aws_lb_listener_rule" "header_based_routing_example-2-tg1" {
listener_arn = aws_lb_listener.http.arn
priority = 15
action {
type = "forward"
target_group_arn = aws_lb_target_group.tg1.arn
}
condition {
http_header {
http_header_name = "hey"
values = ["hello"]
}
}
}
resource "aws_lb_listener_rule" "header_based_routing_user-agent-1-tg2" {
listener_arn = aws_lb_listener.http.arn
priority = 12
action {
type = "forward"
target_group_arn = aws_lb_target_group.tg2.arn
}
condition {
http_header {
http_header_name = "User-Agent"
values = ["Mozilla/*"]
}
}
}
resource "aws_lb_listener_rule" "header_based_routing_user-agent-2-tg2" {
listener_arn = aws_lb_listener.http.arn
priority = 40
action {
type = "forward"
target_group_arn = aws_lb_target_group.tg2.arn
}
condition {
http_header {
http_header_name = "myname"
values = ["shraddha"]
}
}
}
# First, attach half (or roughly half) of the instances to the first target group
resource "aws_lb_target_group_attachment" "tg1_attachment" {
count = ceil(length(var.instance_ids) / 2)
target_group_arn = aws_lb_target_group.tg1.arn
target_id = element(var.instance_ids, count.index)
port = 80
}
# Attach the remaining instances to the second target group
resource "aws_lb_target_group_attachment" "tg2_attachment" {
count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2)
target_group_arn = aws_lb_target_group.tg2.arn
target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2))
port = 80
}
/* testing 131 curl -H "X-Custom-Header: custom-value" tf-lb-20240912050937972000000005-1509432986.ap-south-1.elb.amazonaws.com
curl -H "hey: hello" tf-lb-20240912050937972000000005-1509432986.ap-south-1.elb.amazonaws.com
curl -H "X-Custom-Header: custom-value" tf-lb-20240912050937972000000005-1509432986.ap-south-1.elb.amazonaws.com
curl -H "hey: hello"
curl -H "myname: shraddha"
curl -H ": "
Host-based Routing:
# Test for example.com
curl -H "Host: example.com" http://<ALB-DNS>
# Test for api.example.com
curl -H "Host: api.example.com" http://<ALB-DNS>
http-header
Header-based Routing
# Test with custom header
curl -H "X-Custom-Header: custom-value" http://<ALB-DNS>
# Test with User-Agent header
curl -A "Mozilla/5.0" http://<ALB-DNS>
Path-based Routing:
# Test path-based routing for /api
curl http://<ALB-DNS>/api/some-endpoint
# Test path-based routing for /static
curl http://<ALB-DNS>/static/some-static-content
*/
Header Based Routing -3 Multi Httpd Condition Block
```plaintext resource "aws_security_group" "sg-alb" {
description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }
ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true
tags = { Name = "instance-alb" } }
resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id
health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 }
tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id
health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 }
tags = { Name = "tg2" } }
resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP"
default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = ".... this is default response ...." status_code = 200 } } }
resource "aws_lb_listener_rule" "header_based_routing_example-1-tg1" { listener_arn = aws_lb_listener.http.arn priority = 10
action { type = "forward" target_group_arn = aws_lb_target_group.tg1.arn } condition { http_header { http_header_name = "region" values = ["east", "west", "south"] } } }
resource "aws_lb_listener_rule" "multiple-values-header_based_routing-tg2" { listener_arn = aws_lb_listener.http.arn priority = 2 action { type = "forward" target_group_arn = aws_lb_target_group.tg2.arn } condition { http_header { http_header_name = "class" values = ["a", "b", "c"] } } }
First, attach half (or roughly half) of the instances to the first target group
resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 }
Attach the remaining instances to the second target group
resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 }
/* testing
curl -H "region: east"
curl -H "region: west"
curl -H "region: south"
curl -H "class: a"
curl -H "class: b"
curl -H "myname: shraddha"
Host-based Routing:
Test for example.com
curl -H "Host: example.com" http://
Test for api.example.com
curl -H "Host: api.example.com" http://
http-header
Header-based Routing
Test with custom header
curl -H "X-Custom-Header: custom-value" http://
Test with User-Agent header
curl -A "Mozilla/5.0" http://
Path-based Routing:
Test path-based routing for /api
curl http:///api/some-endpoint
Test path-based routing for /static
curl http:///static/some-static-content
*/
4. Header Based Routing - 4 Match Pattern
```plaintext
resource "aws_security_group" "sg-alb" {
description = "example"
vpc_id = var.vpc_id
tags = {
Name = "sns-sg-ec2"
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_lb" "main" {
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.sg-alb.id]
subnets = var.public_subnet_ids
enable_deletion_protection = false
enable_cross_zone_load_balancing = true
tags = {
Name = "instance-alb"
}
}
resource "aws_lb_target_group" "tg1" {
name = "tg1"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
path = "/"
interval = 10
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
}
tags = {
Name = "tg1"
}
}
resource "aws_lb_target_group" "tg2" {
name = "tg2"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
path = "/"
interval = 10
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
}
tags = {
Name = "tg2"
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
message_body = ".... this is default response ...."
status_code = 200
}
}
}
resource "aws_lb_listener_rule" "header_based_routing_example-1-tg1" {
listener_arn = aws_lb_listener.http.arn
priority = 10
action {
type = "forward"
target_group_arn = aws_lb_target_group.tg1.arn
}
condition {
http_header {
http_header_name = "region"
values = ["east/5.0*"]
}
}
}
resource "aws_lb_listener_rule" "multiple-values-header_based_routing-tg2" {
listener_arn = aws_lb_listener.http.arn
priority = 2
action {
type = "forward"
target_group_arn = aws_lb_target_group.tg2.arn
}
condition {
http_header {
http_header_name = "class"
values = ["a/version/api-1*"]
}
}
}
# First, attach half (or roughly half) of the instances to the first target group
resource "aws_lb_target_group_attachment" "tg1_attachment" {
count = ceil(length(var.instance_ids) / 2)
target_group_arn = aws_lb_target_group.tg1.arn
target_id = element(var.instance_ids, count.index)
port = 80
}
# Attach the remaining instances to the second target group
resource "aws_lb_target_group_attachment" "tg2_attachment" {
count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2)
target_group_arn = aws_lb_target_group.tg2.arn
target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2))
port = 80
}
/* testing
curl -H "region: east/5.0"
curl -H "class: a/version/api-1"
Host-based Routing:
# Test for example.com
curl -H "Host: example.com" http://<ALB-DNS>
# Test for api.example.com
curl -H "Host: api.example.com" http://<ALB-DNS>
http-header
Header-based Routing
# Test with custom header
curl -H "X-Custom-Header: custom-value" http://<ALB-DNS>
# Test with User-Agent header
curl -A "Mozilla/5.0" http://<ALB-DNS>
Path-based Routing:
# Test path-based routing for /api
curl http://<ALB-DNS>/api/some-endpoint
# Test path-based routing for /static
curl http://<ALB-DNS>/static/some-static-content
*/
Host Based Routing - 1 Single Target Group
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "Default response for unspecified routes" status_code = "200" } } } resource "aws_lb_listener_rule" "single-target-group-1" { listener_arn = aws_lb_listener.http.arn priority = 1 action { type = "forward" target_group_arn = aws_lb_target_group.tg1.arn } condition { host_header { values = ["example.com"] } } } /* resource "aws_lb_listener_rule" "single-Host-TG-2" { listener_arn = aws_lb_listener.http.arn priority = 10 action { type = "forward" target_group_arn = aws_lb_target_group.tg2.arn } condition { host_header { values = ["host.com"] } } } */ # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /* testing Host-based Routing: # Test for example.com curl -H "Host: example.com" http://<ALB-DNS> # Test for api.example.com curl -H "Host: api.example.com" http://<ALB-DNS> Header-based Routing # Test with custom header curl -H "X-Custom-Header: custom-value" http://<ALB-DNS> # Test with User-Agent header curl -A "Mozilla/5.0" http://<ALB-DNS> Path-based Routing: # Test path-based routing for /api curl http://<ALB-DNS>/api/some-endpoint # Test path-based routing for /static curl http://<ALB-DNS>/static/some-static-content */
Host Based Routing - 2 Two Target Group
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "Default response for unspecified routes" status_code = "200" } } } resource "aws_lb_listener_rule" "host-based-multi-target-groups" { listener_arn = aws_lb_listener.http.arn priority = 1 action { type = "forward" forward { target_group { arn = aws_lb_target_group.tg1.arn weight = 50 } target_group { arn = aws_lb_target_group.tg2.arn weight = 30 } } } condition { host_header { values = [ "example.com" ] } } } # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /* testing Host-based Routing: # Test for example.com curl -H "Host: example.com" http://<ALB-DNS> # Test for api.example.com curl -H "Host: api.example.com" http://<ALB-DNS> Header-based Routing # Test with custom header curl -H "X-Custom-Header: custom-value" http://<ALB-DNS> # Test with User-Agent header curl -A "Mozilla/5.0" http://<ALB-DNS> Path-based Routing: # Test path-based routing for /api curl http://<ALB-DNS>/api/some-endpoint # Test path-based routing for /static curl http://<ALB-DNS>/static/some-static-content */
Host Based Routing - 3 Fixed Response
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "Default response for unspecified routes" status_code = "200" } } } resource "aws_lb_listener_rule" "host-based-multi-target-groups" { listener_arn = aws_lb_listener.http.arn priority = 1 action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "service unavailiable" status_code = "230" } } condition { host_header { values = [ "maintenance.example.com" ] } } } # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /* testing Host-based Routing: # Test for example.com curl -H "Host: example.com" http://<ALB-DNS> # Test for api.example.com curl -H "Host: api.example.com" http://<ALB-DNS> Header-based Routing # Test with custom header curl -H "X-Custom-Header: custom-value" http://<ALB-DNS> # Test with User-Agent header curl -A "Mozilla/5.0" http://<ALB-DNS> Path-based Routing: # Test path-based routing for /api curl http://<ALB-DNS>/api/some-endpoint # Test path-based routing for /static curl http://<ALB-DNS>/static/some-static-content */
Host Based Routing - 4 Redirect
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "Default response for unspecified routes" status_code = "200" } } } resource "aws_lb_listener_rule" "host-redirect-target-group" { listener_arn = aws_lb_listener.http.arn priority = 1 action { type = "redirect" redirect { protocol = "HTTPS" port = "443" status_code = "HTTP_301" } } condition { host_header { values = [ "example.com" ] } } } # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /* testing Host-based Routing: # Test for example.com curl -H "Host: example.com" http://<ALB-DNS> # Test for api.example.com curl -H "Host: api.example.com" http://<ALB-DNS> Header-based Routing # Test with custom header curl -H "X-Custom-Header: custom-value" http://<ALB-DNS> # Test with User-Agent header curl -A "Mozilla/5.0" http://<ALB-DNS> Path-based Routing: # Test path-based routing for /api curl http://<ALB-DNS>/api/some-endpoint # Test path-based routing for /static curl http://<ALB-DNS>/static/some-static-content */
IP Based Routing -1 Two Target Groups (Internal/External)
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "Default response for unspecified routes" status_code = "404" } } } resource "aws_lb_listener_rule" "ip-based-routing-tg1-internal" { listener_arn = aws_lb_listener.http.arn priority = 10 action { type = "forward" target_group_arn = aws_lb_target_group.tg1.arn } condition { source_ip { values = ["172.31.0.0/16"] } } } resource "aws_lb_listener_rule" "ip-based-routing-tg1-external" { listener_arn = aws_lb_listener.http.arn priority = 300 action { type = "forward" target_group_arn = aws_lb_target_group.tg2.arn } condition { source_ip { values = ["192.168.0.0/16","10.0.0.0/8", "65.0.0.0/16" ] #"0.0.0.0/0"] } } } # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /* testing Host-based Routing: # Test for example.com curl -H "Host: example.com" http://<ALB-DNS> # Test for api.example.com curl -H "Host: api.example.com" http://<ALB-DNS> Header-based Routing # Test with custom header curl -H "X-Custom-Header: custom-value" http://<ALB-DNS> # Test with User-Agent header curl -A "Mozilla/5.0" http://<ALB-DNS> Path-based Routing: # Test path-based routing for /api curl http://<ALB-DNS>/api/some-endpoint # Test path-based routing for /static curl http://<ALB-DNS>/static/some-static-content ip based routing internal ip must be the public ip range of testing instance curl -H "X-Forwarded-For: 65.0.0.0" tf-lb-20240912050937972000000005-1509432986.ap-south-1.elb.amazonaws.com curl -H "X-Forwarded-For: 0.0.0.0" tf-lb-20240912050937972000000005-1509432986.ap-south-1.elb.amazonaws.com Source IP Routing in AWS: The ALB will see the private IP of the instance when you're testing within AWS. Private IP Test: Adjust your listener rules to match the private IP range (172.31.0.0/16) for internal traffic. NAT or Elastic IP: If the instance is behind a NAT Gateway, traffic may be seen as coming from the NAT IP range. */
IP Based Routing -2 Two Weighted Target Groups
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "Default response for unspecified routes" status_code = "404" } } } resource "aws_lb_listener_rule" "ip-based-routing-tg1-internal" { listener_arn = aws_lb_listener.http.arn priority = 10 action { type = "forward" forward { target_group { arn = aws_lb_target_group.tg1.arn weight = 70 } target_group { arn = aws_lb_target_group.tg2.arn weight = 30 } stickiness { enabled = true duration = 3 } } } condition { source_ip { values = ["172.31.0.0/16"] } } }/* resource "aws_lb_listener_rule" "ip-based-routing-tg1-external" { listener_arn = aws_lb_listener.http.arn priority = 300 action { type = "forward" target_group_arn = aws_lb_target_group.tg2.arn } condition { source_ip { values = ["192.168.0.0/16","10.0.0.0/8", "65.0.0.0/16" ] #"0.0.0.0/0"] } } } */ # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /* testing Host-based Routing: # Test for example.com curl -H "Host: example.com" http://<ALB-DNS> # Test for api.example.com curl -H "Host: api.example.com" http://<ALB-DNS> Header-based Routing # Test with custom header curl -H "X-Custom-Header: custom-value" http://<ALB-DNS> # Test with User-Agent header curl -A "Mozilla/5.0" http://<ALB-DNS> Path-based Routing: # Test path-based routing for /api curl http://<ALB-DNS>/api/some-endpoint # Test path-based routing for /static curl http://<ALB-DNS>/static/some-static-content ip based routing internal ip must be the public ip range of testing instance curl -H "X-Forwarded-For: 65.0.0.0" tf-lb-20240912050937972000000005-1509432986.ap-south-1.elb.amazonaws.com curl -H "X-Forwarded-For: 0.0.0.0" tf-lb-20240912050937972000000005-1509432986.ap-south-1.elb.amazonaws.com Source IP Routing in AWS: The ALB will see the private IP of the instance when you're testing within AWS. Private IP Test: Adjust your listener rules to match the private IP range (172.31.0.0/16) for internal traffic. NAT or Elastic IP: If the instance is behind a NAT Gateway, traffic may be seen as coming from the NAT IP range. */
Path Based Routing - 1 Static Path
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = ".... this is default response ...." status_code = 200 } } } resource "aws_lb_listener_rule" "path_based_routing_example_service1_to_target_1" { listener_arn = aws_lb_listener.http.arn priority = 10 action { type = "forward" target_group_arn = aws_lb_target_group.tg1.arn } condition { path_pattern { values = ["/service1/*"] } } } resource "aws_lb_listener_rule" "path_based_routing_example_service1_to_target_2" { listener_arn = aws_lb_listener.http.arn priority = 200 action { type = "forward" target_group_arn = aws_lb_target_group.tg2.arn } condition { path_pattern { values = ["/service2/*"] } } } # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /*Requests to /service1/* go to service_1 target group. Requests to /service2/* go to service_2 target group. Path-based Routing: # Test path-based routing for /api curl http://<ALB-DNS>/api/some-endpoint # Test path-based routing for /static curl http://<ALB-DNS>/static/some-static-content */
Path Based Routing - 2 Multi Static Paths
```plaintext resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }
ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true
tags = { Name = "instance-alb" } }
resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id
health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 }
tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id
health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 }
tags = { Name = "tg2" } }
resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP"
default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = ".... this is default response ...." status_code = 200 } } }
resource "aws_lb_listener_rule" "path_based_routing_example_service1_to_target_1" { listener_arn = aws_lb_listener.http.arn priority = 10
action { type = "forward" target_group_arn = aws_lb_target_group.tg1.arn } condition { path_pattern { values = ["/service1/", "/service2/", "/service3/*"] } } }
resource "aws_lb_listener_rule" "path_based_routing_example_service1_to_target_2" { listener_arn = aws_lb_listener.http.arn priority = 200 action { type = "forward" target_group_arn = aws_lb_target_group.tg2.arn } condition { path_pattern { values = ["/app/", "/user/", "/admin/*"] } } }
First, attach half (or roughly half) of the instances to the first target group
resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 }
Attach the remaining instances to the second target group
resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 }
/Requests to /service1/, service 2 go to target group 1. Requests to /app/, /user/, /admin/* go to service_2 target group 2.
Path-based Routing:
Test path-based routing for /api
curl http:///api/some-endpoint
Test path-based routing for /static
curl http:///static/some-static-content curl http:///admin curl http:///service1 == this will take you to the default response page set earlier */
13. Path Based Routing - 3 Weighted Target Group
```plaintext
resource "aws_security_group" "sg-alb" {
description = "example"
vpc_id = var.vpc_id
tags = {
Name = "sns-sg-ec2"
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_lb" "main" {
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.sg-alb.id]
subnets = var.public_subnet_ids
enable_deletion_protection = false
enable_cross_zone_load_balancing = true
tags = {
Name = "instance-alb"
}
}
resource "aws_lb_target_group" "tg1" {
name = "tg1"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
path = "/"
interval = 10
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
}
tags = {
Name = "tg1"
}
}
resource "aws_lb_target_group" "tg2" {
name = "tg2"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
path = "/"
interval = 10
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
}
tags = {
Name = "tg2"
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
message_body = ".... this is default response ...."
status_code = 200
}
}
}
resource "aws_lb_listener_rule" "path_based_routing_weighted" {
listener_arn = aws_lb_listener.http.arn
priority = 100
action {
type = "forward"
forward {
target_group {
arn = aws_lb_target_group.tg1.arn
weight = 80
}
target_group {
arn = aws_lb_target_group.tg2.arn
weight = 20
}
}
}
condition {
path_pattern {
values = ["/*"]
}
}
}
# First, attach half (or roughly half) of the instances to the first target group
resource "aws_lb_target_group_attachment" "tg1_attachment" {
count = ceil(length(var.instance_ids) / 2)
target_group_arn = aws_lb_target_group.tg1.arn
target_id = element(var.instance_ids, count.index)
port = 80
}
# Attach the remaining instances to the second target group
resource "aws_lb_target_group_attachment" "tg2_attachment" {
count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2)
target_group_arn = aws_lb_target_group.tg2.arn
target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2))
port = 80
}
/*Requests to /service1/* go to service_1 target group.
Requests to /service2/* go to service_2 target group.*/
Path Based Routing - 4 Fixed Response
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "Default response for unspecified routes" status_code = "200" } } } resource "aws_lb_listener_rule" "path-fixed-response" { listener_arn = aws_lb_listener.http.arn priority = 100 action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "Service is currently down..." status_code = "503" } } condition { path_pattern { values = ["/maintainance/*"] } } } # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /*aws_lb_listener: Defines the ALB listener for incoming HTTP requests on port 80. The default_action here is a fixed-response action. If no specific rule matches, this will return a default message ("Default response for unspecified routes."). aws_lb_listener_rule: Defines a rule for the listener. If the path matches /maintenance/*, the action taken will be a fixed-response with a custom message ("Service is currently down for maintenance.") and a 503 Service Unavailable status code. */
Path Based Routing - 5 Query String
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = "Default response for unspecified routes" status_code = "200" } } } resource "aws_lb_listener_rule" "path-query-string-1" { listener_arn = aws_lb_listener.http.arn priority = 100 action { type = "forward" target_group_arn = aws_lb_target_group.tg1.arn } condition { query_string { key = "action" value = "create" } } } resource "aws_lb_listener_rule" "path-query-string-2" { listener_arn = aws_lb_listener.http.arn priority = 10 action { type = "forward" target_group_arn = aws_lb_target_group.tg2.arn } condition { query_string { key = "action" value = "update" } } } # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /* testing curl "http://<ALB_DNS_NAME>?action=create" curl http://<ALB_DNS_NAME>?action=update */
Path Based Routing - 6 Redirect
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = ".... this is default response ...." status_code = 200 } } } resource "aws_lb_listener_rule" "path_based_routing_weighted" { listener_arn = aws_lb_listener.http.arn priority = 100 action { type = "redirect" redirect { protocol = "HTTPS" port = "443" status_code = "HTTP_301" } } condition { path_pattern { values = ["/*"] } } } # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /* Testing 1 - browser 2 - cli - curl http://dns-name Redirect -moved permanently Forward - This condition will forward the traffic to the defined target group ... */
Path Based Routing - 7 Forward
resource "aws_security_group" "sg-alb" { description = "example" vpc_id = var.vpc_id tags = { Name = "sns-sg-ec2" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_lb" "main" { internal = false load_balancer_type = "application" security_groups = [aws_security_group.sg-alb.id] subnets = var.public_subnet_ids enable_deletion_protection = false enable_cross_zone_load_balancing = true tags = { Name = "instance-alb" } } resource "aws_lb_target_group" "tg1" { name = "tg1" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg1" } } resource "aws_lb_target_group" "tg2" { name = "tg2" port = 80 protocol = "HTTP" vpc_id = var.vpc_id health_check { path = "/" interval = 10 timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } tags = { Name = "tg2" } } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.main.arn port = 80 protocol = "HTTP" default_action { type = "fixed-response" fixed_response { content_type = "text/plain" message_body = ".... this is default response ...." status_code = 200 } } } resource "aws_lb_listener_rule" "path_based_routing_weighted" { listener_arn = aws_lb_listener.http.arn priority = 100 action { type = "forward" target_group_arn = aws_lb_target_group.tg1.arn } condition { path_pattern { values = ["/*"] } } } # First, attach half (or roughly half) of the instances to the first target group resource "aws_lb_target_group_attachment" "tg1_attachment" { count = ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg1.arn target_id = element(var.instance_ids, count.index) port = 80 } # Attach the remaining instances to the second target group resource "aws_lb_target_group_attachment" "tg2_attachment" { count = length(var.instance_ids) - ceil(length(var.instance_ids) / 2) target_group_arn = aws_lb_target_group.tg2.arn target_id = element(var.instance_ids, count.index + ceil(length(var.instance_ids) / 2)) port = 80 } /* Testing 1 - browser 2 - cli - curl http://dns-name Redirect -moved permanently Forward - This condition will forward the traffic to the defined target group ... */
So this concludes the ALB Code for various types of Routing.
Subscribe to my newsletter
Read articles from Shraddha Suryawanshi directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by