Terraform em equipe: organização do estado, raio de impacto e planos revisados
Como dividir o estado do Terraform, rodar planos no CI e aplicar só o que foi revisado, para que mudanças de infraestrutura virem rotina em vez de risco.
Os exemplos são genéricos e ilustrativos. Não vêm do ambiente de nenhum cliente: ajuste limites e configurações ao seu próprio sistema.
O arquivo de estado é a fronteira real
Todo terraform apply pode alterar qualquer coisa no estado em que opera. Isso faz do estado, e não do módulo, a unidade de risco. Com um único estado para um ambiente inteiro, um erro de digitação em um registro DNS e uma mudança no banco de produção passam pelo mesmo plano — e esse plano leva minutos para ser calculado.
Divida por ciclo de vida e raio de impacto
Agrupe recursos que mudam juntos e falham juntos. Uma organização comum separa, em cada ambiente:
- Fundação: contas, redes, zonas DNS — mudam raramente.
- Dados: bancos, buckets, filas — mudam com cuidado e ficam protegidos contra exclusão.
- Computação e serviços: clusters, funções, balanceadores — mudam com frequência.
Cada camada lê as saídas da camada de baixo e nunca gerencia os recursos dela. Os ambientes compartilham os mesmos módulos, mas têm estado e credenciais separados, para que um apply em staging não consiga tocar a produção.
Estado remoto, locking e versões
- Mantenha o estado em um backend remoto com locking e versionamento habilitados — nunca no Git e nunca em um notebook.
- Faça commit do lock file de dependências (.terraform.lock.hcl) e fixe as versões dos módulos, para que um plano hoje e um plano no mês que vem rodem o mesmo código.
- Proteja recursos com estado com prevent_destroy e com a proteção contra exclusão do próprio provedor.
Plano em todo pull request, apply do que foi revisado
Rode terraform plan no CI para toda mudança e publique o resultado no pull request. Depois da aprovação, aplique o plano salvo em vez de planejar de novo, para que a produção receba exatamente o que os revisores leram; se o estado mudou no meio do caminho, o Terraform rejeita o plano desatualizado. O pipeline deve se autenticar com credenciais de curta duração via federação OIDC, não com chaves de longa duração guardadas como segredos.
terraform init -input=false
terraform plan -input=false -lock-timeout=5m -out=tfplan
terraform show -no-color tfplan > plan.txt # attach to the pull request
# after approval, applying the same saved plan:
terraform apply -input=false tfplan
Detecte drift periodicamente
Mudanças pelo console ainda acontecem, normalmente durante incidentes. Um job agendado que roda terraform plan -detailed-exitcode as encontra: o código de saída 0 significa sem mudanças, 2 significa que a infraestrutura real difere do código e 1 significa erro. Transforme um 2 em ticket e então incorpore a mudança ao código ou desfaça-a.
Política antes do apply
Regras como “nenhum bucket público” ou “todo recurso tem uma tag de responsável” são melhor verificadas por uma máquina do que por um revisor no fim de um dia longo. Ferramentas de política como código, como o Open Policy Agent via Conftest, podem avaliar a forma JSON do plano (terraform show -json) no CI e bloquear o merge.