Dividir um state gigante
State único com toda a infraestrutura tem quatro sintomas conhecidos: plano lento, lock disputado, revisão difícil, e um erro capaz de destruir tudo de uma vez. Dividir resolve os quatro — e a divisão é feita sem tocar em nenhum recurso real, porque mover no state não altera a nuvem.
1. Confirme que vale dividir
Seção intitulada “1. Confirme que vale dividir”Sinais objetivos: terraform plan levando vários minutos, mais de 200 ou 300 recursos no
mesmo state, times diferentes esperando o lock um do outro, e mudanças de aplicação
convivendo com mudanças de rede no mesmo plano.
terraform state list | wc -ltime terraform plan2. Escolha o corte
Seção intitulada “2. Escolha o corte”Corte por frequência de mudança e por dono, não por tipo de recurso.
infra/ rede/prod/ # muda por trimestre — dono: plataforma cluster/prod/ # muda por trimestre dados/prod/ # bancos, com prevent_destroy — dono: dados loja/prod/ # muda toda semana — dono: time do produtoUma boa fronteira minimiza as dependências entre states. Se dois grupos precisam trocar dez valores, provavelmente eles são um só.
3. Prepare o destino e faça backup
Seção intitulada “3. Prepare o destino e faça backup”mkdir -p infra/rede/prod && cd infra/rede/prod# backend novo, chave própriacat > backend.tf <<'EOF'terraform { backend "s3" { bucket = "empresa-tfstate-prod" key = "rede/prod/terraform.tfstate" region = "sa-east-1" encrypt = true use_lockfile = true }}EOFterraform init
# backup dos dois lados, semprecd ../../monolito/prod && terraform state pull > backup-origem-$(date +%F).tfstate4. Mova os recursos
Seção intitulada “4. Mova os recursos”Duas abordagens; a segunda é mais segura para volume grande.
Opção A — state mv entre states, direto:
cd infra/monolito/prodterraform state mv \ -state-out=../../rede/prod/terraform.tfstate \ aws_vpc.principal aws_vpc.principalOpção B — remover e importar, com controle explícito:
# 1. no destino: declare o recurso e importecd infra/rede/prodterraform import aws_vpc.principal vpc-0a1b2c3dterraform plan # precisa ficar limpo ANTES do próximo passo
# 2. só então, na origem: esqueça o recurso (sem destruir)cd ../../monolito/prodterraform state rm aws_vpc.principalA ordem da opção B é o ponto crítico: importe primeiro, remova depois. Invertido, você fica com um recurso órfão se a importação falhar.
Mova o grupo inteiro de uma vez (VPC, subnets, rotas, gateways) — deixar metade em cada lado gera dependências cruzadas difíceis de desfazer.
5. Compartilhe valores entre os states
Seção intitulada “5. Compartilhe valores entre os states”O state de aplicação precisa dos IDs que agora vivem no state de rede.
# origem: publique os valoresoutput "subnet_privada_ids" { value = aws_subnet.privada[*].id }output "vpc_id" { value = aws_vpc.principal.id }# consumidor: leia o state remotodata "terraform_remote_state" "rede" { backend = "s3" config = { bucket = "empresa-tfstate-prod" key = "rede/prod/terraform.tfstate" region = "sa-east-1" }}# uso: data.terraform_remote_state.rede.outputs.vpc_idAlternativa mais desacoplada, e melhor quando os times são diferentes: publicar os
identificadores em SSM Parameter Store (ou equivalente) e consultá-los por data source —
assim ninguém precisa de acesso de leitura ao state alheio.
6. Valide com plano vazio dos dois lados
Seção intitulada “6. Valide com plano vazio dos dois lados”Este é o critério de aceite. Os dois precisam ficar limpos.
cd infra/rede/prod && terraform plan -detailed-exitcode # espera-se 0cd ../../loja/prod && terraform plan -detailed-exitcode # espera-se 0Se algum lado propõe criar o que já existe, o recurso não chegou ao state certo — restaure o backup e refaça o movimento.
Só depois de tudo validado, remova do código de origem as declarações dos recursos movidos, e atualize o pipeline: cada state passa a ter o seu job, com sua credencial.
Se der errado
Seção intitulada “Se der errado”| Sintoma | Causa provável |
|---|---|
| Destino quer criar recurso existente | Falha no state mv / import não concluído |
| Origem quer destruir o que foi movido | O código de origem ainda declara o recurso |
Resource already managed |
Ficou nos dois states — remova de um |
| Dependência circular entre states | O corte foi feito no lugar errado; revise a fronteira |
| Lock preso no meio da operação | Ninguém mais deve estar aplicando; veja o guia de state quebrado |
Checklist de pronto
Seção intitulada “Checklist de pronto”- Corte definido por frequência de mudança e dono.
- Backend novo configurado, com locking e versionamento.
- Backup do state de origem e do destino.
- Grupos movidos inteiros, importando antes de remover.
- Valores compartilhados por output ou parameter store.
-
planlimpo nos dois lados. - Código de origem limpo e pipeline ajustado por state.