DEV Community

Cover image for AWS na prática - subindo instâncias EC2 e um target group do zero
Rafael Dutra for apsis-cc

Posted on

AWS na prática - subindo instâncias EC2 e um target group do zero

1. Uma nova série: balanceamento de carga na AWS

Colocar uma aplicação em produção quase nunca significa "uma máquina rodando o código". Significa várias instâncias idênticas, distribuição de tráfego entre elas, substituição automática de quem falhar e, cada vez mais, decisões de roteamento que acontecem antes mesmo do tráfego chegar a um balanceador — no próprio DNS. Nesta nova série de dois artigos, vamos construir esse cenário na AWS: primeiro, subindo instâncias EC2 e organizando-as em um target group; depois, no próximo artigo, olhando para o Route 53 e como balanceamento de carga também acontece na camada de resolução de nomes.

Começamos pela base: o que é uma instância EC2, como criar algumas delas de forma repetível, e como agrupá-las para que um balanceador (ou outro consumidor) saiba para onde mandar tráfego.

2. O que é o EC2

O Amazon EC2 (Elastic Compute Cloud) é o serviço de máquinas virtuais da AWS. Cada instância roda em um tipo (t3.micro, m5.large, etc.) que define CPU, memória e características de rede, a partir de uma AMI (Amazon Machine Image) — uma imagem de disco com o sistema operacional e, opcionalmente, software já instalado. Os elementos que mais importam ao planejar uma frota de instâncias por trás de um balanceador são:

  • Subnet: em qual sub-rede (e portanto em qual zona de disponibilidade) a instância nasce. Distribuir instâncias em subnets de AZs diferentes é o que garante que a queda de um datacenter não tire a aplicação do ar.
  • Security Group: o firewall da instância, controlando portas de entrada e saída.
  • Key pair: o par de chaves usado para acesso SSH inicial.
  • User data: um script executado no primeiro boot, útil para instalar e subir a aplicação sem depender de uma AMI customizada.

3. Criando uma instância EC2 via CLI

Para ilustrar de forma reprodutível, os exemplos abaixo usam a AWS CLI. Primeiro, um security group liberando HTTP e SSH:

aws ec2 create-security-group \
  --group-name web-servers-sg \
  --description "SG para instancias web atras do target group" \
  --vpc-id vpc-0123456789abcdef0

aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp --port 80 --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp --port 22 --cidr 10.0.0.0/16
Enter fullscreen mode Exit fullscreen mode

Com o security group pronto, sobe-se a instância com um user data que instala e inicia um servidor web mínimo:

aws ec2 run-instances \
  --image-id ami-0abcdef1234567890 \
  --instance-type t3.micro \
  --key-name minha-chave \
  --security-group-ids sg-0123456789abcdef0 \
  --subnet-id subnet-0aaa111122223333 \
  --count 1 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-01}]' \
  --user-data '#!/bin/bash
yum install -y nginx
systemctl enable nginx
systemctl start nginx'
Enter fullscreen mode Exit fullscreen mode

Repetir o comando trocando subnet-id (para uma subnet em outra AZ) e a tag Name cria uma segunda instância idêntica em termos de aplicação, mas fisicamente isolada da primeira — o ponto de partida para alta disponibilidade.

4. O mesmo cenário em Terraform

Rodar run-instances manualmente não escala nem é repetível. Em um projeto real, o mesmo cenário costuma ser descrito em Terraform, usando count para gerar N instâncias distribuídas em subnets diferentes:

variable "subnet_ids" {
  default = ["subnet-0aaa111122223333", "subnet-0bbb444455556666"]
}

resource "aws_instance" "web" {
  count                  = length(var.subnet_ids)
  ami                    = "ami-0abcdef1234567890"
  instance_type          = "t3.micro"
  subnet_id              = var.subnet_ids[count.index]
  vpc_security_group_ids = [aws_security_group.web.id]
  key_name               = "minha-chave"

  user_data = <<-EOF
    #!/bin/bash
    yum install -y nginx
    systemctl enable nginx
    systemctl start nginx
  EOF

  tags = {
    Name = "web-${count.index + 1}"
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Criando o target group

Um target group é a lista de destinos (instâncias EC2, IPs ou funções Lambda) para onde um balanceador de carga da AWS (ALB ou NLB) encaminha tráfego, junto com a configuração de health check que decide se cada destino está saudável o suficiente para receber requisições:

aws elbv2 create-target-group \
  --name web-servers-tg \
  --protocol HTTP \
  --port 80 \
  --vpc-id vpc-0123456789abcdef0 \
  --health-check-protocol HTTP \
  --health-check-path /healthz \
  --health-check-interval-seconds 15 \
  --healthy-threshold-count 2 \
  --unhealthy-threshold-count 3
Enter fullscreen mode Exit fullscreen mode

O comando retorna um TargetGroupArn, usado tanto para registrar instâncias quanto para, no próximo artigo, anexar o target group a um listener de balanceador.

6. Registrando as instâncias no target group

Com as instâncias no ar e o target group criado, o passo final é registrar cada instância como um destino:

aws elbv2 register-targets \
  --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/web-servers-tg/abcdef1234567890 \
  --targets Id=i-0123456789abcdef0 Id=i-0fedcba9876543210
Enter fullscreen mode Exit fullscreen mode

A partir daí, o próprio target group passa a monitorar a saúde de cada instância via o health check configurado no passo anterior:

aws elbv2 describe-target-health \
  --target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/web-servers-tg/abcdef1234567890
Enter fullscreen mode Exit fullscreen mode

A saída mostra o estado (healthy, unhealthy, initial) de cada instância registrada — é esse estado que um Application Load Balancer usa para decidir se deve ou não rotear tráfego para um destino específico.

7. Por que isso importa antes de falar em balanceador

Vale notar que, até aqui, nenhum balanceador de carga foi criado — só a infraestrutura que ele vai consumir. Essa separação é deliberada: um target group existe de forma independente do listener/load balancer que o usa, o que permite trocar de estratégia de roteamento (um ALB clássico, regras baseadas em path, ou o roteamento por DNS que veremos a seguir) sem recriar as instâncias nem o agrupamento delas.

8. Conclusão

Instâncias EC2 distribuídas em múltiplas zonas de disponibilidade e agrupadas em um target group com health check ativo são a base de qualquer arquitetura de alta disponibilidade na AWS — é esse agrupamento que qualquer balanceador, do ALB clássico a estratégias mais avançadas, vai consultar para saber quem está apto a receber tráfego. No próximo artigo desta série, vamos sair da camada de balanceador tradicional e olhar para o Route 53: como o próprio DNS pode distribuir tráfego entre regiões e endpoints, com políticas de roteamento ponderado, por latência e failover automático.


Imagem de capa: Logo da AWS — Wikimedia Commons, marca da Amazon.com, Inc. (convertido para PNG via wsrv.nl)

Referências:

  1. Amazon EC2 — User Guide
  2. Elastic Load Balancing — Target Groups
  3. Terraform Provider: AWS — aws_instance

Top comments (0)