AWS na Prática · 03 — Elastic Beanstalk

Subindo o primeiro microserviço em produção, com PaaS gerenciado.

16 min de leitura

Subindo o primeiro microserviço em produção, com PaaS gerenciado.

Sobre este módulo

Este é o módulo do primeiro deploy real do projeto. Você vai subir o serviço Orders no Beanstalk, entender ciclo de releases, health checks, logs e troubleshooting. É onde a teoria encontra o dia a dia operacional da AWS.

Nível: Intermediário · Duração estimada: 4-5 horas


Sumário

  1. O que Beanstalk faz por você
  2. Anatomia de uma aplicação Beanstalk
  3. Environments: dev, staging, prod
  4. Preparando o serviço Orders
  5. Configurando IAM para Beanstalk
  6. Primeiro deploy
  7. Health checks e auto-recovery
  8. Logs e troubleshooting
  9. Atualizando o serviço (deploy contínuo)
  10. Variáveis de ambiente e configuração
  11. Exercícios de fixação
  12. Próximos passos

01. O que Beanstalk faz por você

Antes de subir qualquer coisa, é importante entender exatamente o que o Beanstalk automatiza. Sem isso, você vai usar uma ferramenta poderosa como caixa preta — e quando algo der errado, vai estar perdido.

O problema que ele resolve

Subir uma aplicação Node.js na AWS sem Beanstalk envolve: criar uma VPC, subnets, security groups, lançar uma EC2, instalar Node, configurar PM2 ou systemd, configurar nginx ou ALB, configurar auto-scaling, configurar deploy via SSH ou pipeline — uma quantidade enorme de decisões e configurações para algo simples.

Beanstalk pega tudo isso e te entrega como uma plataforma. Você sobe um zip com seu código, ele cuida do resto.

O que ele provisiona automaticamente

  • EC2 instances com a runtime correta (Node.js 20, Python, Java etc).
  • Application Load Balancer com health check e SSL.
  • Auto Scaling Group com regras configuráveis.
  • CloudWatch para logs e métricas.
  • Security Groups com regras seguras por padrão.
  • S3 bucket para guardar versões da aplicação.
  • Notifications via SNS para mudanças de estado do environment.

O que ele NÃO faz

  • Não cria seu banco de dados (RDS pode ser integrado, mas é opcional).
  • Não escreve seu código por você.
  • Não substitui boas práticas de observabilidade — você ainda precisa instrumentar logs.
  • Não escolhe a arquitetura por você (single-instance vs load-balanced).

02. Anatomia de uma aplicação Beanstalk

O vocabulário do Beanstalk pode confundir no começo. Vamos esclarecer.

Os três níveis de hierarquia

  • Application — o nome lógico do seu sistema. Exemplo: orders-service. Uma application contém uma ou mais versions e environments.
  • Application Version — um pacote de código (zip) com uma versão específica. Exemplo: v1.0.0, v1.1.0. Cada deploy cria uma nova version.
  • Environment — uma instância rodando da aplicação. Pode ter múltiplos environments para a mesma application: orders-dev, orders-prod.

Tipos de environment

TipoQuando usarComponentes
Web ServerAPIs e aplicações HTTPEC2 + ALB + ASG
WorkerProcessamento de tarefas em background via SQSEC2 + SQS + ASG

Para o nosso projeto, todos os microserviços são Web Server — recebem requisições HTTP. Worker environments são interessantes para processamento assíncrono, mas vamos preferir Lambda para essa função no projeto.

Single-instance vs load-balanced

Ao criar um environment, você escolhe entre dois modos:

  • Single-instance — apenas uma EC2, sem ALB. Barato (sem custo do ALB) e simples. Ideal para dev/estudo.
  • Load-balanced — ALB + Auto Scaling com 1+ instâncias. Resiliente. Custa ~US$ 16/mês a mais (ALB).

Plataforma e versão

Cada environment usa uma platform — basicamente uma AMI pré-configurada. Vamos usar Node.js 20 running on 64bit Amazon Linux 2023. AWS atualiza essas plataformas periodicamente; você pode (e deve) atualizar quando novas versões forem lançadas.

03. Environments: dev, staging, prod

Boa parte da disciplina de DevOps moderna passa por separar ambientes. Beanstalk facilita isso enormemente.

Por que separar ambientes?

  • Isolamento — bug em dev não afeta prod.
  • Configurações independentes — endpoints, credenciais, capacidade diferentes.
  • Pipeline progressivo — código vai dev → staging → prod, com validação em cada etapa.
  • Custos controlados — dev usa instância menor; prod usa o necessário.

Estratégia para o projeto

Para o estudo, vamos usar apenas o environment de dev de cada serviço. Em projetos reais você teria os três (dev, staging, prod) — mas o setup é idêntico, multiplicado por 3. Não há ganho de aprendizado em fazer isso agora.

Naming convention

Adotaremos o padrão:

Application name:  <serviço>-service
Environment name:  <serviço>-<ambiente>

# Exemplos:
orders-service / orders-dev
inventory-service / inventory-dev
payments-service / payments-dev

Aplique consistência. Beanstalk usa esses nomes em URLs, em logs, em events — então qualquer inconsistência vai te confundir mais tarde.

04. Preparando o serviço Orders

Antes do deploy, você precisa de uma aplicação Node.js mínima rodando. Aqui vamos definir o que precisa estar pronto e te guiar pela estrutura — mas o código você escreve.

Estrutura sugerida do projeto

orders-service/
├── src/
│   ├── index.js          # entrypoint
│   ├── routes/
│   │   └── orders.js     # rotas REST
│   ├── services/
│   │   └── ordersDb.js   # acesso ao DynamoDB
│   └── middleware/
│       └── errorHandler.js
├── package.json
├── package-lock.json
├── .ebignore             # arquivos a NÃO incluir no zip
└── README.md

Requisitos mínimos do package.json

  • start script — Beanstalk roda npm start por padrão.
  • node engines — declare a versão do Node compatível com a plataforma.
  • express ou framework HTTP equivalente.
  • @aws-sdk/client-dynamodb e @aws-sdk/lib-dynamodb para acessar tabelas.

O que sua aplicação precisa atender

  • Escutar na porta dada por process.env.PORT — Beanstalk define essa variável (geralmente 8080).
  • Endpoint GET / ou GET /health retornando 200 — para o health check.
  • Logs em stdout/stderr — Beanstalk captura automaticamente para CloudWatch.
  • Não persistir nada localmente — instâncias são efêmeras; use o DynamoDB ou S3.
  • Endpoints implementando os contratos da seção 7 do Módulo 01.

O arquivo .ebignore

Funciona como .gitignore: lista arquivos que não devem ser incluídos no zip de deploy. Sempre exclua:

node_modules/
.git/
.env
.env.local
*.log
.DS_Store
coverage/
tests/

Não inclua node_modules — Beanstalk roda npm install automaticamente após o upload.

Validando localmente

Antes de fazer qualquer deploy, sua aplicação precisa rodar limpa localmente:

cd orders-service
npm install
PORT=8080 npm start
 
# Em outro terminal:
curl http://localhost:8080/health
# resposta esperada: {"status":"ok"} ou similar

05. Configurando IAM para Beanstalk

Antes do deploy, precisamos garantir que: (a) o Beanstalk tem permissão para criar recursos AWS; (b) as instâncias EC2 têm permissão para acessar o DynamoDB.

Service role do Beanstalk

Quando o Beanstalk precisa criar EC2, configurar ALB, escrever em CloudWatch, ele assume uma service role. Por padrão, AWS cria essa role automaticamente na primeira vez (chamada aws-elasticbeanstalk-service-role).

Instance profile (mais importante)

Esta é a role que as instâncias EC2 vão assumir. É aqui que você dá ao Orders Service permissão para acessar a tabela DynamoDB Orders.

AWS cria automaticamente uma role chamada aws-elasticbeanstalk-ec2-role com permissões básicas de Beanstalk. Você precisa adicionar permissão específica para o DynamoDB.

Criando a policy customizada

  1. Vá em IAM > Policies > Create policy.
  2. Use o JSON editor e cole a policy abaixo.
  3. Substitua 123456789012 pelo ID da sua conta.
  4. Nome da policy: orders-service-dynamodb-access.
  5. Em IAM > Roles, encontre aws-elasticbeanstalk-ec2-role.
  6. Clique em Add permissions > Attach policies e adicione a policy criada.

Policy JSON

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:PutItem",
        "dynamodb:UpdateItem",
        "dynamodb:DeleteItem",
        "dynamodb:Query"
      ],
      "Resource": [
        "arn:aws:dynamodb:us-east-1:123456789012:table/Orders",
        "arn:aws:dynamodb:us-east-1:123456789012:table/Orders/index/*"
      ]
    }
  ]
}

Quando subirmos Inventory e Payments, vamos criar policies análogas para essas tabelas. Cada serviço, sua policy.

06. Primeiro deploy

Hora da verdade. Vamos subir o Orders Service no Beanstalk.

Criando o pacote zip

No diretório raiz do seu projeto:

cd orders-service
 
# Garante que .ebignore existe e está correto
cat .ebignore
 
# Cria o zip excluindo o que está no .ebignore
zip -r orders-v1.zip . -x '@.ebignore'
 
# Verifica o conteúdo (não deve ter node_modules!)
unzip -l orders-v1.zip | head

Criando a aplicação no console

  1. Console AWS > Elastic Beanstalk.
  2. Confirme região us-east-1.
  3. Clique em Create application.
  4. Application name: orders-service.
  5. Tags: Project=order-system, Environment=dev.
  6. Platform: Node.js 20 running on 64bit Amazon Linux 2023.
  7. Application code: Upload your code > selecione orders-v1.zip.
  8. Version label: v1.0.0.
  9. Presets: escolha Single instance (Free Tier eligible).
  10. Clique Next para continuar com a configuração detalhada.

Configuração detalhada (importante)

  1. Service role: use a default aws-elasticbeanstalk-service-role.
  2. EC2 instance profile: use aws-elasticbeanstalk-ec2-role (com a policy DynamoDB que criamos).
  3. Instance type: t2.micro (Free Tier).
  4. Instance metadata service: versão v2 (mais segura).
  5. Root volume type: General Purpose (SSD), 8 GB.
  6. Environment name: orders-dev.
  7. Environment properties (variáveis de ambiente): definiremos na seção 10.
  8. Revise tudo e clique em Submit.

Acompanhando o deploy

O environment leva de 5 a 10 minutos para criar. Você vai ver eventos rolando em tempo real:

  • Created CloudWatch alarms
  • Created security group
  • Created EC2 instance(s)
  • Application available at <url>
  • Environment health: Ok / Warning / Severe

07. Health checks e auto-recovery

O Beanstalk monitora continuamente sua aplicação. Entender como funcionam os health checks é crucial para diagnosticar problemas rapidamente.

Os dois tipos de health check

TipoO que verificaFrequência
BasicApenas se a EC2 está respondendoA cada 30s
EnhancedEC2 + ALB + métricas + logs do appA cada 10s

Use Enhanced sempre. É grátis (entra no Free Tier) e te dá visibilidade muito superior.

Estados de saúde

EstadoSignificado
OkTudo funcionando normalmente
WarningHá algum problema detectado, mas não crítico
DegradedPerformance degradada (ex: muitos 5xx)
SevereSério problema — possivelmente fora do ar
PendingMudança em andamento (deploy, escala)
UnknownBeanstalk não consegue determinar

Health check path

Por padrão, o ALB faz GET no path /. Se sua aplicação tem um endpoint específico, configure-o em Configuration > Load balancer > Health check path. Recomendo:

Health check path: /health

// Implementação sugerida (apenas exemplo):
app.get('/health', (req, res) => {
  // Idealmente, faça uma checagem real:
  // - DynamoDB respondendo?
  // - dependências críticas ok?
  res.json({ status: 'ok' });
});

Auto-recovery

Quando uma instância EC2 falha (ou o health check falha por algum tempo), o Beanstalk automaticamente termina a instância e cria uma nova. Em single-instance environments, isso significa downtime de 1-2 minutos. Em load-balanced, o tráfego é redirecionado para outras instâncias enquanto a doente é substituída.

08. Logs e troubleshooting

Cedo ou tarde alguma coisa vai dar errado. Saber onde olhar é o que separa 30 minutos de debugging de 3 horas.

Onde estão os logs

  • Console do environment > Logs > Request logs — pega snapshots dos logs.
  • CloudWatch Logs > /aws/elasticbeanstalk/<env-name>/... — fluxo contínuo (precisa habilitar).
  • SSH na EC2 > /var/log/ — em último caso, debugging direto.

Habilitando CloudWatch Logs

  1. Environment > Configuration > Software > Edit.
  2. Em CloudWatch Logs, marque Log streaming.
  3. Retention: 7 dias (suficiente para o estudo).
  4. Lifecycle: Keep logs after terminating environment? Não.
  5. Salve.

Os arquivos de log que importam

ArquivoO que contém
nodejs/nodejs.logStdout/stderr da sua aplicação
nginx/access.logRequisições HTTP recebidas
nginx/error.logErros do nginx (proxy reverso)
eb-engine.logLogs do deploy do Beanstalk
eb-hooks.logHooks de pré/pós deploy

Erros comuns no primeiro deploy

  • Health check failing — Aplicação não escutou na porta 8080, ou o endpoint /health retorna != 200.
  • Application Version not found — Zip corrompido ou tamanho excedendo limite. Refaça o zip.
  • Permission denied (DynamoDB) — Policy não foi anexada à instance role. Revise a seção 5.
  • npm install fails — package.json com versão inválida ou dependência privada sem credenciais.
  • Process exits — Sua aplicação está crashando. Veja nodejs.log.

09. Atualizando o serviço

Subir a primeira versão é fácil. Subir a 50ª versão de forma confiável é o que separa um sistema de brinquedo de um sistema de produção.

Como atualizar via console

  1. Faça as mudanças no código local.
  2. Crie um novo zip: orders-v1.1.zip.
  3. Environment > Upload and deploy.
  4. Selecione o novo zip.
  5. Version label: v1.1.0 (sempre incremente).
  6. Clique em Deploy.

Estratégias de deploy

EstratégiaComo funcionaRisco
All at onceAtualiza todas as instâncias ao mesmo tempoDowntime durante o deploy
RollingAtualiza em batchesCapacidade reduzida temporariamente
Rolling with batchLança novas, depois remove antigasCusto extra durante deploy
ImmutableCria ASG paralelo, troca após validaçãoMais lento, mas seguro

Em single-instance, só dá para usar All at once (não há mais instâncias para fazer rolling). Em load-balanced de produção, Immutable é o mais seguro — sem nenhum downtime, fácil rollback.

Rollback

Se algo der errado depois do deploy, você pode reverter para uma versão anterior:

  1. Environment > Application Versions.
  2. Encontre a versão anterior estável.
  3. Clique em Deploy ao lado dela.

10. Variáveis de ambiente e configuração

Sua aplicação não pode ter configurações hardcoded. Endpoints, nomes de tabela, feature flags — tudo deve vir de variáveis de ambiente.

Configurando no Beanstalk

  1. Environment > Configuration > Updates, monitoring, and logging > Edit.
  2. Vá até a seção Environment properties.
  3. Adicione pares chave-valor.
  4. Salve. O Beanstalk reinicia a aplicação para aplicar.

Variáveis típicas para o Orders Service

AWS_REGION=us-east-1
DYNAMODB_TABLE_NAME=Orders
LOG_LEVEL=info
NODE_ENV=production
PAYMENTS_SERVICE_URL=https://payments-dev.us-east-1.elasticbeanstalk.com
SNS_ORDER_CREATED_TOPIC_ARN=arn:aws:sns:us-east-1:123456789012:order-created

No código, acesse via process.env:

// Apenas exemplo de como acessar — você implementa a lógica.
const region = process.env.AWS_REGION;
const tableName = process.env.DYNAMODB_TABLE_NAME;
 
// Sempre valide:
if (!tableName) {
  throw new Error('DYNAMODB_TABLE_NAME not set');
}

Secrets vs configurações

Para informações comuns (URL, log level), variáveis de ambiente são ok. Para secrets (API keys, senhas), o ideal é usar AWS Secrets Manager ou SSM Parameter Store. Vamos ver isso em módulos futuros — por ora, IAM roles cobrem o uso do DynamoDB sem precisar de credenciais.

11. Exercícios de fixação

Exercício
01

Suba o Orders Service

Implemente o serviço Orders com pelo menos os endpoints POST /v1/orders, GET /v1/orders/:id e GET /health. Faça o deploy completo seguindo as seções 4-6. Confirme que: (a) o environment está saudável; (b) você consegue criar um pedido via curl; (c) o pedido aparece na tabela DynamoDB.

Exercício
02

Force um erro

Faça um deploy de uma versão com bug proposital (ex: throw em app.listen). Observe: o que muda no painel? Quanto tempo até detectar? Onde aparece o erro nos logs? Faça rollback para a versão anterior.

Exercício
03

Configurações via env

Modifique seu serviço para ler o nome da tabela de uma variável DYNAMODB_TABLE_NAME. Crie a tabela Orders-test no DynamoDB. Mude a env var no Beanstalk apontando para a nova tabela. Confirme que novos pedidos vão para Orders-test, sem mudar uma linha de código.

Exercício
04

Suba também Inventory e Payments

Repita todo o processo para os outros dois serviços. Crie applications, policies IAM (cada serviço com acesso só à sua tabela), e environments. Ao final, você deve ter três URLs do Beanstalk respondendo independentemente.

Exercício
05

Reflexão: limites do Beanstalk

Em texto livre (10-15 linhas), descreva: “Em que ponto Beanstalk começa a fazer falta? Que tipo de necessidade levaria você a migrar para ECS ou EKS?” Pense em escala, custos, complexidade.

12. Próximos passos

Conquista importante: você tem três microserviços rodando em produção na AWS. No próximo módulo, vamos eliminar todo o trabalho manual de console.

O que você aprendeu

  • Anatomia de uma aplicação Beanstalk: application, version, environment.
  • Configurar IAM roles e instance profiles com least privilege.
  • Fazer o primeiro deploy de um microserviço Node.js.
  • Health checks (basic vs enhanced) e auto-recovery.
  • Onde encontrar logs e como diagnosticar problemas comuns.
  • Estratégias de deploy e como fazer rollback.
  • Configurar variáveis de ambiente sem hardcoding.

O que vem no Módulo 04

CloudFormation: tudo como código. Vamos pegar tudo o que fizemos manualmente (tabelas DynamoDB, applications Beanstalk, policies IAM) e transformar em templates YAML versionáveis. Será o módulo mais transformador do curso — depois dele, você nunca mais vai querer clicar no console para criar recursos.

Deploy é apenas o começo. Boa jornada — Módulo 04 a seguir.

Posts relacionados