Infraestrutura AWS do projeto FIAP X em AWS CDK (TypeScript). Provisiona todos os recursos necessários para rodar os três microsserviços (api, processor, notification) no AWS ECS Fargate dentro de uma conta AWS Academy Learner Lab.
| Stack | Recursos |
|---|---|
FiapxNetworkStack |
VPC (2 AZs, 1 NAT gateway), subnets pública / privada / isolada |
FiapxDataStack |
RDS PostgreSQL 15 (t3.micro), ElastiCache Redis (t3.micro), S3 fiapx-videos-{account}, SQS (process-video-queue + DLQ, update-video-status-queue, notificate-video-status-queue), SNS videos-events (fan-out → as duas filas de status), ECR (fiapx-api, fiapx-processor, fiapx-notification) |
FiapxSecretsStack |
Secrets Manager: /fiapx/jwt/secret (gerado automaticamente), /fiapx/smtp/credentials (inserido manualmente) |
FiapxComputeStack |
ECS Cluster Fargate + Cloud Map fiapx.local, serviços api (ALB público, autoscaling CPU 1→4), processor (autoscaling por profundidade de fila 1→10), notification (autoscaling 0→2). Cada serviço tem um sidecar FireLens (Fluent Bit) que roteia logs para Loki. |
FiapxMonitoringStack |
Prometheus (scrape via Cloud Map DNS), Loki (agregação de logs), Tempo (traces OTLP), Grafana (ALB público) — todos self-hosted no mesmo cluster Fargate. Configs carregadas de config/*.yml via SSM Parameter. Dados persistidos em EFS. |
AMP/AMG e EKS não estão disponíveis no Learner Lab. Toda a stack de observabilidade roda como tasks Fargate no mesmo cluster.
serviço ──stdout──► Fluent Bit (FireLens) ──push──► Loki :3100
serviço ──OTel──────────────────────────────────────► Tempo :4318
serviço ──/metrics──────────────────────────────────► Prometheus :9090 (scrape)
│
└──► Grafana :3000 (ALB público)
Cada serviço expõe três endpoints:
| Endpoint | Descrição |
|---|---|
GET /health |
Health check do ECS / ALB |
GET /metrics |
Métricas Prometheus (Go runtime + processo) |
GET /test |
Smoke test: sempre loga a requisição, 20% de chance de retornar 500 |
O endpoint /test é útil para gerar tráfego real nos três backends de observabilidade imediatamente após o deploy.
| Ferramenta | Versão mínima | Instalação |
|---|---|---|
| Node.js | 18 | nodejs.org |
| npm | 8 | incluído com Node.js |
| AWS CLI v2 | 2.x | docs.aws.amazon.com/cli |
| AWS CDK CLI | 2.x | npm install -g aws-cdk |
| Docker | 24+ | necessário para build e push das imagens |
Este projeto foi desenhado para o AWS Academy Learner Lab. Antes de qualquer operação:
- Acesse o Lab no Canvas e clique em Start Lab.
- Após o lab iniciar, clique em AWS Details e copie as credenciais temporárias (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKEN). - Copie também o ARN do LabRole (geralmente
arn:aws:iam::<ACCOUNT_ID>:role/LabRole).
As credenciais expiram após ~4 horas. Repita esse passo no início de cada sessão.
cd media-processor-cdk
npm installexport AWS_ACCESS_KEY_ID="ASIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..."
export AWS_DEFAULT_REGION="us-east-1"
export CDK_DEFAULT_ACCOUNT="$(aws sts get-caller-identity --query Account --output text)"
export LAB_ROLE_ARN="arn:aws:iam::${CDK_DEFAULT_ACCOUNT}:role/LabRole"O bootstrap usa o LabRole em todos os roles do CDK para não criar novos papéis IAM — que o Learner Lab não permite.
npx cdk bootstrap \
--cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \
aws://${CDK_DEFAULT_ACCOUNT}/us-east-1Se o bucket de bootstrap já existir de uma sessão anterior, esse comando é seguro de repetir — ele é idempotente.
O deploy é feito em duas fases: primeiro a infraestrutura base, depois o build e push das imagens, e por fim os serviços.
npx cdk deploy FiapxNetworkStack FiapxDataStack FiapxSecretsStack --require-approval neverOs repositórios ECR são criados na fase 1. Após o deploy do FiapxDataStack, os nomes dos repositórios ficam disponíveis nos outputs do CloudFormation.
# Autenticar no ECR
aws ecr get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin \
${CDK_DEFAULT_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com
# Build e push — executar a partir da raiz do media-processor/
cd ../media-processor
docker build -f services/api/Dockerfile -t fiapx-api .
docker build -f services/processor/Dockerfile -t fiapx-processor .
docker build -f services/notification/Dockerfile -t fiapx-notification .
ECR="${CDK_DEFAULT_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com"
docker tag fiapx-api ${ECR}/fiapx-api:latest
docker tag fiapx-processor ${ECR}/fiapx-processor:latest
docker tag fiapx-notification ${ECR}/fiapx-notification:latest
docker push ${ECR}/fiapx-api:latest
docker push ${ECR}/fiapx-processor:latest
docker push ${ECR}/fiapx-notification:latest
# Build e push do frontend — executar a partir de media-processor-frontend/
cd ../media-processor-frontend
docker build -t fiapx-frontend .
docker tag fiapx-frontend ${ECR}/fiapx-frontend:latest
docker push ${ECR}/fiapx-frontend:latestcd ../media-processor-cdk
npx cdk deploy FiapxComputeStack FiapxMonitoringStack FiapxFrontendStack --require-approval nevernpx cdk deploy --all --require-approval never# Rebuildar e fazer push com nova tag
IMAGE_TAG=$(git rev-parse --short HEAD)
docker build -f services/api/Dockerfile -t ${ECR}/fiapx-api:${IMAGE_TAG} .
docker push ${ECR}/fiapx-api:${IMAGE_TAG}
# repetir para processor e notification
# Reimplantar apontando para a nova tag
npx cdk deploy FiapxComputeStack --require-approval never -c imageTag=${IMAGE_TAG}O secret /fiapx/smtp/credentials é criado vazio. Preencha com as credenciais do Mailtrap (dev) ou SendGrid/Gmail (prod):
aws secretsmanager put-secret-value \
--secret-id /fiapx/smtp/credentials \
--secret-string '{"host":"smtp.mailtrap.io","port":"587","user":"SEU_USER","pass":"SUA_SENHA"}'
# Force redeploy do notification para carregar o novo valor
aws ecs update-service \
--cluster FiapxComputeStack-Cluster \
--service FiapxComputeStack-NotificationService \
--force-new-deploymentAs URLs dos ALBs são exibidas ao final do deploy como outputs do CDK. Para consultá-las novamente:
aws cloudformation describe-stacks \
--stack-name FiapxComputeStack \
--query "Stacks[0].Outputs"
aws cloudformation describe-stacks \
--stack-name FiapxMonitoringStack \
--query "Stacks[0].Outputs"| Output | Stack | Descrição |
|---|---|---|
ApiUrl |
FiapxComputeStack |
URL pública do ALB da API (http://...elb.amazonaws.com) |
FrontendUrl |
FiapxFrontendStack |
URL pública do frontend (http://...elb.amazonaws.com) |
GrafanaUrl |
FiapxMonitoringStack |
URL pública do Grafana (http://...elb.amazonaws.com) |
LokiEndpoint |
FiapxMonitoringStack |
Endpoint interno do Loki (VPC-only) |
TempoOtlpHttp |
FiapxMonitoringStack |
Endpoint OTLP HTTP do Tempo (VPC-only) |
HTTPS não está disponível no Learner Lab (sem Route53 nem ACM gerenciado). Os endpoints ficam em HTTP simples.
Após o deploy, acesse o Grafana em GrafanaUrl e:
- Prometheus → Menu Explore → selecione datasource Prometheus → verifique métricas
go_goroutinesdos serviços - Loki → Menu Explore → selecione datasource Loki → filtre por
{job="api"}— logs aparecem assim que/testrecebe chamadas - Tempo → no Grafana, abra um log do Loki que contenha
trace_id→ clique no ícone de link para abrir o trace no Tempo
Para gerar tráfego rapidamente:
API_URL=$(aws cloudformation describe-stacks \
--stack-name FiapxComputeStack \
--query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" \
--output text)
# 20 requisições — ~4 devem retornar 500
for i in $(seq 1 20); do curl -s ${API_URL}/test | jq .status; doneTodos os recursos têm removalPolicy=DESTROY. Para apagar tudo ao fim da sessão:
npx cdk destroy --all --forceNão é necessário destruir manualmente — o Learner Lab limpa a conta automaticamente ao encerrar. Use
destroyapenas se quiser liberar recursos durante a sessão para redeploy limpo.
| Restrição | Como o CDK lida |
|---|---|
| Sem criação de IAM roles | DefaultStackSynthesizer aponta todos os roles para LabRole; task role e execution role = LabRole |
| Sem EKS | ECS Fargate |
| Sem AMP/AMG | Prometheus + Grafana + Loki + Tempo self-hosted como tasks Fargate |
| Sem SES fora de sandbox | SMTP externo via Secrets Manager |
| Sem KMS custom keys | Criptografia com chaves AWS-managed (aws/rds, aws/s3, etc.) |
| Sem Route53 / ACM | ALB com DNS *.elb.amazonaws.com, HTTP simples |
| Credenciais rotativas a cada ~4h | Re-exportar variáveis e re-executar cdk deploy |
media-processor-cdk/
├── bin/
│ └── app.ts # entrypoint CDK — instancia e conecta as stacks
├── config/
│ ├── lab.ts # constantes: região, LAB_ROLE_ARN, endpoints internos
│ ├── prometheus.yml # config de scrape do Prometheus
│ ├── loki.yml # config do Loki (single-binary, filesystem)
│ ├── tempo.yml # config do Tempo (OTLP receivers, local storage)
│ └── grafana-datasources.yml # provisioning Grafana: Prometheus + Loki + Tempo
├── lib/
│ ├── network-stack.ts # VPC
│ ├── data-stack.ts # RDS, Redis, S3, SQS, SNS, ECR
│ ├── secrets-stack.ts # Secrets Manager (JWT, SMTP)
│ ├── compute-stack.ts # ECS Fargate (api, processor, notification) + FireLens
│ └── monitoring-stack.ts # Prometheus, Loki, Tempo, Grafana
├── cdk.json
├── package.json
└── tsconfig.json