Skip to main content

Nginx Ingress with AWS NLB (deprecated in favor of Gateway API)

Setting up a single NLB to handle multiple domains through NGINX is a “power-user” architecture. It’s cost-effective, high-performance, and gives you total control over your routing. Since it is 2026, the Kubernetes community is actually shifting toward the Gateway API, but the NGINX + NLB approach remains the industry standard for production flexibility.

1. The High-Level Flow

To make this work, we use the AWS Load Balancer Controller to manage the NLB and the NGINX Ingress Controller to manage the internal routing.
  1. Route 53: Points app1.example.com and app2.example.com to the same NLB DNS.
  2. NLB (AWS): Terminates TLS using your ACM Certificate. It listens on port 443 and sends plain HTTP (port 80) to the NGINX pods.
  3. NGINX Ingress (K8s): Reads the Host header (e.g., “https://www.google.com/url?sa=E&source=gmail&q=app1.example.com”) and routes the traffic to the correct Service.
  4. Apps: Your apps receive the traffic and respond.

2. Step-by-Step Setup

Step A: The ACM Certificate

You need one certificate that covers both domains.
  • Recommendation: Request a wildcard certificate in AWS Certificate Manager (ACM) for *.example.com.
  • Why: This allows you to add app3, app4, etc., later without changing your infrastructure.

Step B: Install AWS Load Balancer Controller

This is the “bridge” between K8s and AWS. It watches your services and creates the NLB.
# 1. Create IAM Policy & Service Account (IRSA)
# 2. Install via Helm
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=my-cluster \
  --set serviceAccount.create=false \
  --set serviceAccount.name=aws-load-balancer-controller

Step C: Install NGINX Ingress with NLB + ACM

We tell NGINX to create a Service of type LoadBalancer. The magic is in the annotations.
# nginx-values.yaml
controller:
  service:
    annotations:
      # Tell AWS to create an NLB
      service.beta.kubernetes.io/aws-load-balancer-type: "external"
      service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
      service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
      
      # TLS Termination at NLB
      service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:region:account:certificate/ID
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
      
      # Force the NLB to talk to NGINX over HTTP (since SSL is finished at NLB)
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"

Deploy using: helm install ingress-nginx ingress-nginx/ingress-nginx -f nginx-values.yaml

3. Creating the Application Routes

Now that the “Highway” (NLB) and “Reception” (NGINX) are ready, you just define your apps.

App 1 Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app1-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: app1.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80

App 2 Ingress

You create a second file exactly like the one above, but change the host to app2.example.com and the service to app2-service. NGINX handles the split automatically!

4. Scale & Industry Use Cases

The Scale

  • Throughput: A single NLB can handle millions of requests per second. It is significantly faster and more “rugged” than an ALB.
  • Limits: NGINX is only limited by the CPU/Memory you give the pods. You can use HPA (Horizontal Pod Autoscaler) to add more NGINX pods as traffic grows.

Who uses what?

ApproachTypical UsersWhy?
ALB IngressStartups / Small Teams (e.g., Buffer, smaller SaaS)Zero maintenance. AWS does all the heavy lifting. Good if you have < 50 services.
NLB + NGINXEnterprise / High Scale (e.g., Airbnb, Reddit, Tinder)Cost: 1 NLB for 500 apps is way cheaper than 500 ALBs. Speed: Lower latency for massive traffic. Control: They need custom logic (like Lua scripts or specialized headers) that ALB doesn’t support.
Note for 2026: Ingress-NGINX (community version) is currently moving toward a maintenance-only mode. Many big companies are migrating from NGINX to Envoy Gateway or Traefik using the same NLB logic you just learned.