Configuring AWS ALB/NLB to Forward Traffic to External IP Addresses (Multi-Cloud Backends)


2 views

When managing web applications across multiple cloud providers (AWS, DigitalOcean, Vultr), you might need to distribute traffic to external endpoints while maintaining a single entry point. AWS Load Balancers can handle this through specific configurations.


Client → DNS → AWS ALB/NLB → Target Groups → 
    - AWS EC2 Instances (Internal IPs)
    - DigitalOcean Droplets (External IPs)
    - Vultr Instances (External IPs)

1. Creating Target Groups for External IPs

For Application Load Balancer (ALB):


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

2. Registering External IP Targets

Using AWS CLI to register non-AWS instances:


aws elbv2 register-targets \
    --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/external-backends/1234567890123456 \
    --targets Id=203.0.113.10,Port=8080 Id=198.51.100.20,Port=8081

3. Network Load Balancer (NLB) Alternative

For TCP/UDP traffic forwarding:


aws elbv2 create-load-balancer \
    --name external-nlb \
    --type network \
    --scheme internet-facing \
    --subnets subnet-123456 subnet-789012
  • Security Groups must allow traffic from the ALB/NLB to external IPs
  • Health checks must be properly configured for external targets
  • Consider using PrivateLink for better security with external endpoints
  • For HTTPS, ensure proper certificate management across providers

resource "aws_lb_target_group" "external" {
  name     = "multi-cloud-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc_id
  target_type = "ip"

  health_check {
    path = "/health"
  }
}

resource "aws_lb_target_group_attachment" "do" {
  target_group_arn = aws_lb_target_group.external.arn
  target_id        = "203.0.113.10"
  port             = 8080
}

When routing to external endpoints:

  • Add latency between 5-15ms per hop between cloud providers
  • Monitor TCP connection times with CloudWatch metrics
  • Consider geographic distribution of your external targets
  • Implement connection draining for better failover handling

In a distributed architecture, you might have web applications running across multiple cloud providers (AWS, Digital Ocean, Vultr) with instances listening on different ports. A common requirement is to use AWS Load Balancer as a single entry point to route traffic to these external endpoints.

AWS offers two main types of load balancers that can potentially solve this:

  • Application Load Balancer (ALB): Operates at layer 7 (HTTP/HTTPS)
  • Network Load Balancer (NLB): Operates at layer 4 (TCP/UDP)

Network Load Balancer is better suited for this scenario as it supports IP addresses as targets:

# AWS CLI command to register external IPs as targets
aws elbv2 register-targets \
    --target-group-arn your-target-group-arn \
    --targets Id=203.0.113.5,Port=8080 Id=198.51.100.10,Port=8081

Here's how to set up an NLB to forward to external IPs:

  1. Create a Network Load Balancer
  2. Create a target group with target type as 'IP addresses'
  3. Register your external IP addresses and ports
  4. Configure health checks for your external endpoints
  5. Create listeners and rules

When routing to external IPs, keep in mind:

# Sample CloudFormation template snippet
Resources:
  ExternalTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: external-ips-target-group
      Port: 80
      Protocol: TCP
      TargetType: ip
      Targets:
        - Id: 203.0.113.5
          Port: 8080
        - Id: 198.51.100.10
          Port: 8081

If traffic isn't flowing correctly:

  • Verify security groups and network ACLs allow traffic from NLB to your external IPs
  • Check that health checks are passing
  • Ensure your external instances can handle the additional hop

While ALB doesn't natively support IP targets, you can use a Lambda function as a target to proxy requests:

// Sample Lambda code to route to external endpoints
exports.handler = async (event) => {
    const http = require('http');
    const options = {
        hostname: 'external.example.com',
        port: 8080,
        path: event.path,
        method: event.httpMethod
    };
    
    return new Promise((resolve) => {
        const req = http.request(options, (res) => {
            let data = '';
            res.on('data', (chunk) => data += chunk);
            res.on('end', () => resolve({
                statusCode: res.statusCode,
                body: data
            }));
        });
        req.end();
    });
};