Настройка балансировки нагрузки через AWS ALB и ELB
AWS предоставляет управляемые балансировщики нагрузки без необходимости поддерживать собственный сервер. Application Load Balancer (ALB) работает на уровне HTTP/HTTPS с маршрутизацией по пути и заголовкам. Network Load Balancer (NLB) — L4 TCP/UDP с минимальной задержкой. Classic ELB устарел и не рекомендуется для новых проектов.
Application Load Balancer
ALB — стандартный выбор для веб-приложений. Маршрутизирует по пути, хосту, HTTP-заголовкам, методу, query string. Интегрируется с ECS, EKS, Lambda, Auto Scaling Groups.
# Terraform: полная конфигурация ALB
resource "aws_lb" "main" {
name = "myapp-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = aws_subnet.public[*].id
enable_deletion_protection = true
enable_cross_zone_load_balancing = true
drop_invalid_header_fields = true
access_logs {
bucket = aws_s3_bucket.alb_logs.bucket
prefix = "alb"
enabled = true
}
tags = { Name = "myapp-alb" }
}
# HTTPS Listener
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.main.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.main.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web.arn
}
}
# HTTP → HTTPS redirect
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
# Target Group для веб-приложения
resource "aws_lb_target_group" "web" {
name = "myapp-web-tg"
port = 8080
protocol = "HTTP"
vpc_id = aws_vpc.main.id
target_type = "ip" # для ECS Fargate
health_check {
enabled = true
path = "/health"
healthy_threshold = 2
unhealthy_threshold = 3
timeout = 5
interval = 10
matcher = "200"
}
deregistration_delay = 30 # секунды дрейнинга соединений
stickiness {
type = "lb_cookie"
cookie_duration = 86400
enabled = false # stateless приложения не нуждаются
}
}
Маршрутизация ALB
# API на отдельном Target Group
resource "aws_lb_target_group" "api" {
name = "myapp-api-tg"
port = 3000
protocol = "HTTP"
vpc_id = aws_vpc.main.id
health_check {
path = "/api/health"
matcher = "200"
}
}
# Правила маршрутизации
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/*"]
}
}
}
# Маршрут по заголовку (версионирование API)
resource "aws_lb_listener_rule" "api_v2" {
listener_arn = aws_lb_listener.https.arn
priority = 5
action {
type = "forward"
target_group_arn = aws_lb_target_group.api_v2.arn
}
condition {
http_header {
http_header_name = "X-API-Version"
values = ["2", "2.0"]
}
}
}
# Weighted forwarding для Canary deployments
resource "aws_lb_listener_rule" "canary" {
listener_arn = aws_lb_listener.https.arn
priority = 20
action {
type = "forward"
forward {
target_group {
arn = aws_lb_target_group.web_stable.arn
weight = 95
}
target_group {
arn = aws_lb_target_group.web_canary.arn
weight = 5
}
stickiness {
enabled = true
duration = 3600
}
}
}
condition {
path_pattern { values = ["/*"] }
}
}
ALB + WAF
resource "aws_wafv2_web_acl_association" "alb" {
resource_arn = aws_lb.main.arn
web_acl_arn = aws_wafv2_web_acl.main.arn
}
resource "aws_wafv2_web_acl" "main" {
name = "myapp-waf"
scope = "REGIONAL"
default_action { allow {} }
rule {
name = "AWSManagedRulesCommonRuleSet"
priority = 1
override_action { none {} }
statement {
managed_rule_group_statement {
name = "AWSManagedRulesCommonRuleSet"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "CommonRuleSet"
sampled_requests_enabled = true
}
}
rule {
name = "RateLimit"
priority = 2
action { block {} }
statement {
rate_based_statement {
limit = 2000 # запросов за 5 минут с одного IP
aggregate_key_type = "IP"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "RateLimit"
sampled_requests_enabled = true
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "MyAppWAF"
sampled_requests_enabled = true
}
}
ALB + ACM: управление сертификатами
resource "aws_acm_certificate" "main" {
domain_name = "example.com"
subject_alternative_names = ["*.example.com"]
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "cert_validation" {
for_each = {
for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
zone_id = aws_route53_zone.main.zone_id
name = each.value.name
type = each.value.type
ttl = 60
records = [each.value.record]
}
resource "aws_acm_certificate_validation" "main" {
certificate_arn = aws_acm_certificate.main.arn
validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn]
}
# Дополнительный сертификат (например, другой домен)
resource "aws_lb_listener_certificate" "secondary" {
listener_arn = aws_lb_listener.https.arn
certificate_arn = aws_acm_certificate.secondary.arn
}
ALB + ECS Fargate
resource "aws_ecs_service" "app" {
name = "myapp-web"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 3
launch_type = "FARGATE"
network_configuration {
subnets = aws_subnet.private[*].id
security_groups = [aws_security_group.app.id]
assign_public_ip = false
}
load_balancer {
target_group_arn = aws_lb_target_group.web.arn
container_name = "web"
container_port = 8080
}
deployment_circuit_breaker {
enable = true
rollback = true
}
deployment_controller {
type = "ECS"
}
depends_on = [aws_lb_listener.https]
}
Network Load Balancer
NLB для TCP/UDP с статическими IP-адресами (нужны для whitelist у клиентов) и минимальной задержкой.
resource "aws_lb" "nlb" {
name = "myapp-nlb"
internal = false
load_balancer_type = "network"
subnets = aws_subnet.public[*].id
enable_cross_zone_load_balancing = true
}
resource "aws_lb_listener" "nlb_tls" {
load_balancer_arn = aws_lb.nlb.arn
port = 443
protocol = "TLS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.main.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.nlb_tcp.arn
}
}
resource "aws_lb_target_group" "nlb_tcp" {
name = "myapp-nlb-tg"
port = 8080
protocol = "TCP"
vpc_id = aws_vpc.main.id
health_check {
protocol = "HTTP"
path = "/health"
healthy_threshold = 2
unhealthy_threshold = 2
interval = 10
}
}
Мониторинг ALB
Ключевые CloudWatch метрики:
resource "aws_cloudwatch_metric_alarm" "target_5xx" {
alarm_name = "alb-5xx-errors"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "HTTPCode_Target_5XX_Count"
namespace = "AWS/ApplicationELB"
period = 60
statistic = "Sum"
threshold = 10
alarm_actions = [aws_sns_topic.alerts.arn]
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
}
}
resource "aws_cloudwatch_metric_alarm" "latency" {
alarm_name = "alb-high-latency"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 3
metric_name = "TargetResponseTime"
namespace = "AWS/ApplicationELB"
period = 60
extended_statistic = "p95"
threshold = 2.0 # секунды
alarm_actions = [aws_sns_topic.alerts.arn]
dimensions = {
LoadBalancer = aws_lb.main.arn_suffix
}
}
Важные метрики для мониторинга: RequestCount, ActiveConnectionCount, TargetResponseTime (p50/p95/p99), HTTPCode_ELB_5XX_Count, HealthyHostCount, UnHealthyHostCount.
Срок реализации
| Конфигурация | Срок |
|---|---|
| ALB + Target Group + HTTPS | 1–2 дня |
| Маршрутизация по путям/заголовкам | +1 день |
| WAF + rate limiting | +1–2 дня |
| Canary deployment через weighted forwarding | +1 день |
| Полная Terraform конфигурация с мониторингом | 3–5 дней |







