State: onde tudo dá errado
O state é o mapa entre o que está no seu código e o que existe no provedor. Sem ele, o
Terraform não sabe que aws_s3_bucket.relatorios corresponde àquele bucket específico — e
propõe criar tudo de novo. Praticamente todo desastre com Terraform é, na origem, um
problema de state.
O que o state guarda, inclusive segredos
Seção intitulada “O que o state guarda, inclusive segredos”Além do mapeamento, ele guarda os atributos lidos do provedor — em texto claro. Senha
inicial de banco, chave gerada, certificado: se passou pelo Terraform, está lá, mesmo que
o output esteja marcado como sensitive.
Consequências práticas: nunca versione o state no Git; use backend com criptografia em repouso e acesso restrito; e trate quem tem leitura do state como quem tem os segredos.
terraform show -json | jq '.values.root_module.resources[].values | keys' | headBackend remoto e locking
Seção intitulada “Backend remoto e locking”Backend remoto resolve dois problemas de uma vez: compartilhar o state entre pipeline e pessoas, e impedir dois apply simultâneos.
terraform { backend "s3" { bucket = "empresa-tfstate-prod" key = "loja/prod/terraform.tfstate" region = "sa-east-1" encrypt = true use_lockfile = true # locking nativo no S3 (versões recentes) # dynamodb_table = "tf-locks" # alternativa clássica de locking }}Ative versionamento no bucket do state e proteja contra exclusão. É a sua rede de segurança para tudo que vem abaixo: um state corrompido com versionamento é um inconveniente de dez minutos; sem versionamento, é uma reconstrução manual.
O lock é o que evita corrupção por concorrência. Quando o Terraform morre no meio, o lock
fica preso — e force-unlock só depois de confirmar que nenhum apply está rodando:
terraform force-unlock <ID-DO-LOCK> # confirme antes; destravar durante um apply corrompeWorkspaces e seus limites
Seção intitulada “Workspaces e seus limites”Workspaces criam vários states com a mesma configuração. Servem para ambientes efêmeros e testes paralelos.
Não use workspace para separar produção de desenvolvimento. Motivos concretos: um erro de
terraform workspace select aplica em produção; a configuração é idêntica, então
diferenças legítimas viram condicional espalhada pelo código; e as permissões não se
separam — quem aplica em dev tem o mesmo acesso ao state de prod.
Prefira diretórios separados, com backend, credencial e pipeline próprios por ambiente.
Dividir o state limita o raio de alcance
Seção intitulada “Dividir o state limita o raio de alcance”State único para tudo significa: plan lento, lock disputado por vários times e um erro capaz de destruir a infraestrutura inteira. Divida por fronteira de mudança e de dono:
infra/ rede/prod/ # muda raramente, dono: plataforma cluster/prod/ # muda por trimestre dados/prod/ # bancos, com proteção contra destruição loja/prod/ # muda toda semana, dono: time do produtoA ligação entre eles é feita por leitura, não por acoplamento de escrita:
data "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.subnet_privada_idsAlternativa mais desacoplada: publicar identificadores em um data source (tags, SSM Parameter Store) e consultá-los — assim um time não precisa de acesso de leitura ao state do outro.
state mv, rm e import
Seção intitulada “state mv, rm e import”Três operações que editam o mapa sem tocar na infraestrutura:
terraform state list # comece sempre por aquiterraform state mv aws_s3_bucket.antigo aws_s3_bucket.novo # renomear sem recriarterraform state rm aws_db_instance.legado # esquece o recurso; NÃO o destróiterraform import aws_s3_bucket.relatorios empresa-relatorios-prodstate rm é a ferramenta certa para passar um recurso para outro state (remove de um,
importa no outro). Ele não apaga nada no provedor — o recurso continua existindo,
agora sem gestão. Fazer rm e esquecer de importar é como se cria recurso órfão pagando
fatura por anos.
Faça backup antes de qualquer uma delas:
terraform state pull > backup-$(date +%F-%H%M).tfstateRecuperando de um state quebrado
Seção intitulada “Recuperando de um state quebrado”Na ordem, do mais barato para o mais caro:
- Restaure a versão anterior do bucket versionado. Resolve a maioria dos casos.
Janela do terminal aws s3api list-object-versions --bucket empresa-tfstate-prod --prefix loja/prod/aws s3api get-object --bucket empresa-tfstate-prod --key loja/prod/terraform.tfstate \--version-id <ID> restaurado.tfstateterraform state push restaurado.tfstate - Refresh para reconciliar com a realidade:
terraform apply -refresh-only, lendo cada mudança proposta antes de aceitar. - Reimporte os recursos perdidos, um a um, até o plano ficar vazio.
- Último recurso: editar o JSON à mão, com backup, incrementando o campo
seriale depoisterraform state push. Faça só com o lock adquirido e ninguém mais aplicando.
O objetivo em todos os caminhos é o mesmo: chegar a um terraform plan sem mudanças.
Enquanto o plano propuser criar o que já existe, o state ainda está errado.
Próximo passo: organize o código que compartilha esse state em Módulos que outros times usam. Para o passo a passo de recuperação, veja o guia State corrompido.