Well-Architected Framework: O Que Realmente Importa na Prática

Os 6 pilares do AWS Well-Architected traduzidos pra realidade. O que aplicar primeiro, o que pode esperar, e os erros que mais vejo em produção.

AWSWell-ArchitectedBoas PráticasArquitetura CloudSegurança

O Well-Architected Framework da AWS tem 6 pilares e centenas de recomendações. Ninguém consegue implementar tudo de cara. Vou compartilhar o que priorizo e por quê.

Os 6 Pilares (Resumo Rápido)

  1. Security - Proteger dados e sistemas
  2. Reliability - Funcionar mesmo quando algo quebra
  3. Performance Efficiency - Usar recursos de forma eficiente
  4. Cost Optimization - Não gastar mais do que precisa
  5. Operational Excellence - Conseguir operar e evoluir o sistema
  6. Sustainability - Minimizar impacto ambiental

Na teoria todos são importantes. Na prática, você precisa escolher onde focar primeiro.

Security - Começo Por Aqui

Segurança não é negociável. Já vi empresa ter dados vazados porque “ia implementar depois”. Não existe depois quando seus dados tão na internet.

O mínimo que faço em todo projeto:

IAM com least privilege - Cada recurso só acessa o que precisa:

resource "aws_iam_policy" "app" {
  name = "app-policy"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "s3:GetObject",
          "s3:PutObject"
        ]
        # Só esse bucket específico, não s3:*
        Resource = "${aws_s3_bucket.app.arn}/*"
      }
    ]
  })
}

Encryption em tudo - Dados em repouso e em trânsito:

# S3 com encryption
resource "aws_s3_bucket_server_side_encryption_configuration" "app" {
  bucket = aws_s3_bucket.app.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "aws:kms"
    }
  }
}

# RDS com encryption
resource "aws_db_instance" "main" {
  storage_encrypted = true
  # ...
}

Secrets Manager pra senhas - Nunca hardcode:

import { SecretsManager } from '@aws-sdk/client-secrets-manager';

const client = new SecretsManager();

async function getDbPassword() {
  const secret = await client.getSecretValue({
    SecretId: 'prod/database/password'
  });
  return JSON.parse(secret.SecretString!).password;
}

Checklist de segurança que uso:

- [ ] MFA no root account
- [ ] IAM policies específicas (não usar AdministratorAccess)
- [ ] Security Groups fechados por padrão
- [ ] S3 buckets privados
- [ ] CloudTrail ativado
- [ ] GuardDuty ligado
- [ ] Secrets no Secrets Manager ou Parameter Store
- [ ] HTTPS em todos endpoints

Reliability - Pra Não Acordar de Madrugada

Nada pior que receber ligação 3h da manhã porque o sistema caiu. Invisto em reliability pra dormir tranquilo.

Multi-AZ é obrigatório em produção

Já vi gente economizando no RDS single-AZ. Funciona até a AZ ter problema - aí fica horas fora do ar esperando recuperar.

resource "aws_db_instance" "main" {
  multi_az = true  # Failover automático

  backup_retention_period = 30  # Point-in-time recovery
}

O custo dobra, mas compensa. Downtime custa mais caro.

Health checks que fazem sentido

Health check muito agressivo derruba instância saudável. Muito lento demora pra detectar problema.

Meu padrão:

health_check {
  healthy_threshold   = 2    # 2 checks OK = healthy
  unhealthy_threshold = 3    # 3 falhas = unhealthy
  timeout             = 5
  interval            = 30   # Checa a cada 30s
  path                = "/health"
}

E o endpoint /health verifica dependências:

app.get('/health', async (req, res) => {
  try {
    // Testa conexão com banco
    await db.query('SELECT 1');

    // Testa conexão com cache
    await redis.ping();

    res.json({ status: 'healthy' });
  } catch (error) {
    res.status(503).json({ status: 'unhealthy', error: error.message });
  }
});

Cost Optimization - Sem Jogar Dinheiro Fora

AWS é fácil de estourar o orçamento se não prestar atenção. Algumas coisas que faço:

Tags em tudo

Sem tags você não sabe de onde vem o custo:

provider "aws" {
  default_tags {
    tags = {
      Environment = "production"
      Project     = "minha-app"
      Owner       = "time-backend"
    }
  }
}

Desligar o que não usa

Ambiente de dev não precisa rodar 24/7:

# Desliga dev às 22h
resource "aws_autoscaling_schedule" "dev_off" {
  scheduled_action_name  = "dev-off"
  min_size               = 0
  max_size               = 0
  desired_capacity       = 0
  recurrence             = "0 22 * * MON-FRI"
  autoscaling_group_name = aws_autoscaling_group.dev.name
}

# Liga dev às 8h
resource "aws_autoscaling_schedule" "dev_on" {
  scheduled_action_name  = "dev-on"
  min_size               = 1
  max_size               = 2
  desired_capacity       = 1
  recurrence             = "0 8 * * MON-FRI"
  autoscaling_group_name = aws_autoscaling_group.dev.name
}

Reserved Instances quando faz sentido

Se o workload é previsível, Reserved Instance economiza 30-60%:

On-Demand t3.medium: $30/mês
Reserved 1 ano:      $19/mês (37% off)
Reserved 3 anos:     $13/mês (57% off)

Só compro reserved pra produção depois de uns 3 meses rodando, quando tenho certeza do sizing.

Operational Excellence - Automatize Tudo

Se você faz manualmente, uma hora vai errar. E não vai lembrar o que fez daqui 6 meses.

Infraestrutura como código

Terraform pra tudo:

terraform {
  backend "s3" {
    bucket         = "meu-terraform-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
}

CI/CD automatizado

Nada de deploy manual:

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: us-east-1

      - name: Deploy
        run: |
          terraform init
          terraform apply -auto-approve

Alertas que importam

Não adianta ter 500 alertas que você ignora. Configuro só o essencial:

  • CPU acima de 80% por 5 minutos
  • Erros 5xx acima de 1%
  • Disco acima de 85%
  • Latência p99 acima do SLA
resource "aws_cloudwatch_metric_alarm" "high_error_rate" {
  alarm_name          = "high-5xx-errors"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 2
  metric_name         = "5XXError"
  namespace           = "AWS/ApplicationELB"
  period              = 300
  statistic           = "Sum"
  threshold           = 10
  alarm_description   = "Mais de 10 erros 5xx em 5 minutos"
  alarm_actions       = [aws_sns_topic.alerts.arn]
}

O Que Deixo Pra Depois

Nem tudo precisa ser perfeito no dia 1. Coisas que implemento conforme o projeto cresce:

  • Performance tuning avançado - Primeiro faz funcionar, depois otimiza
  • DR cross-region - Começo com backup S3 cross-region, DR completo vem depois
  • Sustainability - Importante, mas não é prioridade no MVP

Minha Ordem de Prioridade

  1. Security - Não tem “depois” pra segurança
  2. Reliability - Sistema precisa funcionar
  3. Operational Excellence - Automatizar pra não sofrer
  4. Cost Optimization - Depois que tá rodando, otimiza
  5. Performance Efficiency - Quando tiver problema de performance
  6. Sustainability - Quando os outros estiverem resolvidos

Não é a ordem “certa” da AWS, é a ordem que funciona na prática quando você tem recurso limitado.


Quer fazer uma revisão Well-Architected do seu ambiente? Me chama no LinkedIn.