In a recent infrastructure setup, I encountered an interesting routing scenario where both external and internal Application Load Balancers (ALBs) needed to point to the same target group of web nodes. The architecture looked like this:
Internet -> elb1-external -> Varnish -> elb2-internal -> target-group-of-webnodes
The twist was that certain paths (/static/*
and /media/*
) needed to bypass Varnish and the internal ALB, being routed directly from elb1-external to the target group.
The AWS Management Console presents a limitation here - when attempting to select the same target group for the second ALB, the option appears grayed out. This contradicts documentation suggesting the configuration is possible.
My initial workaround involved:
aws elbv2 create-target-group \
--name target-group-of-webnodes-2 \
--protocol HTTP \
--port 80 \
--vpc-id vpc-123456 \
--health-check-path /health
But maintaining duplicate target groups becomes problematic when implementing auto-scaling, as we need a single source of truth for instance registration.
Through AWS CLI, we can properly associate multiple ALBs with a single target group:
# First get the target group ARN
TG_ARN=$(aws elbv2 describe-target-groups \
--names target-group-of-webnodes \
--query 'TargetGroups[0].TargetGroupArn' \
--output text)
# Then create a new listener rule on elb1-external
aws elbv2 create-rule \
--listener-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/elb1-external/1234567890123456/1234567890123456 \
--priority 10 \
--conditions Field=path-pattern,Values='/static/*','/media/*' \
--actions Type=forward,TargetGroupArn=$TG_ARN
# Verify the configuration
aws elbv2 describe-rules \
--listener-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/elb1-external/1234567890123456/1234567890123456
When implementing auto-scaling, we need to ensure our Launch Template properly registers instances with both ALBs. The CloudFormation snippet below shows how to configure this:
WebServerAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
LaunchTemplate:
LaunchTemplateId: !Ref WebServerLaunchTemplate
Version: !GetAtt WebServerLaunchTemplate.LatestVersionNumber
TargetGroupARNs:
- !Ref ExternalALBTargetGroup
- !Ref InternalALBTargetGroup
MinSize: 2
MaxSize: 6
Routing traffic through multiple ALBs to the same targets does introduce some considerations:
- Health checks will originate from both ALBs, increasing instance load
- Connection multiplexing becomes less effective
- CloudWatch metrics will aggregate across both ALBs
A monitoring solution should be implemented to track these impacts:
aws cloudwatch get-metric-statistics \
--namespace AWS/ApplicationELB \
--metric-name RequestCount \
--dimensions Name=LoadBalancer,Value=app/elb1-external/1234567890123456 \
--start-time 2023-01-01T00:00:00Z \
--end-time 2023-01-02T00:00:00Z \
--period 3600 \
--statistics Sum
In my current AWS infrastructure, I've implemented this traffic flow:
Internet -> ELB1 (external) -> Varnish -> ELB2 (internal) -> Target Group (web nodes)
However, I need certain paths (/static/*
and /media/*
) to bypass Varnish and go directly from ELB1 to the target group, requiring both ALBs to point to the same target group.
The AWS Management Console grays out the target group selection when attempting to attach it to a second ALB. While this appears restrictive, AWS documentation confirms the capability exists at the API level.
Here's how to implement this using AWS CLI:
# First, get the target group ARN
TG_ARN=$(aws elbv2 describe-target-groups --names targetgroupofwebnodes --query 'TargetGroups[0].TargetGroupArn' --output text)
# Then attach to the second ALB
aws elbv2 modify-listener --listener-arn arn:aws:elasticloadbalancing:region:account-id:listener/app/elb2internal/1234567890123456/abcdef0123456789 \
--default-actions Type=forward,TargetGroupArn=$TG_ARN
When migrating to Auto Scaling Groups, you'll need to:
# Create an ASG that registers with the target group
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name WebNodes-ASG \
--launch-template LaunchTemplateName=WebNodeTemplate,Version=1 \
--target-group-arns $TG_ARN \
--min-size 2 \
--max-size 10 \
--vpc-zone-identifier "subnet-12345678,subnet-87654321"
To implement the path-based routing in ELB1:
aws elbv2 create-rule \
--listener-arn arn:aws:elasticloadbalancing:region:account-id:listener/app/elb1external/9876543210987654/0123456789abcdef \
--conditions Field=path-pattern,Values='/static/*','/media/*' \
--priority 10 \
--actions Type=forward,TargetGroupArn=$TG_ARN
The remaining traffic will follow the original path through Varnish to the internal ALB, which also points to the same target group.
- Verify IAM permissions for ELB modifications
- Check target group health status after attachment
- Monitor CloudWatch metrics for uneven traffic distribution
- Confirm security groups allow traffic from both ALBs