1. Um outro tipo de balanceamento
No artigo anterior desta série, subimos instâncias EC2 e as agrupamos em um target group, prontas para receber tráfego de um balanceador de carga tradicional. Mas existe uma camada de decisão que acontece antes de qualquer pacote chegar a um Application Load Balancer: a resolução de nome. Quando um cliente pergunta "qual é o IP de api.minhaempresa.com?", quem responde pode já estar escolhendo, com base em latência, saúde do destino ou uma política de peso, para qual região ou endpoint mandar esse cliente. É esse balanceamento — feito no Route 53, o serviço de DNS da AWS — que vamos explorar aqui.
2. Por que balancear no DNS, se já existe um load balancer
Um ALB/NLB distribui tráfego entre instâncias dentro de uma região. O Route 53 resolve um problema diferente: distribuir tráfego entre regiões, entre contas ou entre serviços completamente distintos, antes mesmo de uma conexão TCP ser aberta. Os dois não são concorrentes — na prática, é comum que registros no Route 53 apontem justamente para ALBs em regiões diferentes, formando duas camadas de balanceamento:
Cliente → Route 53 (escolhe a região) → ALB da região → Target Group → EC2
A diferença central de mecanismo importa: um ALB decide por requisição, em tempo real, olhando para o estado atual de cada destino. O Route 53 decide por resposta de consulta DNS, e o cliente (ou, mais frequentemente, o resolver DNS dele) fica com essa resposta em cache pelo tempo definido no TTL do registro — o que torna o balanceamento por DNS mais grosseiro, porém indispensável quando o requisito é geográfico ou cruza fronteiras que um load balancer sozinho não alcança.
3. Políticas de roteamento do Route 53
O Route 53 suporta várias políticas de roteamento no mesmo nome, cada uma resolvendo um problema diferente:
- Simple: um registro, uma resposta fixa (ou uma lista, escolhida aleatoriamente pelo cliente). Sem balanceamento real.
- Weighted: distribui consultas entre múltiplos endpoints por peso relativo — útil para canary release ou para migrar tráfego gradualmente de um ambiente para outro.
- Latency-based: responde com o endpoint na região com menor latência medida a partir da localização do resolver que fez a pergunta.
- Failover: mantém um endpoint primário e um secundário, alternando automaticamente quando o health check do primário falha.
- Geolocation / Geoproximity: roteia com base na localização geográfica de quem pergunta, útil para requisitos de residência de dados ou conteúdo localizado.
- Multivalue answer: retorna várias respostas saudáveis por consulta, funcionando como um DNS round-robin com health check embutido.
4. Roteamento ponderado (weighted) na prática
Para migrar tráfego gradualmente entre dois ALBs (por exemplo, uma versão antiga e uma nova da aplicação), dois registros com o mesmo nome e pesos diferentes:
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch '{
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "api.minhaempresa.com",
"Type": "A",
"SetIdentifier": "versao-atual",
"Weight": 90,
"AliasTarget": {
"HostedZoneId": "Z35SXDOTRQ7X7K",
"DNSName": "alb-antigo-123456.us-east-1.elb.amazonaws.com",
"EvaluateTargetHealth": true
}
}
}]
}'
E o segundo registro, apontando para o novo ALB com 10% do tráfego:
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch '{
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "api.minhaempresa.com",
"Type": "A",
"SetIdentifier": "versao-nova",
"Weight": 10,
"AliasTarget": {
"HostedZoneId": "Z35SXDOTRQ7X7K",
"DNSName": "alb-novo-654321.us-east-1.elb.amazonaws.com",
"EvaluateTargetHealth": true
}
}
}]
}'
Aumentar gradualmente o peso do "versao-nova" (10 → 50 → 100) e reduzir o do "versao-atual" na mesma proporção é uma forma simples de canary release sem depender de lógica de roteamento na aplicação.
5. O mesmo cenário em Terraform
O provider da AWS modela cada registro ponderado como um aws_route53_record com set_identifier e bloco weighted_routing_policy:
resource "aws_route53_record" "api_atual" {
zone_id = aws_route53_zone.principal.zone_id
name = "api.minhaempresa.com"
type = "A"
set_identifier = "versao-atual"
weighted_routing_policy {
weight = 90
}
alias {
name = aws_lb.antigo.dns_name
zone_id = aws_lb.antigo.zone_id
evaluate_target_health = true
}
}
resource "aws_route53_record" "api_nova" {
zone_id = aws_route53_zone.principal.zone_id
name = "api.minhaempresa.com"
type = "A"
set_identifier = "versao-nova"
weighted_routing_policy {
weight = 10
}
alias {
name = aws_lb.novo.dns_name
zone_id = aws_lb.novo.zone_id
evaluate_target_health = true
}
}
6. Failover automático com health check
Para um cenário de disaster recovery — um ambiente primário e um standby em outra região — o Route 53 monitora o endpoint primário e só resolve para o secundário quando ele falha:
aws route53 create-health-check \
--caller-reference "hc-api-primario-$(date +%s)" \
--health-check-config '{
"IPAddress": "203.0.113.10",
"Port": 443,
"Type": "HTTPS",
"ResourcePath": "/healthz",
"RequestInterval": 30,
"FailureThreshold": 3
}'
O HealthCheckId retornado é referenciado nos dois registros de failover:
resource "aws_route53_record" "primario" {
zone_id = aws_route53_zone.principal.zone_id
name = "api.minhaempresa.com"
type = "A"
set_identifier = "primario"
health_check_id = aws_route53_health_check.primario.id
failover_routing_policy {
type = "PRIMARY"
}
alias {
name = aws_lb.regiao_principal.dns_name
zone_id = aws_lb.regiao_principal.zone_id
evaluate_target_health = true
}
}
resource "aws_route53_record" "secundario" {
zone_id = aws_route53_zone.principal.zone_id
name = "api.minhaempresa.com"
type = "A"
set_identifier = "secundario"
failover_routing_policy {
type = "SECONDARY"
}
alias {
name = aws_lb.regiao_dr.dns_name
zone_id = aws_lb.regiao_dr.zone_id
evaluate_target_health = true
}
}
Enquanto o health check do primário estiver saudável, todas as consultas recebem o endpoint principal. Assim que três checagens consecutivas falham, o Route 53 passa a responder com o endpoint secundário — sem nenhuma intervenção manual, embora o efeito completo dependa do TTL do registro e do quanto os resolvers dos clientes respeitam esse cache.
7. Uma ressalva importante: TTL e propagação
Diferente de um ALB, que reage a mudanças de saúde de um destino em segundos, uma mudança de resposta no Route 53 só se propaga para novos clientes conforme o TTL do registro expira em cada resolver intermediário — e alguns resolvers ignoram TTLs muito baixos. Para cenários de failover, é comum usar um TTL de 30 a 60 segundos nos registros críticos, aceitando uma janela de indisponibilidade parcial maior do que a de um balanceador de camada 4/7, em troca da capacidade de rotear entre regiões inteiras.
8. Conclusão
Combinar as duas camadas — instâncias EC2 agrupadas em um target group, como vimos no artigo anterior, e políticas de roteamento no Route 53 por cima delas — cobre tanto o balanceamento fino dentro de uma região quanto decisões de mais alto nível: canary release gradual, redução de latência por geografia e failover entre regiões inteiras. A escolha de política (weighted, latency-based, failover) depende do problema: migração gradual de versão pede weighted, presença global pede latency-based, disaster recovery pede failover — e nada impede combinar mais de uma, já que o Route 53 permite políticas aninhadas apontando um conjunto de registros para outro.
Imagem de capa: Logo da AWS — Wikimedia Commons, marca da Amazon.com, Inc. (convertido para PNG via wsrv.nl)
Referências:
Top comments (0)