Health Checks no Auto Scaling Group: EC2 vs ELB — Quando Trocar e Como Diagnosticar Terminações Inesperadas

Seu Auto Scaling Group está terminando instâncias que parecem saudáveis no console EC2 — o status mostra running, o sistema operacional responde ao SSH, mas o ASG insiste em substituí-las. Esse comportamento quase sempre aponta para uma divergência entre o tipo de health check configurado e o que a aplicação realmente precisa para ser considerada saudável.

TL;DR — Auto Scaling Group Health Check: EC2 vs ELB

AspectoEC2 (padrão)ELB
O que verificaStatus do hipervisor e hardwareResposta HTTP/TCP da aplicação
Quando usarWorkloads sem load balancerInstâncias registradas em Target Group
Instância 'running' mas app travadaConsiderada saudávelConsiderada unhealthy → terminada
Risco principalServir tráfego com app quebradaTerminações em cascata se health check mal configurado
Grace periodAplica-se a ambosAplica-se a ambos

Como os Health Checks do ASG Funcionam

O ASG avalia a saúde de cada instância periodicamente. Quando uma instância é marcada como unhealthy, o ASG a termina e provisiona uma substituta — independentemente do que você vê no console EC2.

O tipo de health check define a fonte da verdade. Com o tipo EC2, o ASG consulta o status do sistema da instância via hipervisor: se o hardware está operacional e a instância está no estado running, ela é saudável. A aplicação pode estar travada, retornando 500, ou com o processo morto — o ASG não sabe e não se importa.

Com o tipo ELB, o ASG passa a respeitar o resultado do health check do Target Group associado. Se o ALB ou NLB marca a instância como unhealthy (baseado em resposta HTTP, código de status, ou timeout TCP), o ASG recebe essa informação e agenda a terminação.

Pense no health check EC2 como verificar se o carro está ligado. O health check ELB verifica se o carro está em movimento na direção certa.
graph TD A["ASG: Avaliação de Saúde"] --> B{"Tipo de Health Check"} B -->|"EC2"| C["Consulta status do hipervisor"] B -->|"ELB"| D["Consulta Target Group"] C --> E{"Instância running?
Status do sistema ok?"} D --> F{"Target Group:
healthy ou unhealthy?"} E -->|"Sim"| G["✅ Saudável — mantida"] E -->|"Não"| H["❌ Unhealthy → Terminada"] F -->|"healthy"| G F -->|"unhealthy"| H H --> I["ASG provisiona substituta"] style G fill:#2d6a4f,color:#fff style H fill:#9b2226,color:#fff style I fill:#495057,color:#fff
  1. EC2 Health Check: O ASG consulta o status do sistema da instância. Se o estado é running e o status do sistema é ok, a instância passa — independentemente da aplicação.
  2. ELB Health Check: O Target Group envia requisições periódicas para a instância. O resultado (healthy/unhealthy) é propagado ao ASG.
  3. Grace Period: Após o launch, o ASG aguarda o período de graça antes de avaliar qualquer health check. Instâncias terminadas durante o grace period indicam um problema diferente (veja diagnóstico abaixo).
  4. Decisão de terminação: Qualquer fonte que marque a instância como unhealthy — EC2 ou ELB — resulta em terminação pelo ASG.

Por Que o ASG Termina Instâncias 'Saudáveis' — Diagnóstico em Camadas

Antes de trocar o tipo de health check, é necessário entender qual verificação está falhando. Trocar de EC2 para ELB sem investigar pode transformar um problema intermitente em terminações em cascata se o health check do Target Group estiver mal configurado.

Passo 1: Identifique a causa da terminação nos eventos do ASG

O histórico de atividades do ASG registra o motivo de cada terminação. Esse é o ponto de partida — sem ele, qualquer diagnóstico é especulação.

aws autoscaling describe-scaling-activities \
  --auto-scaling-group-name nome-do-seu-asg \
  --max-items 20 \
  --query 'Activities[?StatusCode==`Failed` || contains(Description, `Terminating`)].[ActivityId,Description,Cause,StatusMessage]' \
  --output table

Procure no campo Cause por strings como 'an instance was found to be in poor health' ou referências ao ELB. Isso indica se a terminação veio de um health check EC2 ou ELB.

Passo 2: Verifique o tipo de health check atual e o grace period

Grace period insuficiente é a causa mais comum de terminações de instâncias recém-lançadas que parecem saudáveis. Se a aplicação demora 90 segundos para inicializar e o grace period é 60, o ASG vai terminar a instância antes mesmo de ela estar pronta — e o log vai mostrar uma falha de health check que tecnicamente é verdadeira, mas evitável.

aws autoscaling describe-auto-scaling-groups \
  --auto-scaling-group-names nome-do-seu-asg \
  --query 'AutoScalingGroups[0].{HealthCheckType:HealthCheckType,HealthCheckGracePeriod:HealthCheckGracePeriod,DesiredCapacity:DesiredCapacity,MinSize:MinSize,MaxSize:MaxSize}' \
  --output table

Passo 3: Se o tipo for ELB, verifique o estado das instâncias no Target Group

Quando o tipo é ELB, o ASG depende inteiramente do que o Target Group reporta. Uma instância pode estar running no EC2 e unhealthy no Target Group simultaneamente — e o ASG vai terminar com base no Target Group.

aws elbv2 describe-target-health \
  --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/nome-do-tg/abc123def456 \
  --query 'TargetHealthDescriptions[*].{Id:Target.Id,Port:Target.Port,State:TargetHealth.State,Reason:TargetHealth.Reason,Description:TargetHealth.Description}' \
  --output table

O campo Reason é o mais importante aqui. Valores como Target.FailedHealthChecks ou Elb.InternalError apontam para causas distintas que exigem correções diferentes.

Passo 4: Verifique a configuração do health check no Target Group

Um health check apontando para o path errado, com timeout muito baixo, ou esperando um código HTTP que a aplicação não retorna vai marcar instâncias saudáveis como unhealthy continuamente. Isso é especialmente comum após deploys que alteram rotas da aplicação.

aws elbv2 describe-target-groups \
  --target-group-arns arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/nome-do-tg/abc123def456 \
  --query 'TargetGroups[0].{Protocol:HealthCheckProtocol,Path:HealthCheckPath,Port:HealthCheckPort,Interval:HealthCheckIntervalSeconds,Timeout:HealthCheckTimeoutSeconds,HealthyThreshold:HealthyThresholdCount,UnhealthyThreshold:UnhealthyThresholdCount,Matcher:Matcher.HttpCode}' \
  --output table

Passo 5: Verifique Security Groups — a causa silenciosa mais frequente

O health check do ALB origina de IPs dentro da VPC. Se o Security Group da instância não permite tráfego na porta do health check a partir do SG do load balancer (ou do range de IPs da VPC), o health check vai falhar com timeout — e o log do Target Group vai mostrar Target.Timeout sem nenhuma mensagem de erro na aplicação.

aws ec2 describe-security-groups \
  --group-ids sg-0123456789abcdef0 \
  --query 'SecurityGroups[0].IpPermissions[*].{FromPort:FromPort,ToPort:ToPort,Protocol:IpProtocol,Sources:UserIdGroupPairs[*].GroupId}' \
  --output table
graph TD START(["Instância terminada inesperadamente"]) --> S1["Passo 1: describe-scaling-activities
Identificar causa no campo Cause"] S1 --> D1{"Causa da terminação"} D1 -->|"EC2 health check failure"| S2A["Verificar status do sistema EC2
Possível kernel panic ou falha de hardware"] D1 -->|"ELB health check failure"| S2B["Passo 3: describe-target-health
Verificar estado no Target Group"] D1 -->|"Terminada durante grace period"| S2C["Passo 2: Verificar grace period
Comparar com tempo de boot da app"] S2B --> S3{"Reason no Target Group"} S3 -->|"Target.FailedHealthChecks"| S4A["Passo 4: Verificar config do health check
Path, timeout, código HTTP esperado"] S3 -->|"Target.Timeout"| S4B["Passo 5: Verificar Security Group
Porta do health check liberada?"] S4A --> FIX["Corrigir configuração do Target Group"] S4B --> FIX S2C --> FIX2["Aumentar health-check-grace-period"] style START fill:#343a40,color:#fff style FIX fill:#2d6a4f,color:#fff style FIX2 fill:#2d6a4f,color:#fff
  1. O fluxo começa com a observação de terminações inesperadas.
  2. O histórico de atividades do ASG é a primeira fonte de verdade — ele diferencia falhas EC2 de falhas ELB.
  3. Falhas EC2 geralmente indicam problemas reais de hardware ou kernel panic — não são falsos positivos.
  4. Falhas ELB exigem investigação em três camadas: configuração do health check, conectividade de rede, e comportamento da aplicação.
  5. Grace period insuficiente é diagnosticado separadamente porque afeta ambos os tipos de health check.

Quando Trocar de EC2 para ELB — e Como Fazer

A troca faz sentido quando: a instância está registrada em um Target Group, a aplicação pode travar sem afetar o estado do SO, e você quer que o ASG reaja a falhas da aplicação — não apenas de hardware.

Antes de trocar, confirme que o health check do Target Group está funcionando corretamente (Passo 4 acima). Trocar para ELB com um health check mal configurado vai iniciar um ciclo de terminações que pode esvaziar o ASG.

aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name nome-do-seu-asg \
  --health-check-type ELB \
  --health-check-grace-period 300

O valor do grace period deve ser maior que o tempo total de inicialização da instância: boot do SO + inicialização da aplicação + tempo para o Target Group marcar como healthy (número de health checks bem-sucedidos × intervalo). Em aplicações Java ou Node.js com dependências externas, 300 segundos é um ponto de partida conservador razoável.

Corrigindo o Health Check do Target Group

Se o diagnóstico revelou que o Target Group está marcando instâncias saudáveis como unhealthy, corrija a configuração antes de qualquer outra mudança no ASG.

aws elbv2 modify-target-group \
  --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/nome-do-tg/abc123def456 \
  --health-check-protocol HTTP \
  --health-check-path /health \
  --health-check-interval-seconds 30 \
  --health-check-timeout-seconds 10 \
  --healthy-threshold-count 2 \
  --unhealthy-threshold-count 3 \
  --matcher HttpCode=200

Use um endpoint dedicado de health check (/health) que retorne 200 apenas quando a aplicação está genuinamente pronta para receber tráfego — não apenas quando o processo está de pé. Endpoints que verificam conectividade com banco de dados e dependências críticas evitam que instâncias parcialmente inicializadas recebam tráfego.

Política IAM Mínima para Diagnóstico

Para executar os comandos de diagnóstico acima, a role ou usuário precisa das seguintes permissões. Ações de leitura no Auto Scaling e ELBv2 frequentemente exigem Resource: "*" — verifique o Service Authorization Reference para confirmar suporte a resource-level permissions por ação.

🔽 Clique para expandir a política IAM
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ASGDiagnostics",
      "Effect": "Allow",
      "Action": [
        "autoscaling:DescribeAutoScalingGroups",
        "autoscaling:DescribeScalingActivities"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ELBDiagnostics",
      "Effect": "Allow",
      "Action": [
        "elasticloadbalancing:DescribeTargetGroups",
        "elasticloadbalancing:DescribeTargetHealth"
      ],
      "Resource": "*"
    },
    {
      "Sid": "EC2Diagnostics",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeSecurityGroups"
      ],
      "Resource": "*"
    }
  ]
}

O Diagnóstico que Parecia Óbvio — Mas Não Era

Um padrão que aparece com frequência: o ASG está com health check tipo EC2, as instâncias são terminadas, e a conclusão imediata é 'preciso trocar para ELB'. A troca é feita, e as terminações continuam — agora em ritmo ainda maior.

O que estava acontecendo: o health check do Target Group apontava para / em vez de /health, e a rota raiz da aplicação fazia uma query de banco de dados a cada requisição. Sob carga, o banco saturava, a query demorava mais que o timeout do health check (5 segundos), e o Target Group marcava todas as instâncias como unhealthy simultaneamente. O ASG, agora respeitando o ELB, terminava tudo.

Com o tipo EC2, as instâncias sobreviviam porque o hipervisor não sabia do problema. Com o tipo ELB e health check mal configurado, o ASG amplificou o problema em vez de resolvê-lo.

A correção real foi criar um endpoint /health que retornava 200 imediatamente sem tocar no banco, ajustar o path no Target Group, e só então habilitar o health check ELB no ASG. O tipo de health check era a mudança certa — mas a ordem importava.

Próximos Passos e Documentação

Após estabilizar o comportamento do health check no Auto Scaling Group, considere configurar CloudWatch Alarms sobre a métrica GroupInServiceInstances para detectar quedas de capacidade antes que afetem usuários. O AWS Well-Architected Framework — Pilar de Confiabilidade cobre padrões de self-healing que complementam a configuração correta de health checks.

Glossário

TermoDefinição
Health Check Grace PeriodTempo em segundos que o ASG aguarda após o launch de uma instância antes de iniciar avaliações de health check.
Target GroupAgrupamento lógico de destinos (instâncias, IPs, Lambdas) para um load balancer; mantém estado de saúde individual por destino.
Health Check Type (ASG)Define qual fonte o ASG usa para determinar saúde: status do hipervisor EC2 ou resultado do health check do ELB associado.
UnhealthyThresholdCountNúmero de health checks consecutivos com falha necessários para o Target Group marcar uma instância como unhealthy.
Scaling ActivityRegistro auditável de cada ação tomada pelo ASG (launch, terminate, etc.) com causa e resultado.

Related Posts

Comentários

Postagens mais visitadas deste blog

Variáveis de Ambiente no Lambda: Configuração, Acesso e Criptografia com KMS

Monitoramento de Memória RAM no EC2: Por que o CloudWatch Agent é Obrigatório

S3 Access Denied: Por que 'Bloquear Acesso Público' impede seu objeto mesmo após torná-lo público