Skip to content

ADR-002: Arquitetura de Persistência de Dados - Anomalias de Custo

Status: Proposto
Data: 16/10/2025
Contexto: Módulo de Anomalias de Custos AWS - Persistência de dados
Decisores: Equipe FinOps


1. Contexto e Problema

O módulo de Anomalias de Custos atualmente processa dados diretamente da AWS Cost Explorer API através de uma Lambda (new_anomaly_processor.py), mas não persiste essas informações em banco de dados. Isso limita:

  • Histórico e Auditoria: Não há registro histórico das anomalias processadas
  • Performance: Cada requisição demanda chamadas à API AWS, aumentando latência
  • Funcionalidades: Impossibilita features como justificativas, feedback persistente e análises históricas
  • Custos: Chamadas repetidas à API AWS aumentam custos operacionais

Objetivo: Definir e documentar a arquitetura de persistência de dados que permita armazenamento, recuperação e gerenciamento eficiente das anomalias de custo.


2. Decisão Arquitetural

2.1 Processo Escolhido

Implementaremos uma arquitetura de persistência baseada em PostgreSQL com camada de API RESTful através de AWS Lambda + API Gateway, seguindo o padrão BFF (Backend for Frontend).

Fluxo de dados:

AWS Cost Explorer API
    ↓
Lambda Processor (new_anomaly_processor.py)
    ↓
PostgreSQL (RDS)
    ↓
Lambda Endpoints (API Gateway)
    ↓
Frontend (Dashboard)

Características principais:

  • Persistência Relacional: PostgreSQL hospedado em AWS RDS para garantir integridade referencial
  • Processamento Assíncrono: Lambda para processamento batch dos dados AWS
  • API RESTful: Endpoints dedicados para operações CRUD
  • Atualização Programada: EventBridge/CloudWatch Events para execução periódica
  • Retenção Inteligente: Política de 90 dias com exceção para anomalias justificadas

3. Modelo de Banco de Dados

3.1 Estrutura de Tabelas

Tabela: tb_cost_anomalies

Armazena as anomalias de custo detectadas pela AWS.


Tabela: tb_root_causes

Armazena as causas raiz de cada anomalia.


3.2 Diagrama Entidade-Relacionamento (ERD)

Diagrama ERD das Tabelas de Anomalias de Custo

Figura: Diagrama Entidade-Relacionamento (ERD) das tabelas tb_cost_anomalies e tb_root_causes.


3.3 Organização das Queries e Metas

Alteração: O uso de SQLAlchemy foi removido. As queries SQL são realizadas diretamente via comandos SQL brutos (raw SQL) utilizando o driver padrão do Python para PostgreSQL (psycopg2 ou similar). A organização das metas e operações (inserção, atualização, deleção) é feita por funções utilitárias Python, que executam as queries conforme a necessidade de cada endpoint, garantindo atomicidade via transações explícitas.

Exemplo de operação (pseudo-código):

def update_anomaly_feedback(conn, anomaly_id, feedback, justification, justified_by):
    with conn.cursor() as cur:
        cur.execute(
            '''
            UPDATE tb_cost_anomalies
            SET feedback = %s, justification = %s, justified_by = %s, updated_at = NOW()
            WHERE anomaly_id = %s
            ''',
            (feedback, justification, justified_by, anomaly_id)
        )
    conn.commit()

4. Arquitetura de Processamento

4.1 Visão Geral

A arquitetura utilizará múltiplas AWS Lambdas, cada uma responsável por uma operação específica (CRUD), expostas através de API Gateway com endpoints RESTful.

Componentes:

  1. Lambda de Processamento (Existente): new_anomaly_processor.py

  2. Busca dados da AWS Cost Explorer API

  3. Persiste/atualiza dados no PostgreSQL
  4. Executada via EventBridge (agendamento)

  5. Lambda de API (Novos): Endpoints para consulta e atualização

  6. Operações GET, PUT para frontend
  7. Validação e transformação de dados
  8. Expostos via API Gateway

4.2 Repositório

Repositório: plat-eng-finop-cloud-cost-anomalies-engine


Regras de Negócio:

  • Se feedback for alterado, sincronizar com AWS Cost Explorer via API update_anomaly_feedback()
  • Atualizar updated_at timestamp
  • Registrar auditoria da alteração

4.3 Configuração do API Gateway

  • API Gateway REST API com endpoints HTTP para cada Lambda.
  • API Keys obrigatórias para acesso aos endpoints privados.
  • Uso de Usage Plans para controle de quota e throttling.
  • Integração com WAF para proteção contra ataques.
  • CORS configurado conforme necessidade de cada rota.
  • Desabilitação do endpoint default do API Gateway para evitar exposição desnecessária.
  • Rotas privadas (private: true) para endpoints sensíveis.

Exemplo de configuração (trecho do serverless.yml):

provider:
  apiGateway:
    apiKeys:
      - name: ${self:service}-${self:provider.stage}-api-key
        enabled: true
    apiKeySourceType: HEADER
    disableDefaultEndpoint: true
    usagePlan:
      quota:
        limit: 10000
        period: DAY
      throttle:
        burstLimit: 200
        rateLimit: 100
  logs:
    restApi:
      accessLogging: false
      executionLogging: true
  tracing:
    apiGateway: true

custom:
  customDomain:
    enabled: true
    domainName: ${self:service}.${self:provider.stage}.${env:VS}.grupoboticario.digital
    stage: ${self:provider.stage}
    basePath: ""
    createRoute53Record: false
  associateWaf:
    name: acl-backend
    version: V2

Variáveis de Ambiente Necessárias:

  • PG_HOST: Host do banco PostgreSQL
  • PG_PORT: Porta do banco PostgreSQL
  • PG_USER: Usuário do banco
  • PG_PASSWORD: Senha do banco
  • PG_DATABASE: Nome do banco
  • ROLE_ARN: ARN do papel para assumir permissões AWS
  • AWS_ACCOUNT_ID, VS, NEWRELIC_ACCOUNT_ID, NEWRELIC_API_KEY, etc. (conforme já utilizado no projeto)

4.4 Uso de Custom Domain

  • O domínio da API é customizado, ficou definido o padrão:
    https://cloud-cost-anomalies-engine.hml.platform-engineering.grupoboticario.digital
    
  • O domínio é configurado via plugin serverless-domain-manager e não cria registros Route53 automaticamente (createRoute53Record: false).
  • Permite padronização de acesso e integração segura com o frontend.

4.4 Regras de Atualização e Retenção de Dados

Política de Sincronização:

  1. Frequência de Atualização:

  2. Lambda new_anomaly_processor executado uma vez ao dia via EventBridge

  3. Busca anomalias dos últimos 90 dias da AWS Cost Explorer API
  4. Período de 90 dias alinhado com a retenção padrão da AWS

  5. Estratégia de Upsert:

  6. Utilizar anomaly_id como chave de identificação única

  7. Se anomalia já existe: UPDATE (atualizar valores atuais)
  8. Se anomalia é nova: INSERT (criar novo registro)
  9. Root Causes: DELETE + INSERT para cada anomalia (cascata)

  10. Retenção de Dados:

  11. Regra Geral: Anomalias com mais de 90 dias são removidas do banco

  12. Exceção: Anomalias com justification_id != NULL são mantidas permanentemente

  13. Lógica de Cleanup:

    DELETE FROM tb_cost_anomalies
    WHERE anomaly_start_date < (CURRENT_DATE - INTERVAL '90 days')
     AND justification_id IS NULL;
    

  14. Sincronização de Feedback com AWS:

  15. Quando usuário altera feedback via PUT endpoint

  16. Lambda chama update_anomaly_feedback() da AWS Cost Explorer API
  17. Mantém consistência entre banco local e AWS
  18. Em caso de falha: registrar em fila de retry (SQS)

Diagrama de Fluxo de Atualização:

┌─────────────────────────────────────────────────┐
│  EventBridge (diário)                   │
└────────────────┬────────────────────────────────┘
                 │
                 ▼
┌─────────────────────────────────────────────────┐
│  Lambda: new_anomaly_processor                  │
│  ├─ Buscar últimos 90 dias da AWS API          │
│  ├─ Processar anomalias e root causes          │
│  └─ Upsert no PostgreSQL                       │
└────────────────┬────────────────────────────────┘
                 │
                 ▼
┌─────────────────────────────────────────────────┐
│  PostgreSQL RDS                                 │
│  ├─ tb_cost_anomalies                          │
│  ├─ tb_root_causes                             │
└────────────────┬────────────────────────────────┘
                 │
                 ▼
┌─────────────────────────────────────────────────┐
│  Lambda: Cleanup Job (diário)                   │
│  └─ Remove anomalias > 90 dias sem justif.     │
└─────────────────────────────────────────────────┘

5. Visualizações do Usuário (Dashboard)

5.1 Endpoints Utilizados

  • Cards de Métricas:
  • GET /cards
  • Gráficos de Evolução:
  • GET /graph
  • Tabela de Anomalias:
  • GET /table/detected-anomalies
  • Tabela de Causas Raiz:
  • GET /table/anomalies-root-causes
  • Anomalias por Feedback:
  • GET /anomaly-by-feedback
  • Atualização de Justificativa:
  • PUT /update-justification
  • Atualização de Feedback:
  • PUT /update-feedback

5.2 Ações Disponíveis

  • Visualização de métricas agregadas (cards)
  • Visualização de gráficos de tendência e impacto
  • Consulta detalhada de anomalias e causas raiz
  • Filtros por feedback, conta, período, etc.
  • Edição de justificativa e feedback diretamente pela interface

6. Referências


Última Atualização: 31/10/2025
Versão: 1.1
Autor: Gabriel Pepe, Fabio Batimarco