AWS na Prática · 03 — Elastic Beanstalk
Subindo o primeiro microserviço em produção, com PaaS gerenciado.
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
- O que Beanstalk faz por você
- Anatomia de uma aplicação Beanstalk
- Environments: dev, staging, prod
- Preparando o serviço Orders
- Configurando IAM para Beanstalk
- Primeiro deploy
- Health checks e auto-recovery
- Logs e troubleshooting
- Atualizando o serviço (deploy contínuo)
- Variáveis de ambiente e configuração
- Exercícios de fixação
- 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
| Tipo | Quando usar | Componentes |
|---|---|---|
| Web Server | APIs e aplicações HTTP | EC2 + ALB + ASG |
| Worker | Processamento de tarefas em background via SQS | EC2 + 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 similar05. 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
- Vá em IAM > Policies > Create policy.
- Use o JSON editor e cole a policy abaixo.
- Substitua 123456789012 pelo ID da sua conta.
- Nome da policy: orders-service-dynamodb-access.
- Em IAM > Roles, encontre aws-elasticbeanstalk-ec2-role.
- 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 | headCriando a aplicação no console
- Console AWS > Elastic Beanstalk.
- Confirme região us-east-1.
- Clique em Create application.
- Application name: orders-service.
- Tags: Project=order-system, Environment=dev.
- Platform: Node.js 20 running on 64bit Amazon Linux 2023.
- Application code: Upload your code > selecione orders-v1.zip.
- Version label: v1.0.0.
- Presets: escolha Single instance (Free Tier eligible).
- Clique Next para continuar com a configuração detalhada.
Configuração detalhada (importante)
- Service role: use a default aws-elasticbeanstalk-service-role.
- EC2 instance profile: use aws-elasticbeanstalk-ec2-role (com a policy DynamoDB que criamos).
- Instance type: t2.micro (Free Tier).
- Instance metadata service: versão v2 (mais segura).
- Root volume type: General Purpose (SSD), 8 GB.
- Environment name: orders-dev.
- Environment properties (variáveis de ambiente): definiremos na seção 10.
- 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
| Tipo | O que verifica | Frequência |
|---|---|---|
| Basic | Apenas se a EC2 está respondendo | A cada 30s |
| Enhanced | EC2 + ALB + métricas + logs do app | A cada 10s |
Use Enhanced sempre. É grátis (entra no Free Tier) e te dá visibilidade muito superior.
Estados de saúde
| Estado | Significado |
|---|---|
| Ok | Tudo funcionando normalmente |
| Warning | Há algum problema detectado, mas não crítico |
| Degraded | Performance degradada (ex: muitos 5xx) |
| Severe | Sério problema — possivelmente fora do ar |
| Pending | Mudança em andamento (deploy, escala) |
| Unknown | Beanstalk 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
- Environment > Configuration > Software > Edit.
- Em CloudWatch Logs, marque Log streaming.
- Retention: 7 dias (suficiente para o estudo).
- Lifecycle: Keep logs after terminating environment? Não.
- Salve.
Os arquivos de log que importam
| Arquivo | O que contém |
|---|---|
| nodejs/nodejs.log | Stdout/stderr da sua aplicação |
| nginx/access.log | Requisições HTTP recebidas |
| nginx/error.log | Erros do nginx (proxy reverso) |
| eb-engine.log | Logs do deploy do Beanstalk |
| eb-hooks.log | Hooks 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
- Faça as mudanças no código local.
- Crie um novo zip: orders-v1.1.zip.
- Environment > Upload and deploy.
- Selecione o novo zip.
- Version label: v1.1.0 (sempre incremente).
- Clique em Deploy.
Estratégias de deploy
| Estratégia | Como funciona | Risco |
|---|---|---|
| All at once | Atualiza todas as instâncias ao mesmo tempo | Downtime durante o deploy |
| Rolling | Atualiza em batches | Capacidade reduzida temporariamente |
| Rolling with batch | Lança novas, depois remove antigas | Custo extra durante deploy |
| Immutable | Cria ASG paralelo, troca após validação | Mais 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:
- Environment > Application Versions.
- Encontre a versão anterior estável.
- 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
- Environment > Configuration > Updates, monitoring, and logging > Edit.
- Vá até a seção Environment properties.
- Adicione pares chave-valor.
- 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
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.
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.
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.
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.
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.