Pular para conteúdo

RFC-007: Deployment Strategy e Ambientes

Campo Valor
Status Draft
Author Time de Tecnologia
Created 2026-02-05
Updated 2026-02-05
Reunião A ser agendada
Deciders Todo o time técnico

Status

🟡 Draft - RFC em elaboração, aguardando apresentação

Contexto e Problema

Processo de deployment documentado em docs/cicd/deployment.md, mas falta:

  • Estratégia de deployment formalizada (rolling, blue-green, canary)
  • Janelas de deploy formalizadas e enforcement
  • Health checks obrigatórios pré e pós deploy
  • Smoke tests automáticos que bloqueiam se falharem
  • Rollback automático quando smoke tests falham
  • Zero-downtime guarantee com validação

Por que resolver isso agora?

  • Deploys manuais são arriscados
  • Downtime ocasional em deploys
  • Falta clareza sobre quando fazer deploy
  • Rollback é manual e lento
  • Smoke tests não são consistentes

Impacto de não resolver

  • Downtime em produção por deploys ruins
  • Bugs em produção não detectados rapidamente
  • Processo de rollback lento e manual
  • Deploys fora de horário causam incidentes
  • Usuários impactados desnecessariamente

Documentação relacionada: - docs/cicd/deployment.md - Processo atual - docs/cicd/pipeline-overview.md - Pipelines - docs/cicd/github-actions.md - GitHub Actions workflows - docs/runbooks/deployment-checklist.md - Checklist - docs/runbooks/rollback-procedure.md - Rollback - docs/infrastructure/environments.md - Configuração ambientes

Proposta de Solução

Deployment strategy com rolling updates, health checks obrigatórios, e rollback automático.

Estratégia: Rolling Deployment

Como funciona: 1. Deploy nova versão em 1 Lambda/container 2. Health check na nova versão 3. Se ok, deploy no restante (1 por vez) 4. Se falhar, rollback automático

Benefícios: - Zero downtime - Rollback rápido (versão anterior ainda rodando) - Gradual (detecta problemas cedo)

Janelas de Deploy

Permitido: - Segunda a Quinta: 10h-16h (horário local) - Exceção: Hotfixes críticos (P0) - qualquer horário

Proibido: - Sextas após 12h (risco de incidente no fim de semana) - Fins de semana (exceto P0 hotfixes) - Feriados - Última semana do mês (período de fechamento)

Enforcement:

# GitHub Actions
- name: Check deploy window
  run: |
    DAY=$(date +%u)  # 1=Mon, 5=Fri
    HOUR=$(date +%H)

    if [ $DAY -eq 5 ] && [ $HOUR -ge 12 ]; then
      echo "Deploy blocked: Friday afternoon"
      exit 1
    fi

    if [ $DAY -eq 6 ] || [ $DAY -eq 7 ]; then
      echo "Deploy blocked: Weekend"
      exit 1
    fi

Health Checks

Pre-deploy health check:

# app/health.py
from fastapi import APIRouter

router = APIRouter()

@router.get("/health")
async def health_check():
    """Health check endpoint."""
    checks = {
        "database": await check_database(),
        "redis": await check_redis(),
        "s3": await check_s3(),
    }

    all_healthy = all(checks.values())

    return {
        "status": "healthy" if all_healthy else "unhealthy",
        "checks": checks,
        "version": os.getenv("APP_VERSION"),
        "timestamp": datetime.utcnow().isoformat()
    }

async def check_database():
    try:
        await db.execute("SELECT 1")
        return True
    except:
        return False

Post-deploy smoke tests:

# tests/smoke/test_critical_endpoints.py
def test_health_endpoint():
    response = requests.get(f"{BASE_URL}/health")
    assert response.status_code == 200
    assert response.json()["status"] == "healthy"

def test_auth_flow():
    # Login
    response = requests.post(f"{BASE_URL}/api/v1/auth/login", json={
        "email": "smoketest@example.com",
        "password": "test123"
    })
    assert response.status_code == 200
    token = response.json()["token"]

    # Use token
    response = requests.get(
        f"{BASE_URL}/api/v1/users/me",
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 200

def test_database_connectivity():
    response = requests.get(f"{BASE_URL}/api/v1/users?page=1&page_size=1")
    assert response.status_code == 200

Deployment Pipeline

# .github/workflows/deploy-production.yml
name: Deploy to Production

on:
  push:
    branches: [main]

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

      - name: Check deploy window
        run: ./scripts/check_deploy_window.sh

      - name: Run tests
        run: |
          pytest --cov --cov-fail-under=70
          npm test

      - name: Build
        run: sam build --use-container

      - name: Backup database
        run: |
          aws rds create-db-snapshot \
            --db-instance-identifier prod-db \
            --db-snapshot-identifier "pre-deploy-$(date +%Y%m%d-%H%M%S)"

      - name: Deploy (rolling)
        run: |
          sam deploy \
            --config-env production \
            --no-fail-on-empty-changeset \
            --capabilities CAPABILITY_IAM

      - name: Health check
        run: |
          sleep 10  # Wait for deployment
          curl -f https://api.seuapp.com/health || exit 1

      - name: Smoke tests
        run: |
          pytest tests/smoke/ --base-url=https://api.seuapp.com

      - name: Rollback on failure
        if: failure()
        run: |
          echo "Smoke tests failed, rolling back..."
          sam deploy \
            --config-env production \
            --parameter-overrides Version=previous

          # Notify team
          curl -X POST $SLACK_WEBHOOK \
            -d '{"text": "🚨 Production deploy FAILED and ROLLED BACK"}'

      - name: Notify success
        if: success()
        run: |
          curl -X POST $SLACK_WEBHOOK \
            -d '{"text": "✅ Production deploy successful"}'

Rollback Automático

Triggers de rollback: - ❌ Smoke tests falharam - ❌ Health check falhou por > 2 minutos - ❌ Error rate > 5% nos primeiros 5 minutos - ❌ P95 latency > 2x baseline

Processo de rollback:

# 1. Rollback código (SAM)
sam deploy --config-env production --parameter-overrides Version=previous

# 2. Rollback migrations (se houve)
python manage.py migrate app_name <previous>
alembic downgrade -1

# 3. Restore backup (se necessário)
aws rds restore-db-instance-from-db-snapshot \
  --db-snapshot-identifier pre-deploy-20260205-140000

# 4. Verificar health
curl https://api.seuapp.com/health

# 5. Notificar time
# Abrir incident
# Postmortem obrigatório

Monitoring Pós-Deploy

Primeiros 5 minutos (crítico): - Error rate < 1% - P95 latency < baseline + 20% - Health checks passando - Zero 500 errors

Primeiros 30 minutos: - Todas as métricas estáveis - Nenhum alarme disparado - Feedback de usuários ok

Primeira hora: - Análise completa de métricas - Comparação com baseline - Confirmar deploy estável

Ambientes

Development (local): - Docker Compose - Banco local ou remoto dev - Sem deploy automático

Staging: - Branch: dev - Deploy: Automático em cada merge - Health checks obrigatórios - Smoke tests obrigatórios - Usado por QA

Production: - Branch: main - Deploy: Automático em cada merge (dentro da janela) - Todos os checks + rollback automático - Monitoramento intensivo

Alternativas Consideradas

Opção 1: Blue-Green Deployment

Prós: - Rollback instantâneo (switch de rota) - Zero downtime garantido - Testing em produção antes de switch

Contras: - 2x custo (dois ambientes completos) - Database migrations complexas - Overhead de manutenção

Por que não escolhemos: Custo não justificado para nosso tamanho. Rolling é suficiente.

Opção 2: Canary Deployment

Prós: - Detecta problemas com 1% de tráfego - Risco minimizado - Gradual

Contras: - Mais complexo de implementar - Requer balanceador sofisticado - Overhead de monitoramento

Por que não escolhemos: Complexidade não justificada ainda. Rolling + smoke tests é suficiente.

Opção 3: Deploy manual sem janelas

Prós: - Máxima flexibilidade

Contras: - Deploys em horários arriscados - Incidentes fora de horário - Time cansado

Por que não escolhemos: Janelas de deploy previnem incidentes.

Análise de Impacto

Impacto Técnico

  • Rolling deployment via SAM/Lambda
  • Health checks e smoke tests obrigatórios
  • Rollback automático
  • Janelas de deploy enforced

Impacto em Negócio

  • ✅ Zero downtime em deploys
  • ✅ Rollback rápido e automático
  • ✅ Bugs detectados antes de impactar usuários
  • ✅ Deploys previsíveis (janelas)
  • ⚠️ Deploy ligeiramente mais lento (+5-10 min)

Riscos

Risco: Smoke tests com falsos positivos bloqueiam deploy

Mitigação: Smoke tests bem escritos e mantidos. Possibilidade de bypass manual em emergências.

Plano de Implementação

Fase 1: Health Checks (Semana 1)

  • Implementar /health endpoint
  • Testes de database, redis, s3
  • Documentar

Fase 2: Smoke Tests (Semana 2)

  • Criar suite de smoke tests
  • Testes de endpoints críticos
  • Integrar no CI/CD

Fase 3: Rolling Deployment (Semana 3)

  • Configurar SAM para rolling
  • Testar em staging
  • Documentar rollback

Fase 4: Automação (Semana 4)

  • Rollback automático
  • Deploy window enforcement
  • Monitoring e alertas

Fase 5: Documentação (Semana 5)

  • Runbook atualizado
  • Treinamento do time
  • Postmortem de deploys anteriores

Métricas de Sucesso

Após 1 mês: - ✅ Zero downtime em deploys - ✅ Rollback testado e funcional - ✅ 100% deploys dentro da janela

Após 3 meses: - ✅ Tempo médio de deploy < 15 min - ✅ Zero incidentes de deploy - ✅ Rollback automático funcionou (se necessário)

Referências