
Elastic Load Balancing (ELB)AuthorCloudBrum editorial teamLast reviewedReading time~12 minLevelBeginner to advanced
Amazon Web Services · Networking · Application, Network and Gateway load balancers
Elastic Load Balancing spreads incoming traffic over your servers and sends it only to the ones that are healthy. AWS offers three kinds for new designs: the Application Load Balancer for HTTP, HTTPS and gRPC, the Network Load Balancer for TCP, UDP and TLS at very high speed, and the Gateway Load Balancer for traffic that must pass through a firewall appliance first. Pick by the type of traffic, and then spend your attention on target groups and health checks, because that is where most outages and most surprises start.
On this page (17 sections)
Mind map: Elastic Load Balancing at a glance
Free to share. The downloaded image includes the CloudBrum link.
Key features (summary)
- Three current typesThe Application Load Balancer works on requests, the Network Load Balancer on connections and packets, and the Gateway Load Balancer inserts appliances such as firewalls into the path. The Classic Load Balancer is the older generation and best left to existing systems.
- Rules on the request (ALB)A listener rule can match the host name, path, header, query string, method or source address, and then forward, redirect, answer with a fixed response, verify a token or authenticate the user first. Rewrite rules for URL and host header arrived in 2025.
- Speed and fixed addresses (NLB)A Network Load Balancer handles millions of requests a second at very low latency, can give each zone a static or Elastic IP address, preserves the client’s source address and is the front of an AWS PrivateLink service.
- Health checks and failoverEvery target group has a health check. A target that fails it stops receiving traffic until it passes again, and a load balancer routes around a failed zone.
- Weighted routingShare traffic between target groups by weight to run a canary or a blue/green release, and shift it by changing two numbers.
- TLS and sign-inTerminate TLS with free ACM certificates and a security policy that you choose. An Application Load Balancer can also run OIDC or Cognito sign-in, verify JWTs, and require client certificates (mutual TLS).
- Many kinds of targetEC2 instances, IP addresses (including servers on premises over a VPN or Direct Connect), containers on ECS and EKS, and Lambda functions behind an Application Load Balancer.
- It scales for youThe service adds capacity as traffic grows, within account limits. For a launch with a known sharp spike, a capacity reservation lets an Application Load Balancer start with a floor of capacity.
Basic concepts
- Load balancer types
- ALB for HTTP and gRPC (layer 7), NLB for TCP, UDP and TLS (layer 4), GWLB for transparent appliance chains (layer 3), and the Classic Load Balancer for old designs.
- Listener
- A process that checks for connection requests on a port and protocol, such as HTTPS on 443. Its default action and rules decide what happens to each request.
- Target group
- A set of targets that a listener rule forwards to, with its own protocol, port and health check.
- Target
- One destination: an instance, an IP address or a Lambda function. Instances and IPs are registered with a port.
- Health check
- A probe that the load balancer sends to each target. A target is healthy after enough successes and unhealthy after enough failures.
- Rule (ALB)
- A condition and an action on a listener, with a priority. The lowest priority number that matches wins, and the default rule catches the rest.
- Cross-zone load balancing
- Spreads requests evenly over all targets in all enabled zones. It’s on by default for ALB, and off by default for NLB and GWLB, where crossing zones can also add data transfer cost.
- Deregistration delay
- How long the load balancer lets in-flight requests finish after a target is removed. The default is 300 seconds, which is often longer than a deployment needs.
- Stickiness
- Sends one client to the same target for a period, using a cookie on ALB. It helps stateful apps and unbalances load if overused.
- Load balancer capacity unit (LCU)
- The ALB billing unit. It is the highest of four measures: new connections, active connections, processed bytes and rule evaluations. NLB uses NLCUs, and GWLB uses GLCUs.
- Security policy
- A named set of TLS protocol versions and ciphers offered to clients on an HTTPS or TLS listener.
- Access logs
- Optional per-request logs written to S3, with the client, target, status codes and timing. They are off by default.
- Weighted target group
- A forward action over several target groups with weights, used for canary and blue/green releases.
How to create & configure it
Put a web service behind an Application Load Balancer with the AWS CLI
- Choose the typeUse an Application Load Balancer for web traffic. Choose a Network Load Balancer for non-HTTP protocols, fixed IP addresses or extreme speed, and a Gateway Load Balancer for firewall appliances.
- Plan the network and the security groupsPut the load balancer in public subnets in at least two zones, and the targets in private ones. Let the targets accept traffic only from the load balancer’s security group.
- Create the target group and a real health checkPoint the check at a path that tests what matters, such as /health, expect a 200, and set thresholds so that a restart doesn’t cause flapping.
- Create the load balancer with safe attributesTurn on deletion protection and the dropping of invalid headers, and decide the idle timeout.
- Add the listenersMake port 80 redirect to HTTPS. On port 443 use an ACM certificate in the same Region and a current TLS security policy.
- Add rules and weightsSend /api/* to its own target group, and use weighted target groups for canary releases.
- Register targets and drain them properlyShorten the deregistration delay to what your requests need, so deployments don’t wait five minutes per instance.
- Turn on logs and alarmsWrite access logs to S3 and alarm on HTTPCode_ELB_5XX_Count, UnHealthyHostCount and TargetResponseTime.
- Test failure on purposeStop a target and a whole zone in a test environment, and watch that traffic moves and alarms fire.
Tip: set your application’s keep-alive timeout higher than the load balancer’s idle timeout (60 seconds by default). If the server closes the connection first, the load balancer sometimes sends a request down a connection that has just died, which shows up as occasional 502 errors. See the code references for the same setup as Terraform.
Common issues after configuration
| Symptom | Likely cause | What to check / fix |
|---|---|---|
| 502 Bad Gateway | The target closed the connection or sent an invalid response, often because its keep-alive timeout is shorter than the load balancer’s idle timeout | Raise the application’s keep-alive timeout above the idle timeout, and check that the app returns valid HTTP responses. |
| 503 Service Unavailable | The target group has no registered targets, or none are healthy | Register targets, look at the health state and the reason code, and fix what fails the check. |
| 504 Gateway Timeout | The target didn’t answer within the idle timeout, or a security group or network ACL blocks the path | Find the slow request, raise the timeout only if the work is meant to be slow, and check that the target’s security group allows the load balancer. |
| Targets show unhealthy | The health check path returns something other than the expected code, the port is wrong, or the target’s security group blocks the load balancer | Call the health check path from another host in the VPC, match the port and success codes, and allow the load balancer’s security group. |
| The application sees the load balancer’s address, not the client’s | An Application Load Balancer opens its own connection to the target | Read the X-Forwarded-For header on ALB, and use client IP preservation or proxy protocol on NLB. |
| One server is busier than the rest | Round-robin sends requests blindly, sticky sessions pin clients, long-lived HTTP/2 or gRPC connections stay on one target, or cross-zone is off with uneven targets per zone | Use least outstanding requests, limit stickiness, add targets evenly per zone, or turn on cross-zone. |
| A redirect loop after moving TLS to the load balancer | The load balancer terminates HTTPS and the app sees HTTP and redirects again | Trust X-Forwarded-Proto in the application, or stop redirecting at the app. |
| A browser shows a certificate warning | The certificate doesn’t cover the host name, an ACM certificate from another Region was chosen, or the wrong SNI certificate is the default | Use an ACM certificate in the load balancer’s Region that lists the name, and add other certificates for other names. |
| Long connections are cut off | Idle connections exceed the timeout (60 seconds on ALB by default, 350 for TCP on NLB) | Send keep-alive traffic from the client or server, or raise the idle timeout. |
| Deployments take very long | The 300-second deregistration delay waits for each instance, and slow start delays new ones | Lower the delay to the longest real request, and plan the rollout in batches. |
| The bill is higher than expected | Many new connections, large data volumes, many rules, idle load balancers or public IPv4 addresses on every load balancer | Check LCU dimensions in the bill, share one ALB between services with host rules, delete unused load balancers and use IPv6 or private addresses where you can. |
Use cases: when and where to use it
Good fit
- Web applications and APIs that run on more than one instance or container
- Microservices that share one entry point with host and path rules
- Blue/green and canary releases using weighted target groups
- TCP and UDP services, such as game servers or databases proxies, that need very low latency and fixed IP addresses
- Service endpoints exposed to other accounts or VPCs through AWS PrivateLink
- Traffic that must pass through third-party firewalls or inspection appliances
Consider something else
- Caching and speeding up delivery worldwide → Amazon CloudFront
- Fixed global entry addresses with fast Regional failover → AWS Global Accelerator
- Routing between Regions with DNS health checks → Amazon Route 53
- A managed API front door with throttling and keys → Amazon API Gateway
- Service-to-service routing inside a mesh → Amazon VPC Lattice or an App Mesh style proxy
- The same job on other clouds → compare Azure Load Balancer and Cloud Load Balancing
Pros: why consider it?
Why teams choose it
- Managed: AWS runs, patches and scales the load balancer
- Health checks and multi-zone spread give high availability with little work
- Rich routing and sign-in on the Application Load Balancer
- Very fast, fixed-address load balancing on the Network Load Balancer
- Integrates with ACM, WAF, Auto Scaling, ECS, EKS and CloudWatch
- Weighted target groups make canary releases simple
Trade-offs to weigh
- It is regional, so a multi-Region design needs Route 53, Global Accelerator or both
- Billing has several parts, and an idle load balancer still costs money
- Defaults such as the 300-second deregistration delay and the 60-second idle timeout surprise people
- Public IPv4 addresses on load balancers now carry a charge
- The Network Load Balancer has no layer 7 features, and the Application Load Balancer has no static IPs
- Debugging 5xx errors needs logs from both the load balancer and the target
Common threats, vulnerabilities & risks
| Risk | Severity | Why it matters | Mitigation |
|---|---|---|---|
| Targets reachable directly | High | If the target’s security group allows the whole internet, people can skip the load balancer, its WAF and its TLS settings. | Allow only the load balancer’s security group on the target’s port, and keep targets in private subnets. |
| Plain HTTP serving content | High | Traffic on port 80 can be read or changed on the way. | Redirect port 80 to HTTPS at the listener, and use a current TLS security policy. |
| No web application firewall on a public ALB | High | Common attacks and bots reach the application unfiltered. | Attach AWS WAF to the load balancer, with rate rules and managed rule groups. |
| Unsafe handling of HTTP requests | Medium | Invalid header fields and request smuggling can confuse backends. | Drop invalid header fields, use the defensive or strictest desync mitigation mode and keep servers patched. |
| A health check that tells nothing | Medium | A check that always passes sends traffic to broken servers, and one that depends on a flaky dependency removes every server at once. | Check the process and the local state it cannot work without, and keep dependency checks out of the load balancer health check. |
| Deletion protection off | Medium | An accidental delete removes the entry point and its DNS target. | Turn on deletion protection, and restrict DeleteLoadBalancer. |
| No access logs | Medium | Without logs you can’t investigate attacks or errors afterwards. | Enable access logs to a locked-down S3 bucket and set a retention rule. |
| Cross-zone and zonal imbalance | Low–Med | Uneven targets per zone overload some servers, or cross-zone traffic raises transfer cost. | Keep targets balanced per zone, and choose cross-zone deliberately. |
| Forgotten load balancers | Low–Med | Each one bills hourly, plus an IPv4 address, even with no traffic. | Tag load balancers with an owner, and review those with no requests every month. |
Performance optimisation
- Use least outstanding requests on target groups with uneven request times, instead of round robin.
- Spread targets evenly over zones, and turn on cross-zone balancing where counts are uneven.
- Keep the application’s keep-alive timeout higher than the load balancer’s idle timeout, to avoid 502 errors on reused connections.
- Lower the deregistration delay to the length of your longest request, so rollouts are quick.
- Use slow start for targets that need time to warm caches or JIT code.
- Use HTTP/2 and gRPC support on the Application Load Balancer, and a Network Load Balancer for the very lowest latency.
- Put CloudFront in front for cacheable content, so the load balancer handles less traffic.
- Request a capacity reservation before a launch or sale with a known spike.
Reduce monthly cost
FinOps is the habit of managing cloud spend together with engineering. These are the FinOps checks that matter most for Elastic Load Balancing.
- Share one Application Load Balancer between several services with host and path rules, instead of one load balancer per service.
- Delete unused load balancers and target groups. Each load balancer bills by the hour.
- Watch the LCU dimension that drives your bill: new connections, active connections, bytes or rule evaluations.
- Reduce new connections with keep-alive and HTTP/2 between clients and the load balancer.
- Keep rules to what you need, since rule evaluations count towards LCUs beyond a free allowance.
- Account for public IPv4 addresses, which carry an hourly charge, and use internal load balancers where traffic is private.
- Cut cross-zone data transfer for chatty services by keeping traffic in the zone where it started, where the design allows.
- Put CloudFront in front of cacheable content and use its free allowance.
- Choose NLB or ALB for the traffic you actually have: each uses different capacity units.
- Tag load balancers by team and add a budget alert on Elastic Load Balancing spend.
Figures here come from AWS's pricing page and published guides, read in October 2026. The sources quote US East rates and other Regions differ, so check the live page (see Pricing).
Security optimisation
- Allow only the load balancer’s security group on the target’s port, and keep targets in private subnets.
- Terminate TLS with ACM certificates and a current security policy such as the TLS 1.3 policies.
- Redirect HTTP to HTTPS, and add HSTS in the application or at CloudFront.
- Attach AWS WAF to public Application Load Balancers.
- Turn on drop invalid header fields and a defensive desync mitigation mode.
- Use OIDC or Cognito sign-in, JWT verification or mutual TLS on the Application Load Balancer for protected apps.
- Enable access logs and connection logs to a restricted S3 bucket, and keep them for the period your rules require.
- Turn on deletion protection and restrict who can modify listeners, rules and attributes.
- Use internal load balancers and PrivateLink for services that shouldn’t be on the internet.
- Alert on CloudTrail events for listener, rule, certificate and security group changes.
Governance & compliance
Guardrails
- A shared Terraform module for load balancers that sets deletion protection, header dropping, access logs, a TLS policy and tags
- A service control policy that blocks internet-facing load balancers without a web ACL where your rules require one
- A naming standard for target groups and rules, with the owner and the health check explained for each
- A review step for new listeners, covering the certificate, the security policy and the redirect from port 80
Continuous checks (AWS Config, Security Hub and your own scripts)
- A scheduled script that lists load balancers with logs off, deletion protection off, HTTP listeners that don’t redirect or old TLS policies (the C# tab does this)
- AWS Config rules and Security Hub controls for Elastic Load Balancing, where your standard includes them
- Alarms on HTTPCode_ELB_5XX_Count, UnHealthyHostCount and TargetResponseTime
- A CloudTrail alert for changes to listeners, certificates and security groups
- A monthly report of load balancers with no traffic
AWS CloudTrail shows who changed a load balancer, AWS Config stores each setting over time, Security Hub scores them against standards, and AWS Artifact holds compliance reports. AWS runs and scales the load balancer nodes. Listener and rule design, certificates, target security, logging and what a health check really tests are yours.
Reduce carbon footprint
- Share load balancers between services and delete idle ones.
- Use cacheable content through CloudFront, so fewer requests reach the load balancer and your servers.
- Right-size the fleet behind it with auto scaling, so servers aren’t idle.
- Keep traffic within a zone and Region where the design allows.
- When data rules and latency allow, run the workload in a Region with a cleaner power grid.
- The AWS carbon tool reports per account and does not list Elastic Load Balancing on its own, so quote no ELB figure.
Pricing
Purchase options
Application Load Balancer $0.0225/h plus $0.008/LCU-h
About $0.0225 per hour plus $0.008 per LCU-hour, US East (N. Virginia) rates quoted in recent guides. An LCU covers 25 new connections a second, 3,000 active connections a minute, 1 GB an hour of processed bytes or 1,000 rule evaluations a second, whichever is highest.
Network Load Balancer $0.0225/h plus $0.006/NLCU-h
About $0.0225 per hour plus $0.006 per NLCU-hour. A capacity unit measures new connections, active connections and processed bytes for TCP, UDP and TLS, and the highest dimension is billed.
Gateway Load Balancer Per hour plus per capacity unit
Billed per hour and by the data processed through the appliance endpoints. Appliance and data transfer charges come on top.
Public IPv4 addresses About $0.005 per address-hour
Every public IPv4 address that a load balancer uses is billed, under VPC pricing. Cross-zone and cross-Region data transfer is billed separately.
What you actually pay for
- Each load balancer for every hour it exists
- Load balancer capacity units, by the highest dimension in each hour
- Public IPv4 addresses attached to the load balancer
- Data transfer across zones, Regions or out to the internet
- Optional extras such as a capacity reservation, WAF rules and access log storage
AWS lists the hourly and capacity unit rates, and any free tier for new accounts, on its pricing page, and rates differ by Region. See the official Elastic Load Balancing pricing page and the AWS Pricing Calculator.
Important code references
A web service behind an Application Load Balancer: security groups, a target group with a real health check and sensible attributes, a load balancer with deletion protection, an HTTP listener that redirects, an HTTPS listener with a TLS 1.3 policy, an API path rule and a 90/10 canary. The CLI tab builds it and reads target health and error metrics; Terraform describes the same resources. The Python tab shifts canary traffic, lists unhealthy targets and drains an instance, and the C# tab audits every load balancer for logs, protection, HTTP listeners and old TLS policies. Replace the Region, the certificate and the instance with your own.
# Placeholders: replace the Region, the certificate and the instance with your own. This uses the default VPC; use private subnets for targets in production.
REGION=ap-south-1
CERT_ARN=arn:aws:acm:$REGION:123456789012:certificate/11111111-2222-3333-4444-555555555555
INSTANCE_ID=i-0123456789abcdef0
VPC_ID=$(aws ec2 describe-vpcs --region $REGION --filters Name=is-default,Values=true --query "Vpcs[0].VpcId" --output text)
SUBNETS=$(aws ec2 describe-subnets --region $REGION --filters Name=vpc-id,Values=$VPC_ID --query "Subnets[0:2].SubnetId" --output text)
# 1. Two security groups. The load balancer accepts web traffic from anywhere, and the targets accept it only from the load balancer.
ALB_SG=$(aws ec2 create-security-group --region $REGION --group-name web-alb --description "Load balancer" --vpc-id $VPC_ID --query GroupId --output text)
APP_SG=$(aws ec2 create-security-group --region $REGION --group-name web-app --description "Web servers" --vpc-id $VPC_ID --query GroupId --output text)
aws ec2 authorize-security-group-ingress --region $REGION --group-id $ALB_SG --protocol tcp --port 80 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --region $REGION --group-id $ALB_SG --protocol tcp --port 443 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --region $REGION --group-id $APP_SG --protocol tcp --port 8080 --source-group $ALB_SG
# 2. A target group with a health check on /health. Short deregistration delay and least-outstanding-requests routing suit short requests.
TG_ARN=$(aws elbv2 create-target-group --region $REGION --name web --protocol HTTP --port 8080 --vpc-id $VPC_ID --target-type instance \
--health-check-path /health --health-check-interval-seconds 15 --healthy-threshold-count 3 --unhealthy-threshold-count 2 \
--matcher HttpCode=200 --query "TargetGroups[0].TargetGroupArn" --output text)
aws elbv2 modify-target-group-attributes --region $REGION --target-group-arn $TG_ARN --attributes \
Key=deregistration_delay.timeout_seconds,Value=30 Key=load_balancing.algorithm.type,Value=least_outstanding_requests Key=slow_start.duration_seconds,Value=30
aws elbv2 register-targets --region $REGION --target-group-arn $TG_ARN --targets Id=$INSTANCE_ID,Port=8080
# 3. The Application Load Balancer, with deletion protection and invalid HTTP headers dropped.
ALB_ARN=$(aws elbv2 create-load-balancer --region $REGION --name web-alb --type application --scheme internet-facing \
--subnets $SUBNETS --security-groups $ALB_SG --query "LoadBalancers[0].LoadBalancerArn" --output text)
aws elbv2 modify-load-balancer-attributes --region $REGION --load-balancer-arn $ALB_ARN --attributes \
Key=deletion_protection.enabled,Value=true Key=routing.http.drop_invalid_header_fields.enabled,Value=true Key=idle_timeout.timeout_seconds,Value=60
# 4. Port 80 only redirects to HTTPS. Port 443 terminates TLS with the certificate and a current security policy, then forwards.
aws elbv2 create-listener --region $REGION --load-balancer-arn $ALB_ARN --protocol HTTP --port 80 \
--default-actions "Type=redirect,RedirectConfig={Protocol=HTTPS,Port=443,StatusCode=HTTP_301}"
HTTPS_ARN=$(aws elbv2 create-listener --region $REGION --load-balancer-arn $ALB_ARN --protocol HTTPS --port 443 \
--ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 --certificates CertificateArn=$CERT_ARN \
--default-actions Type=forward,TargetGroupArn=$TG_ARN --query "Listeners[0].ListenerArn" --output text)
# 5. A path rule: /api/* goes to its own target group.
API_TG=$(aws elbv2 create-target-group --region $REGION --name api --protocol HTTP --port 8081 --vpc-id $VPC_ID --target-type instance \
--health-check-path /health --query "TargetGroups[0].TargetGroupArn" --output text)
aws elbv2 create-rule --region $REGION --listener-arn $HTTPS_ARN --priority 10 \
--conditions Field=path-pattern,Values=/api/* --actions Type=forward,TargetGroupArn=$API_TG
# 6. Send 10 percent of traffic to a new version by weighting two target groups on the default action. Set the weights back to move on.
CANARY_TG=$(aws elbv2 create-target-group --region $REGION --name web-canary --protocol HTTP --port 8080 --vpc-id $VPC_ID --target-type instance \
--health-check-path /health --query "TargetGroups[0].TargetGroupArn" --output text)
aws elbv2 modify-listener --region $REGION --listener-arn $HTTPS_ARN --default-actions \
"Type=forward,ForwardConfig={TargetGroups=[{TargetGroupArn=$TG_ARN,Weight=90},{TargetGroupArn=$CANARY_TG,Weight=10}]}"
# 7. Which targets are healthy, and why not? The reason code points at the problem (for example Target.Timeout or Target.ResponseCodeMismatch).
aws elbv2 describe-target-health --region $REGION --target-group-arn $TG_ARN \
--query "TargetHealthDescriptions[].{target:Target.Id,state:TargetHealth.State,reason:TargetHealth.Reason}"
# 8. Load balancer errors and unhealthy hosts over the last hour.
LB_DIM=$(echo $ALB_ARN | cut -d/ -f2-)
aws cloudwatch get-metric-statistics --region $REGION --namespace AWS/ApplicationELB --metric-name HTTPCode_ELB_5XX_Count \
--dimensions Name=LoadBalancer,Value=$LB_DIM --statistics Sum --period 300 \
--start-time $(date -u -d '-1 hour' +%FT%TZ) --end-time $(date -u +%FT%TZ)
# Placeholders: pass in your own certificate and instance. This uses the default VPC; use private subnets for targets in production.
variable "region" {
type = string
default = "ap-south-1"
}
variable "certificate_arn" {
type = string
}
variable "instance_id" {
type = string
}
provider "aws" {
region = var.region
}
data "aws_vpc" "default" {
default = true
}
data "aws_subnets" "default" {
filter {
name = "vpc-id"
values = [data.aws_vpc.default.id]
}
}
# The load balancer accepts web traffic from anywhere. The targets accept it only from the load balancer.
resource "aws_security_group" "alb" {
name = "web-alb"
description = "Load balancer"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "app" {
name = "web-app"
description = "Web servers"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 8080
to_port = 8080
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_lb_target_group" "web" {
name = "web"
port = 8080
protocol = "HTTP"
vpc_id = data.aws_vpc.default.id
target_type = "instance"
deregistration_delay = 30
slow_start = 30
load_balancing_algorithm_type = "least_outstanding_requests"
health_check {
path = "/health"
interval = 15
healthy_threshold = 3
unhealthy_threshold = 2
matcher = "200"
}
}
resource "aws_lb_target_group" "api" {
name = "api"
port = 8081
protocol = "HTTP"
vpc_id = data.aws_vpc.default.id
target_type = "instance"
health_check {
path = "/health"
}
}
resource "aws_lb_target_group_attachment" "web" {
target_group_arn = aws_lb_target_group.web.arn
target_id = var.instance_id
port = 8080
}
resource "aws_lb" "web" {
name = "web-alb"
load_balancer_type = "application"
internal = false
subnets = slice(data.aws_subnets.default.ids, 0, 2)
security_groups = [aws_security_group.alb.id]
enable_deletion_protection = true
drop_invalid_header_fields = true
idle_timeout = 60
}
# Port 80 only redirects to HTTPS.
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.web.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.web.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = var.certificate_arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web.arn
}
}
resource "aws_lb_listener_rule" "api" {
listener_arn = aws_lb_listener.https.arn
priority = 10
action {
type = "forward"
target_group_arn = aws_lb_target_group.api.arn
}
condition {
path_pattern {
values = ["/api/*"]
}
}
}
output "dns_name" {
value = aws_lb.web.dns_name
}
# pip install boto3
# Moves a share of traffic to a canary target group, lists the targets that are not healthy, and drains an instance before it is stopped.
import boto3
elbv2 = boto3.client("elbv2", region_name="ap-south-1")
def set_canary(listener_arn, stable_arn, canary_arn, percent):
"""Sends `percent` of new requests to the canary target group. percent=0 sends everything back to the stable one."""
elbv2.modify_listener(ListenerArn=listener_arn, DefaultActions=[{
"Type": "forward",
"ForwardConfig": {"TargetGroups": [
{"TargetGroupArn": stable_arn, "Weight": 100 - percent},
{"TargetGroupArn": canary_arn, "Weight": percent},
]},
}])
def unhealthy(target_group_arn):
"""Returns (target id, state, reason) for every target that is not healthy. The reason says why, for example Target.Timeout."""
reply = elbv2.describe_target_health(TargetGroupArn=target_group_arn)
return [(d["Target"]["Id"], d["TargetHealth"]["State"], d["TargetHealth"].get("Reason", ""))
for d in reply["TargetHealthDescriptions"] if d["TargetHealth"]["State"] != "healthy"]
def drain(target_group_arn, instance_id, port=8080):
"""Takes the instance out of rotation and waits until in-flight requests have finished (the deregistration delay)."""
target = {"Id": instance_id, "Port": port}
elbv2.deregister_targets(TargetGroupArn=target_group_arn, Targets=[target])
elbv2.get_waiter("target_deregistered").wait(TargetGroupArn=target_group_arn, Targets=[target],
WaiterConfig={"Delay": 10, "MaxAttempts": 40})
if __name__ == "__main__":
group = elbv2.describe_target_groups(Names=["web"])["TargetGroups"][0]["TargetGroupArn"]
print("not healthy:", unhealthy(group) or "none")
// dotnet add package AWSSDK.ElasticLoadBalancingV2
// Audits every load balancer in the Region: deletion protection, dropping invalid headers, access logs,
// HTTP listeners that do not redirect to HTTPS, and old TLS security policies.
using Amazon.ElasticLoadBalancingV2;
using Amazon.ElasticLoadBalancingV2.Model;
using var elb = new AmazonElasticLoadBalancingV2Client();
int problems = 0;
string? marker = null;
do
{
var page = await elb.DescribeLoadBalancersAsync(new DescribeLoadBalancersRequest { Marker = marker });
foreach (LoadBalancer lb in page.LoadBalancers)
{
var attributes = (await elb.DescribeLoadBalancerAttributesAsync(new DescribeLoadBalancerAttributesRequest { LoadBalancerArn = lb.LoadBalancerArn }))
.Attributes.ToDictionary(a => a.Key, a => a.Value);
if (attributes.GetValueOrDefault("deletion_protection.enabled") != "true")
{
Console.WriteLine($"{lb.LoadBalancerName}: deletion protection is off");
problems++;
}
if (attributes.GetValueOrDefault("access_logs.s3.enabled") != "true")
{
Console.WriteLine($"{lb.LoadBalancerName}: access logs are off");
problems++;
}
if (lb.Type == LoadBalancerTypeEnum.Application && attributes.GetValueOrDefault("routing.http.drop_invalid_header_fields.enabled") != "true")
{
Console.WriteLine($"{lb.LoadBalancerName}: invalid HTTP header fields are not dropped");
problems++;
}
var listeners = (await elb.DescribeListenersAsync(new DescribeListenersRequest { LoadBalancerArn = lb.LoadBalancerArn })).Listeners;
foreach (Listener listener in listeners)
{
if (listener.Protocol == ProtocolEnum.HTTP && !listener.DefaultActions.Any(a => a.Type == ActionTypeEnum.Redirect))
{
Console.WriteLine($"{lb.LoadBalancerName}:{listener.Port}: HTTP listener does not redirect to HTTPS");
problems++;
}
if (listener.Protocol == ProtocolEnum.HTTPS && !(listener.SslPolicy ?? "").Contains("TLS13"))
{
Console.WriteLine($"{lb.LoadBalancerName}:{listener.Port}: security policy {listener.SslPolicy} does not offer TLS 1.3");
problems++;
}
}
}
marker = page.NextMarker;
} while (marker != null);
Console.WriteLine(problems == 0 ? "No problems found." : $"{problems} problem(s) found.");
return problems == 0 ? 0 : 1;
Best videos to explore
Videos picked for this service. Each one is labelled with its source, opens on YouTube if you prefer, and loads only when you press play.
Interview questions
BasicWhat is Elastic Load Balancing?
It’s the AWS service that spreads incoming traffic over several targets, such as EC2 instances, containers, IP addresses or Lambda functions, and sends requests only to targets that pass health checks. That gives an application more capacity and keeps it available if a server or a whole zone fails.
BasicWhat is the difference between an Application Load Balancer and a Network Load Balancer?
An Application Load Balancer works at layer 7 and understands HTTP, so it can route by host, path or header, redirect, and sign users in. A Network Load Balancer works at layer 4 on TCP, UDP and TLS connections, is faster, can have static IP addresses and keeps the client’s source address, but it can’t look inside the request.
BasicWhat are a listener, a target group and a health check?
A listener waits for connections on a port and protocol and decides what to do with them. A target group is the set of destinations a rule forwards to. A health check is a regular probe of each target, and only healthy targets receive traffic.
IntermediateWhat does cross-zone load balancing do, and what are the defaults?
With cross-zone enabled each load balancer node spreads requests over targets in all enabled zones, which evens the load when zones have different numbers of targets. It is on by default for Application Load Balancers and off by default for Network and Gateway Load Balancers, where crossing zones can add data transfer cost.
IntermediateWhy do you sometimes see 502 errors that come and go?
Often the target’s keep-alive timeout is shorter than the load balancer’s idle timeout. The target closes an idle connection at the moment the load balancer reuses it, and the request fails. Set the application’s keep-alive timeout above the idle timeout, and also check for crashes and invalid responses in the target logs.
IntermediateHow do you run a canary release with an Application Load Balancer?
Create a target group for the new version, and change the listener’s forward action to two target groups with weights, for example 90 and 10. Watch error rates and latency for each group, move the weights in steps, and set the new group to 100 when you are happy. Setting the old group back to 100 is the rollback.
AdvancedHow would you design a highly available, secure public web tier?
Place an internet-facing Application Load Balancer in public subnets across at least two zones, and the instances or containers in private subnets that accept traffic only from the load balancer’s security group. Use an ACM certificate, a TLS 1.3 policy and a redirect from port 80, attach WAF, drop invalid headers, enable access logs and deletion protection, and add an Auto Scaling group with health checks that match the load balancer’s.
AdvancedWhen would you choose a Network Load Balancer, and how does client IP handling differ?
Choose it for non-HTTP protocols, very high connection rates, static or Elastic IP addresses, and PrivateLink services. With instance targets it can preserve the client’s source address, and for IP targets it can pass it with proxy protocol v2. An Application Load Balancer always opens a new connection to the target and tells you the client in the X-Forwarded-For header.
AdvancedHow do you troubleshoot a rise in 5xx responses?
Separate errors the load balancer generated from errors the target returned, using HTTPCode_ELB_5XX_Count and HTTPCode_Target_5XX_Count. Look at target health and reason codes, access logs for status, target processing time and error reason, then the application logs for the same request ID. Common causes are unhealthy or overloaded targets, mismatched timeouts, deployments that drained too fast, and security group changes.
AdvancedHow do you control the cost of load balancing across many services?
Share Application Load Balancers across services with host and path rules, delete unused ones, and check which LCU dimension sets each bill. Reduce new connections with keep-alive, limit rules, avoid public IPv4 addresses where a private or IPv6 design works, put CloudFront in front of cacheable content and review cross-zone data transfer. Tag every load balancer with an owner so waste is visible.
Similar or alternative services on other clouds
| Capability | AWS | Azure | Google Cloud |
|---|---|---|---|
| Service | Elastic Load Balancing | Azure Load Balancer and Azure Application Gateway | Cloud Load Balancing |
| HTTP(S), layer 7 | Application Load Balancer | Azure Application Gateway (a separate service) | Application Load Balancers |
| TCP and UDP, layer 4 | Network Load Balancer | Azure Load Balancer (Standard) | Network Load Balancers, proxy and passthrough |
| Network appliances | Gateway Load Balancer | Gateway Load Balancer SKU | Internal passthrough load balancer as a next hop |
| Scope | Regional load balancers, global with Route 53 or Global Accelerator | Regional, with a cross-region tier | Global with one anycast address, or regional |
| Health checks | Per target group | Health probes | Health checks on backend services |
| Certificates | ACM on the listener | Application Gateway certificates, Key Vault | Google-managed or your own |
| Web firewall | AWS WAF on the Application Load Balancer | WAF on Application Gateway | Cloud Armor |
| How you are billed | Hours plus capacity units, plus IPv4 addresses | Rules and data processed | Forwarding rule hours plus data processed |
Typical targets are Amazon EC2 instances, Amazon EKS pods and AWS Lambda functions, with Amazon CloudFront in front for caching. Load balancer metrics and alarms live in Amazon CloudWatch.
Did you find this article helpful?
Your answer helps us improve this page for the next reader.
Sources and further reading
CloudBrum wrote this page in its own words, using the provider’s public documentation listed below as the reference. Features, limits, names and prices change, so confirm anything that matters on the provider’s own pages before you decide.
- What is Elastic Load Balancing?Amazon Web Services
- What is an Application Load Balancer?Amazon Web Services
- What is a Network Load Balancer?Amazon Web Services
- Target groups for your Application Load BalancersAmazon Web Services
- Health checks for your target groupsAmazon Web Services
- Listeners for your Application Load BalancersAmazon Web Services
- Capacity reservations for your Application Load BalancerAmazon Web Services
- Troubleshoot your Application Load BalancersAmazon Web Services
- Elastic Load Balancing pricingAmazon Web Services
- Terraform AWS provider: aws_lbHashiCorp
