Post

AWS Load Balancers — ALB, NLB, Target Groups, and Listeners

A full walkthrough of AWS Elastic Load Balancing — ALB vs NLB, listeners, target groups, health checks, sticky sessions, and SSL termination

AWS Load Balancers — ALB, NLB, Target Groups, and Listeners

What is Elastic Load Balancing?

Elastic Load Balancing (ELB) automatically distributes incoming traffic across multiple targets — EC2 instances, containers, Lambda functions, or IP addresses — in one or more Availability Zones. It is the standard way to make applications highly available and scalable on AWS.

If one target becomes unhealthy or an entire AZ goes down, the load balancer stops sending traffic there automatically. When capacity scales up, the load balancer starts sending traffic to new targets immediately.

AWS has three types of load balancers:

TypeLayerProtocolUse Case
Application Load Balancer (ALB)7 (HTTP)HTTP, HTTPS, WebSocketWeb apps, APIs, microservices
Network Load Balancer (NLB)4 (TCP)TCP, UDP, TLSHigh performance, static IP, gaming, VoIP
Gateway Load Balancer (GWLB)3 (IP)All IP trafficThird-party network appliances (firewalls, IDS)

The old Classic Load Balancer is deprecated — do not use it for new workloads.


Application Load Balancer (ALB)

An ALB operates at Layer 7 — it understands HTTP/HTTPS. It can make routing decisions based on the request content: URL path, hostname, headers, query strings, and HTTP method. This is what makes it ideal for microservices — one ALB can route /api/users to one service and /api/orders to another.

Key features

  • Content-based routing — route by path, host, header, query string, method
  • SSL/TLS termination — decrypts HTTPS at the ALB, forwards HTTP to targets (or HTTPS)
  • WebSocket support — long-lived connections for real-time apps
  • HTTP/2 support — between client and ALB (ALB → target is HTTP/1.1)
  • Sticky sessions — route a user’s requests to the same target (cookie-based)
  • User authentication — integrate with Cognito or any OIDC provider before forwarding
  • Lambda targets — invoke a Lambda function from HTTP traffic

Creating an ALB

📸 SCREENSHOT: EC2 → Load Balancers → Create Load Balancer → Application Load Balancer selected. Show the scheme options (Internet-facing vs Internal), VPC selection, and the AZ/subnet mapping section.

1
2
3
4
5
6
7
8
9
10
# Create an internet-facing ALB
aws elbv2 create-load-balancer \
  --name prod-alb \
  --type application \
  --scheme internet-facing \
  --subnets subnet-public-1a subnet-public-1b subnet-public-1c \
  --security-groups sg-alb

# List load balancers
aws elbv2 describe-load-balancers --output table

Scheme:

  • Internet-facing — has a public DNS name, receives traffic from the internet
  • Internal — only reachable within the VPC, used between tiers (e.g. frontend ALB → backend ALB)

Target Groups

A target group is a collection of targets that receive traffic from a load balancer. Targets can be EC2 instances, IP addresses, Lambda functions, or another ALB. Each target group has its own health check configuration.

Target types

TypeUse Case
instanceEC2 instances by instance ID
ipAny IP address — EC2, ECS tasks (awsvpc), on-premises
lambdaA single Lambda function
albAnother ALB (for NLB → ALB chaining)

📸 SCREENSHOT: EC2 → Target Groups → Create Target Group. Show the target type selection (Instance / IP / Lambda / ALB), protocol and port fields, and the VPC dropdown.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Create a target group
aws elbv2 create-target-group \
  --name prod-app-tg \
  --protocol HTTP \
  --port 8080 \
  --vpc-id vpc-0abc123 \
  --target-type instance \
  --health-check-path /health \
  --health-check-interval-seconds 30

# Register targets (EC2 instances)
aws elbv2 register-targets \
  --target-group-arn arn:aws:elasticloadbalancing:...:targetgroup/prod-app-tg/abc123 \
  --targets Id=i-0abc123 Id=i-0def456

# Check target health
aws elbv2 describe-target-health \
  --target-group-arn arn:aws:elasticloadbalancing:...:targetgroup/prod-app-tg/abc123

Health Checks

The load balancer sends periodic requests to each target to check if it is healthy. Unhealthy targets are removed from rotation until they recover.

📸 SCREENSHOT: EC2 → Target Groups → select a group → Health Checks tab. Show the health check path (/health), interval, threshold counts, and the success codes (200).

SettingDefaultMeaning
ProtocolHTTPProtocol for health check requests
Path/URL path to check
Healthy threshold5Consecutive successes to mark healthy
Unhealthy threshold2Consecutive failures to mark unhealthy
Timeout5sHow long to wait for a response
Interval30sTime between checks
Success codes200HTTP status codes that count as healthy

Best practice: create a dedicated /health endpoint in your app that checks database connectivity and returns 200 only when everything is working.


Listeners and Rules

A listener is a process that checks for connection requests using a configured protocol and port. An ALB rule determines what to do with requests that match conditions.

Listeners

1
2
Listener 1: HTTP:80  → redirect to HTTPS (301)
Listener 2: HTTPS:443 → forward to target group (default rule)

📸 SCREENSHOT: EC2 → Load Balancers → select ALB → Listeners tab. Show two listeners (HTTP:80 and HTTPS:443) and the default action for each.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Create an HTTPS listener
aws elbv2 create-listener \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:loadbalancer/app/prod-alb/abc123 \
  --protocol HTTPS \
  --port 443 \
  --certificates CertificateArn=arn:aws:acm:...:certificate/abc-123 \
  --default-actions Type=forward,TargetGroupArn=arn:...:targetgroup/prod-app-tg/abc123

# Create HTTP → HTTPS redirect listener
aws elbv2 create-listener \
  --load-balancer-arn arn:aws:elasticloadbalancing:...:loadbalancer/app/prod-alb/abc123 \
  --protocol HTTP \
  --port 80 \
  --default-actions '[{
    "Type": "redirect",
    "RedirectConfig": {
      "Protocol": "HTTPS",
      "Port": "443",
      "StatusCode": "HTTP_301"
    }
  }]'

Listener Rules

Rules let you route to different target groups based on request content. Rules are evaluated in priority order (lowest number first). The default rule (priority *) matches everything else.

📸 SCREENSHOT: EC2 → Load Balancers → select ALB → Listeners tab → View/edit rules. Show the rules editor with multiple rules — one matching /api/* forwarding to api-tg, one matching /admin/* requiring authentication, and the default rule forwarding to web-tg.

Example routing setup:

1
2
3
4
5
IF path is /api/*       → forward to api-target-group
IF path is /admin/*     → authenticate via Cognito, then forward
IF host is api.myapp.com → forward to api-target-group
IF header X-Version = v2 → forward to v2-target-group
DEFAULT                 → forward to web-target-group
1
2
3
4
5
6
# Add a path-based routing rule
aws elbv2 create-rule \
  --listener-arn arn:aws:elasticloadbalancing:...:listener/app/prod-alb/abc/xyz \
  --priority 10 \
  --conditions '[{"Field":"path-pattern","Values":["/api/*"]}]' \
  --actions '[{"Type":"forward","TargetGroupArn":"arn:...:targetgroup/api-tg/abc"}]'

Network Load Balancer (NLB)

An NLB operates at Layer 4 — it works with raw TCP/UDP packets. It does not read HTTP headers or understand URLs. What it offers instead is extreme performance and static IP addresses.

Key features

  • Ultra-low latency — millions of requests per second, sub-millisecond latency
  • Static IP per AZ — each AZ gets a fixed Elastic IP, useful for firewall whitelisting
  • Preserves client IP — the target sees the original client IP address
  • TLS passthrough or termination — can terminate TLS or pass it to targets
  • Cross-zone load balancing — disabled by default (costs money when enabled)
  • PrivateLink — expose your service to other VPCs without VPC peering

When to use NLB over ALB

Use NLB whenUse ALB when
You need static IP addressesYou need path/host-based routing
Protocol is TCP/UDP (not HTTP)Protocol is HTTP/HTTPS
Extreme performance is neededYou want native HTTP features
You need to preserve client IP at Layer 4You need user authentication
Exposing service via AWS PrivateLinkRouting microservices
1
2
3
4
5
6
# Create an NLB
aws elbv2 create-load-balancer \
  --name prod-nlb \
  --type network \
  --scheme internet-facing \
  --subnets subnet-public-1a subnet-public-1b

SSL/TLS Termination

The ALB handles the SSL handshake and decrypts HTTPS traffic. Your backend targets receive plain HTTP — they do not need to handle SSL. This reduces CPU overhead on your application servers.

ACM Integration

Use AWS Certificate Manager (ACM) to provision free SSL certificates. ACM automatically renews them before they expire.

📸 SCREENSHOT: ACM → Request Certificate → enter domain names. Show the domain validation method (DNS validation recommended) and the CNAME record that ACM creates in Route 53 for validation.

1
2
3
4
5
6
7
8
9
# Request a certificate
aws acm request-certificate \
  --domain-name myapp.com \
  --subject-alternative-names *.myapp.com \
  --validation-method DNS \
  --region eu-west-1

# List certificates
aws acm list-certificates --output table

Once issued, attach the certificate ARN to your ALB HTTPS listener.

End-to-end HTTPS

For sensitive workloads, you may want HTTPS all the way to the target:

1
Client → HTTPS → ALB (SSL termination) → HTTPS → Target

Configure the target group protocol as HTTPS and install a certificate on your application servers. The certificate on the targets can be self-signed or from a private CA — the ALB does not validate it by default (but you can enable validation).


Sticky Sessions

Sticky sessions (session affinity) ensure a user’s requests always go to the same target. Used for applications that store session state on the server (not recommended — use Redis instead, but sometimes you need it for legacy apps).

Stickiness typeCookie nameDuration
Load balancer generatedAWSALB1 second to 7 days
Application-basedCustom cookie nameSet by your app

📸 SCREENSHOT: EC2 → Target Groups → select group → Attributes tab. Show the Stickiness toggle enabled, stickiness type (Load balancer generated), and duration field.


Access Logs

ALB and NLB can log every request to S3. Access logs include: timestamp, client IP, request, response, target, latency, user agent. Useful for debugging, security analysis, and compliance.

1
2
3
4
5
6
aws elbv2 modify-load-balancer-attributes \
  --load-balancer-arn arn:aws:elasticloadbalancing:... \
  --attributes \
    Key=access_logs.s3.enabled,Value=true \
    Key=access_logs.s3.bucket,Value=my-alb-logs \
    Key=access_logs.s3.prefix,Value=prod-alb

Common Architecture

1
2
3
4
5
6
7
8
9
10
11
12
13
Internet
    │
    ▼
[Security Group: allow 80/443 from 0.0.0.0/0]
Application Load Balancer (public subnets, multi-AZ)
    │
    ├── /api/*  → API Target Group
    │              [Security Group: allow 8080 from ALB SG only]
    │              EC2 instances in private subnets
    │
    └── /*      → Web Target Group
                   [Security Group: allow 3000 from ALB SG only]
                   EC2 instances in private subnets

The ALB sits in public subnets and is the only resource that accepts public traffic. The EC2 instances sit in private subnets and only accept traffic from the ALB’s security group.


Quick Reference

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Load balancers
aws elbv2 describe-load-balancers --output table

# Target groups
aws elbv2 describe-target-groups --output table

# Target health
aws elbv2 describe-target-health --target-group-arn ARN

# Listeners
aws elbv2 describe-listeners --load-balancer-arn ARN

# Rules
aws elbv2 describe-rules --listener-arn ARN

# Register/deregister targets
aws elbv2 register-targets --target-group-arn ARN --targets Id=i-xxx
aws elbv2 deregister-targets --target-group-arn ARN --targets Id=i-xxx

You can find me online at:

My signature image

This post is licensed under CC BY 4.0 by the author.