How to Replace Nginx Reverse Proxy with AWS Cloud-Based Routing Solutions


2 views

In my AWS infrastructure, API servers running on EC2 instances sit behind an Elastic Load Balancer (ELB) that terminates SSL connections. The ELB forwards requests to Nginx reverse proxy servers, which then route traffic to specific backend servers based on URL patterns. This setup creates several operational challenges:

  • Constant maintenance of Nginx configuration files
  • Manual updates required when backend IPs change
  • No centralized management interface for routing rules
  • Scaling limitations during traffic spikes

AWS offers several services that can replace Nginx proxy functionality:

1. AWS Application Load Balancer (ALB)

ALB provides path-based routing natively. Here's a CloudFormation snippet for path-based routing:

Resources:
  MyALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing
      Type: application
      
  TargetGroup1:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Port: 80
      Protocol: HTTP
      VpcId: vpc-123456
  
  Listener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
      - Type: forward
        TargetGroupArn: !Ref TargetGroup1
      LoadBalancerArn: !Ref MyALB
      Port: 443
      Protocol: HTTPS
      Certificates:
      - CertificateArn: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012
      
  PathRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
      - Type: forward
        TargetGroupArn: !Ref TargetGroup2
      Conditions:
      - Field: path-pattern
        Values: [/api/v1/*]
      ListenerArn: !Ref Listener
      Priority: 1

2. Amazon API Gateway

For more advanced routing needs, API Gateway offers:

  • Native path-based routing
  • Built-in caching
  • Request/response transformation
  • Integration with Lambda and EC2

AWS App Mesh

For microservices architectures, App Mesh provides:

{
  "virtualRouter": {
    "listeners": [
      {
        "portMapping": {
          "port": 8080,
          "protocol": "http"
        }
      }
    ]
  },
  "routes": [
    {
      "httpRoute": {
        "match": {
          "prefix": "/api"
        },
        "action": {
          "weightedTargets": [
            {
              "virtualNode": "api-v1",
              "weight": 90
            },
            {
              "virtualNode": "api-v2",
              "weight": 10
            }
          ]
        }
      }
    }
  ]
}

When moving from Nginx to AWS services, consider:

  • Performance characteristics (ALB has 25+ ms latency vs Nginx's sub-millisecond)
  • Cost implications (API Gateway charges per request)
  • Feature parity (WebSocket support, custom error pages)
  • Monitoring and logging differences

For most use cases, ALB provides the best balance of features, performance and cost when replacing Nginx reverse proxies. The built-in path-based routing eliminates configuration management overhead while providing comparable functionality.


In a typical AWS deployment for API services, we often see this pattern:

HTTPS Request → ELB (SSL Termination) → Nginx (URL Routing) → EC2 Backends

While functional, this setup introduces several operational headaches:

  • Manual Nginx config updates when backend IPs change
  • No centralized management interface for routing rules
  • Additional EC2 instances just for reverse proxy functionality

Option 1: Application Load Balancer (ALB) Path-Based Routing

ALBs can route requests based on URL paths without needing Nginx:

aws elbv2 create-rule \
    --listener-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/my-load-balancer/1234567890123456/1234567890123456 \
    --priority 10 \
    --conditions Field=path-pattern,Values='/api/v1/*' \
    --actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-targets/1234567890123456

Option 2: API Gateway + ALB Integration

For more advanced routing scenarios:

Resources:
  MyApi:
    Type: AWS::ApiGatewayV2::Api
    Properties:
      Name: MyApi
      ProtocolType: HTTP
      RouteKey: 'ANY /api/{proxy+}'
      Target: 
        Arn: !Ref MyALB
        Port: 80

AWS App Mesh for Service Routing

For microservices architectures, App Mesh provides dynamic routing:

{
  "routeName": "api-route",
  "spec": {
    "httpRoute": {
      "match": {
        "prefix": "/api"
      },
      "action": {
        "weightedTargets": [
          {
            "virtualNode": "api-v1-node",
            "weight": 100
          }
        ]
      }
    }
  }
}

Amazon CloudFront + Lambda@Edge

For global routing needs with edge computing:

exports.handler = async (event) => {
    const request = event.Records[0].cf.request;
    
    if (request.uri.startsWith('/api/')) {
        request.origin = {
            custom: {
                domainName: 'api.internal.example.com',
                port: 80,
                protocol: 'http',
                path: '',
                sslProtocols: ['TLSv1.2'],
                readTimeout: 5,
                keepaliveTimeout: 5
            }
        };
    }
    
    return request;
};

When moving from Nginx to cloud-native solutions:

  • Test routing performance under load
  • Implement proper health checks
  • Consider cost implications of managed services
  • Monitor 5xx errors during transition