Reorganização da infraestrutura em stateful e stateless
TLDR: Quebrar o state monolítico do projeto MKT em states isolados por serviço, separando recursos com dado (
stateful/) dos recursos de computação (stateless/), para que umterraform destroynunca alcance o banco.
Contexto
A infraestrutura do MKT tinha banco, cache e aplicações no mesmo state do Terraform. Isso criava quatro problemas:
- Risco de perda de dado —
terraform destroyno MKT levava os dados do banco junto. - Proteção insuficiente —
prevent_destroyé contornável com a flag-target. - Scripts complexos — todo script calculava caminhos relativos como
../../../../../bin/tf. - Sem separação — recursos com dado e recursos de computação misturados.
Objetivos
- State isolado por serviço, para que falhas e destroys não cascateiem.
prevent_destroyem banco e cache, que passam a ser destruídos explicitamente e em separado.- Configuração do messagebroker (vhost/user) separada do runtime da aplicação, para recriar uma sem tocar na outra.
- Um helper de bootstrap que elimine o cálculo de caminho relativo nos scripts.
- Hierarquia de targets
makeem quatro níveis paraapply,plan,taintedestroy.
Fora de escopo
- Migração de dado. A decisão foi destruir o MKT existente e reconstruir do zero — o projeto estava em fase de teste, o dado podia ser recriado e a mesa limpa evitava drift de state escondido.
- Granularidade dentro de
shared/(kubernetes, messagebroker) — ficou para depois. - Gerador de template para novos contextos.
Mudanças
Layout
``` bootstrap/ ├── env.sh # helper: carrega .env e exporta a função tf() └── install.sh # instala o wehive em /usr/local/bin
src/stacks/ ├── shared/terraform/ # INALTERADO (kubernetes + messagebroker) ├── stateful/mkt/ │ ├── database/terraform/ # state isolado + prevent_destroy │ └── cache/terraform/ # state isolado + prevent_destroy └── stateless/mkt/n8n/ ├── prepare/terraform/ # vhost/user do messagebroker └── runtime/terraform/ # deploy no App Platform ou Kubernetes ```
Hierarquia de targets
```makefile # Nível 1: terraform específico (grão mais fino) stateful.mkt.database.apply stateful.mkt.cache.apply stateless.mkt.n8n.prepare.apply stateless.mkt.n8n.runtime.apply
Nível 2: aplicação completa (prepare + runtime)
stateless.mkt.n8n.apply
Nível 3: camada stateful / stateless
stateful.mkt.apply stateless.mkt.apply
Nível 4: projeto completo
mkt.apply ```
Helper de bootstrap
bootstrap/env.sh detecta a raiz do projeto (via git rev-parse --show-toplevel ou presença de .env), carrega o .env e exporta uma função tf() que chama $PROJECT_ROOT/bin/tf. Todo script passa a começar com source wehive (ou o fallback para bootstrap/env.sh) em vez de calcular caminho relativo.
Estrutura do state
wehive-terraform-states/
└── stacks/
├── shared/terraform.tfstate
├── stateful/mkt/{database,cache}/terraform.tfstate
└── stateless/mkt/n8n/{prepare,runtime}/terraform.tfstate
Riscos aceitos
| Risco | Mitigação |
|---|---|
| Perda de dado na reorganização | MKT em teste; dado recriável |
| Scripts quebram na transição | testar o helper de bootstrap primeiro |
| Conflito de state | usar chaves de state completamente novas |
| Complexidade dos makefiles | hierarquia de 4 níveis com nomenclatura consistente |
Como verificar
- Toda a infraestrutura do MKT sobe com a estrutura nova.
- Os 4 níveis de atalho
makefuncionam. - O comando
wehiveestá instalado e funcional. - Nenhum caminho relativo restou nos scripts.
- Destruir o stateless não afeta o stateful.
- Banco e cache têm
prevent_destroy.
Documentação
CLAUDE.md— seção de estrutura de diretórios atualizada.- Guia de primeiros passos.
Nota histórica: a separação stateful/stateless sobreviveu, mas os caminhos definidos aqui foram alterados depois pela reestruturação da infraestrutura, que moveu
makefiles/para.project/make/esrc/stacks/shared/parasrc/shared/.