Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

03 - AWS Auto Scaling Groups (EC2)

#auto scaling group#aws#ec2#launch template
video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

AWS Auto Scaling Groups (EC2)

O Auto Scaling Group (ASG) é o recurso da AWS que mantém um conjunto de instâncias EC2 em quantidade e saúde desejadas, adicionando e removendo unidades conforme políticas de escala e verificações de saúde. Ele é o alicerce da elasticidade em workloads de instâncias: aplicações HTTP atrás de um ELB, workers que consomem filas, ambientes de batch e componentes que exigem controle do sistema operacional. O ASG combina três funções que operam juntas: garantia de capacidade, com mínimo, desejado e máximo; auto recuperação, substituindo instâncias não saudáveis; e escala automática, reagindo a políticas de target tracking, step ou agendamento. Em produção, dominar o ASG é dominar a relação entre capacidade, custo e disponibilidade no nível mais básico da nuvem AWS. Este registro cobre o launch template, os parâmetros de capacidade, os health checks, o ciclo de substituição de instâncias, o warm-up e a integração com balanceadores e zonas de disponibilidade.

Conceito e problema que resolve

O problema clássico de infraestrutura tradicional é a capacidade fixa: compras para o pico e paga ociosidade, ou dimensiona para a média e derruba o sistema no pico. O ASG resolve com três mecanismos integrados. Primeiro, o grupo garante a quantidade desejada de instâncias saudáveis, repovoando automaticamente o que falha. Segundo, políticas de escala ajustam a quantidade desejada conforme métricas, horários ou alarmes. Terceiro, a integração com ELB e Target Groups distribui tráfego apenas para instâncias saudáveis e registradas, sem configuração manual.

O resultado operacional é a conversão de uma tarefa de operação em um objeto declarativo. O time não gerencia instâncias individualmente; gerencia um grupo com regras. Instâncias vêm e vão com IDs diferentes, e nada dependente de host deve sobreviver nelas, o que reforça o desenho stateless e imutável: novas instâncias nascem de uma AMI e de user data idênticos, sem configuração manual residual.

Launch template: o molde da instância

O launch template define tudo que uma instância precisa para nascer: AMI, tipo de instância, par de chaves, security groups, user data, bloco de volumes, IAM instance profile e tags. Ele substitui o antigo launch configuration, que era imutável, e passa a ser versionado: cada alteração gera uma nova versão, e o ASG pode apontar para a versão mais recente ou para uma fixa. Esse versionamento é a base de estratégias de atualização controlada, como instance refresh, que substitui gradualmente as instâncias do grupo pela nova versão do template.

Elemento do template Função Cuidado em produção
AMI Imagem base do sistema operacional e da aplicação Construa por pipeline; nunca use AMI manual
Instance type Capacidade de CPU e memória Diversifique tipos com grupos de capacidade
IAM instance profile Permissões da instância na AWS Menor privilégio por papel do grupo
User data Bootstrap na inicialização Idempotente; testado com a AMI
Security groups Regras de rede de entrada e saída Restrito ao necessário; sem SSH amplo
EBS / volumes Disco raiz e adicionais Deletar on termination decidido explicitamente

A AMI merece atenção especial: o padrão saudável é uma esteira de golden images construída no CI, com sistema atualizado, agente de observabilidade instalado e aplicação baked, ou, alternativamente, uma AMI genérica que baixa a aplicação no boot. A primeira abordagem reduz o tempo de boot e o risco de falha externa no provisionamento; a segunda simplifica o pipeline. Ambas funcionam, desde que o template seja tratado como código versionado.

O exemplo a seguir mostra um trecho de launch template típico de produção, com bootstrap idempotente.

{
  "LaunchTemplateName": "api-lt",
  "ImageId": "ami-0abc123def456",
  "InstanceType": "m7g.large",
  "IamInstanceProfile": { "Name": "api-instance-profile" },
  "SecurityGroupIds": ["sg-api-privado"],
  "BlockDeviceMappings": [
    {
      "DeviceName": "/dev/xvda",
      "Ebs": { "VolumeSize": 30, "VolumeType": "gp3", "DeleteOnTermination": true }
    }
  ],
  "MetadataOptions": {
    "HttpTokens": "required",
    "HttpPutResponseHopLimit": 2
  },
  "UserData": "IyEvYmluL2Jhc2gK# base64 da configuração de bootstrap da aplicação"
}

O detalhamento de segurança importa em produção: exigir IMDSv2 com HttpTokens required elimina a variante antiga de metadados que facilitou ataques de SSRF, e o instance profile com menor privilégio evita que a exploração de uma instância comprometa a conta inteira.

Capacidade desejada, mínima e máxima

Os três parâmetros numéricos definem a moldura de operação do grupo. O mínimo é o piso de disponibilidade, tipicamente duas instâncias para tolerar uma falha. O desejado é o tamanho corrente, alterado pelas políticas de escala e pela restauração automática. O máximo é o teto de custo e de proteção, e deve ser coerente com as cotas de serviço da conta e com a capacidade real do banco e dos serviços downstream.

# Cria o grupo com moldura de capacidade e distribuição em três AZs
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name api-producao \
  --launch-template LaunchTemplateName=api-lt,Version='$Latest' \
  --min-size 2 --max-size 12 --desired-capacity 4 \
  --vpc-zone-identifier "subnet-a,subnet-b,subnet-c" \
  --health-check-type ELB \
  --health-check-grace-period 180 \
  --target-group-arns arn:aws:elasticloadbalancing:sa-east-1:123456789012:targetgroup/api/abc \
  --capacity-rebalance \
  --tag Key=Time,Value=pedidos,PropagateAtLaunch=true

# Política de escala mantendo 60% de CPU média
aws autoscaling put-scaling-policy \
  --auto-scaling-group-name api-producao \
  --policy-name api-cpu-60 \
  --policy-type TargetTrackingScaling \
  --target-tracking-configuration '{
    "TargetValue": 60.0,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "ASGAverageCPUUtilization"
    }
  }'

# Inspeção do estado atual do grupo e das instâncias
aws autoscaling describe-auto-scaling-groups \
  --auto-scaling-group-names api-producao \
  --query 'AutoScalingGroups[0].{desejado:DesiredCapacity,instancias:Instances[*].{id:InstanceId,az:AvailabilityZone,saudavel:HealthStatus}}'

A escolha do mínimo merece análise de custo e de disponibilidade: um mínimo de 1 evita custo, mas derruba o serviço quando a única instância falha ou é substituída. Em serviços críticos, o mínimo deve cobrir a perda de uma zona de disponibilidade, e a distribuição das sub-redes no parâmetro de zonas precisa refletir essa intenção.

Health checks e substituição de instância

O ASG determina a saúde de cada instância por checks configuráveis: EC2, que observa apenas o estado do hypervisor, e ELB, que valida se o balanceador consegue alcançar a aplicação nas portas dos Target Groups. O ELB check é o correto para aplicações HTTP, pois captura falhas que o sistema operacional não reporta, como processo travado respondendo conexões recusadas. O health check grace period dá tempo do boot antes de julgar a instância morta; configurá-lo curto demais cria o ciclo de matar instâncias ainda subindo.

Quando uma instância é considerada não saudável, o fluxo automático é: registrar evento, remover a instância do Target Group para cessar tráfego novo, terminar a instância e criar uma substituição a partir do launch template. Com o parâmetro de instance scale-in protection, instâncias críticas podem ser protegidas de remoção durante scale down, e com capacity rebalance, o grupo reage a interrupções de spot antecipando a substituição antes da interrupção efetiva.

O instance refresh completa o ciclo de atualização: em vez de deploys manuais nas instâncias, o time publica uma nova versão do launch template e dispara o refresh, que substitui as instâncias em ondas respeitando um warm-up e um limite de porcentagem pronta, com rollback automático se o health check falhar. É o mecanismo de deploy do próprio ASG, adequado quando a aplicação está baked na AMI.

Hooks de ciclo de vida

Os lifecycle hooks permitem executar ações em pontos de transição do ciclo de vida da instância: antes de entrar em serviço no scale out e antes de ser terminada no scale down. No evento de lançamento, a instância fica em estado pending-wait até o hook ser completado, dando janela para instalar agentes, registrar em service discovery ou aquecer caches. No evento de encerramento, a instância entra em terminating-wait, e o time pode drenar conexões, finalizar tarefas em andamento e enviar métricas de despedida.

# Hook de encerramento: 120 segundos para drenar conexões e finalizar trabalho
aws autoscaling put-lifecycle-hook \
  --auto-scaling-group-name api-producao \
  --lifecycle-hook-name drenar-conexoes \
  --lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING \
  --heartbeat-timeout 120 \
  --default-result CONTINUE

# A instância drenada notifica o hook, por exemplo via Lambda no EventBridge,
# e o encerramento prossegue após o timeout ou após complete-lifecycle-action
aws autoscaling complete-lifecycle-action \
  --auto-scaling-group-name api-producao \
  --lifecycle-hook-name drenar-conexoes \
  --lifecycle-action-result CONTINUE \
  --instance-id i-0abc123def456

O padrão comum combina o hook com uma função Lambda disparada pelo EventBridge no evento de terminação, que consulta o serviço para decidir se a instância pode ir: fila vazia, requisições em voo concluídas, checkpoints salvos. Sem esse cuidado, o scale down deixa trabalho inacabado, e o sistema fica lento até o retry automático resgatar a tarefa perdida.

Warm-up, cool-down e políticas de escala

A interação entre escala e boot é onde residem os erros mais custosos. O warm-up period informa ao controlador quanto tempo uma instância nova leva para estar pronta, e as métricas dessa instância não são contadas no cálculo das políticas durante esse período. Sem isso, a política lê CPU alta das instâncias em bootstrap, adiciona mais instâncias desnecessárias e encarece o pico. O cool-down, herdado das políticas simples, impede ações em sequência enquanto o sistema absorve a mudança anterior.

A recomendação prática é configurar o warm-up com o valor medido do boot real, não estimado: se a instância leva 90 segundos até o health check passar, warm-up de 120 segundos dá folga. Para workloads spot, o capacity rebalance combinado com diversificação de tipos em duas ou três famílias reduz o risco de interrupções concentradas. As políticas em si seguem o que o arquivo de políticas de escala detalha; aqui, o ponto central é que o comportamento do ASG como um todo depende tanto dos números quanto dos períodos de estabilização.

Integração com ELB e zonas de disponibilidade

A integração com o Elastic Load Balancing é bidirecional: o ASG registra instâncias nos Target Groups especificados, e o ELB alimenta o ASG com sinais de saúde. O atributo de requisições por alvo permite políticas que escalam pelo tráfego efetivo, e o connection draining do ELB, chamado de deregistration delay, garante que instâncias removidas concluam requisições em voo. Sem esse atraso configurado corretamente, o scale down produz erros 502 visíveis ao cliente.

Zonas de disponibilidade entram em dois níveis. No agendamento, o ASG distribui instâncias entre as sub-redes informadas, buscando equilíbrio entre zonas. Em caso de falha de zona, o controlador tenta repor capacidade nas zonas restantes, e a quantidade mínima deve ser dimensionada para sobreviver a esse cenário. Regras adicionais, como instâncias mínimas por zona, protegem serviços sensíveis a latência que precisam estar sempre perto de consumidores em cada região.

Erros comuns e boas práticas

A lista de problemas recorrentes concentra-se em configuração de saúde, custos e desenho stateless.

  • Grace period curto demais, gerando loop de substituição de instâncias em aplicações de boot lento; meça o boot e configure com folga.
  • Health check do tipo EC2 para aplicações web, que não detecta processo travado; use ELB sempre que houver Target Group.
  • Estado em disco local e sessão em memória, quebrando a substituição de instâncias; extraia para serviços compartilhados antes de habilitar escala.
  • Falta de diversificação de tipos com spot, concentrando o risco de interrupção; use grupos de capacidade com múltiplas famílias.
  • Máximo sem alarme e sem relação com cotas, transformando picos em surpresa de custo ou falha por limite de conta.
  • Encerramento sem drenagem, causando erros no cliente; configure deregistration delay e hooks de ciclo de vida para finalizar trabalho em curso.

Boas práticas consolidam a operação madura do grupo. Trate o launch template como código, com esteira de AMI e revisão por pull request; configure mínimo que sobreviva à perda de uma zona; monitore a capacidade atingida com alarmes nos limites; use instance refresh para deploys imutáveis; e valide a elasticidade com testes de carga que percorram a curva completa de crescimento e redução. O ASG é maduro, estável e previsível, e recompensa configuração disciplinada com disponibilidade contínua a custo variável.