Infraestrutura como código: Terraform e Ansible sem virar bagunça

Terraform provisiona, Ansible configura. Como dividir os papéis, cuidar do estado, evitar desvio manual e manter o código de infraestrutura sustentável.

Equipe Solvefy 8 min de leitura

Infraestrutura como código promete duas coisas: ambientes reprodutíveis e mudanças revisáveis. Entregar isso é bem menos automático do que parece. O que vemos com frequência são repositórios de Terraform com três cópias quase idênticas do mesmo ambiente, arquivos de estado versionados junto do código, e playbooks de Ansible que ninguém roda mais porque "quebram tudo". O problema quase nunca é a ferramenta — é a falta de uma divisão clara de responsabilidade e de umas poucas disciplinas.

A divisão de papéis que evita 80% da confusão

Terraform e Ansible resolvem problemas diferentes, e usar um no lugar do outro é a origem mais comum de bagunça.

Terraform provisiona recursos. Ele é declarativo e guarda estado: sabe o que criou, compara com o que você descreveu e calcula a diferença. É a ferramenta certa para VM, rede, disco, registro de DNS, regra de firewall, banco gerenciado — coisas que têm ciclo de vida de criação e destruição.

Ansible configura sistemas. Ele não guarda estado: conecta na máquina e garante que ela esteja como descrito. É a ferramenta certa para pacote instalado, arquivo de configuração, serviço rodando, usuário criado, ajuste de kernel.

A fronteira prática: o Terraform entrega a máquina de pé com acesso; o Ansible faz dela o que ela precisa ser. Quem usa Terraform para instalar pacote via script de inicialização descobre que não tem como reaplicar sem recriar a VM. Quem usa Ansible para criar VMs descobre que não tem como saber o que existe nem destruir com segurança.

O estado do Terraform é o ativo mais delicado

O arquivo de estado é o que liga o seu código aos recursos reais. Ele merece três cuidados, e falhar em qualquer um deles gera incidente sério.

  1. Estado remoto, sempre. Estado no laptop significa que só uma pessoa consegue aplicar, e que um disco perdido leva embora o mapeamento. Guarde em armazenamento compartilhado — bucket S3-compatível, por exemplo — com versionamento ativado.
  2. Travamento. Sem trava, duas pessoas aplicando ao mesmo tempo corrompem o estado. Todo backend sério suporta trava; confirme que a sua está ativa.
  3. Nunca no Git. O estado contém valores sensíveis em texto claro, inclusive senhas geradas. Estado versionado é vazamento de credencial esperando ser descoberto. Se já está no histórico, considere as credenciais comprometidas e rotacione.

Um quarto cuidado, menos óbvio: estado separado por ambiente. Produção e desenvolvimento no mesmo estado significa que um comando mal digitado em desenvolvimento pode destruir produção. A separação física do estado é a barreira mais eficaz que existe.

Estrutura: comece simples e resista à abstração precoce

A tentação de criar módulos genéricos e parametrizáveis para tudo aparece cedo e custa caro. Módulo com trinta variáveis para atender a cinco casos hipotéticos é mais difícil de entender do que a duplicação que ele evita.

Uma estrutura que funciona bem na maioria dos casos:

  • Um diretório por ambiente, com o seu próprio estado e as suas variáveis.
  • Módulos apenas para o que se repete de verdade, três vezes ou mais. Antes disso, duplicar é mais honesto.
  • Módulos versionados, referenciados por tag e não por branch. Módulo referenciado por branch muda debaixo de você e transforma um apply de rotina em surpresa.
  • Nomes previsíveis, derivados de ambiente e função, para que o recurso no painel seja identificável sem consulta.

E um cuidado com ambientes: usar o mesmo código para produção e desenvolvimento é ótimo em teoria e vira problema quando os ambientes divergem por necessidade legítima — produção tem réplica, desenvolvimento não. Trate essas diferenças como parâmetros explícitos, não como condicionais espalhadas pelo código.

Desvio manual: a doença que mata IaC

O código descreve a infraestrutura. Alguém entra no painel às duas da manhã, muda uma regra de firewall para resolver um incidente e não conta a ninguém. Agora o código mente.

O próximo apply vai desfazer aquela correção — provavelmente reabrindo o incidente — ou vai falhar de forma confusa. E, mais grave: a equipe aprende que aplicar Terraform é arriscado, e passa a fazer tudo à mão. A infraestrutura como código morre nesse ponto, e o repositório vira documentação desatualizada.

O que sustenta a disciplina:

  • Regra explícita: mudança em produção acontece pelo código. Correção emergencial no painel é aceitável, com a obrigação de refletir no código no mesmo dia.
  • Detecção de desvio, rodando periodicamente para mostrar diferenças entre código e realidade. Achar o desvio em uma execução agendada é muito melhor que achá-lo durante um apply urgente.
  • Acesso de escrita restrito. Se todo mundo tem permissão de alterar direto, alguém vai alterar. Deixar o caminho do código ser o mais fácil ajuda mais que qualquer política escrita.

Ansible: idempotência é a única regra que importa

O valor do Ansible está em poder rodar o mesmo playbook dez vezes com o mesmo resultado. Perder isso é perder a ferramenta.

O que costuma destruir a idempotência:

  1. Comando de shell onde existe módulo. O módulo sabe verificar antes de agir; o comando executa sempre. Quando o shell é inevitável, defina uma condição de guarda que evite a reexecução.
  2. Ordem implícita. Playbook que só funciona se rodado depois de outro é armadilha. Cada playbook deve ser aplicável isoladamente.
  3. Estado acumulado. Tarefa que adiciona linha a arquivo sem verificar duplicidade produz um arquivo com a linha vinte vezes depois de vinte execuções.

Duas outras práticas fazem diferença. Use inventário dinâmico, gerado a partir da fonte real — o Proxmox ou o provedor de nuvem — em vez de manter lista manual que envelhece. E organize em papéis por função, não por servidor: um papel de "servidor web" aplicável a qualquer host vale mais que um playbook por máquina.

Como as duas ferramentas se conectam

ResponsabilidadeFerramentaObservação
Criar VM, rede, disco, DNSTerraformGuarda estado, sabe destruir
Acesso inicial à máquinaTerraform via cloud-initChave SSH e usuário, nada além
Pacotes e configuração do sistemaAnsibleIdempotente, reaplicável
Implantar aplicaçãoPipeline de CI/CDNem Terraform nem Ansible
Inventário de hostsDinâmico, a partir da realidadeNunca lista manual
SegredosCofre externoNunca no repositório

O encadeamento limpo é: Terraform cria a VM e injeta a chave via cloud-init; o inventário dinâmico do Ansible descobre a máquina; o Ansible a configura. Cada etapa é reexecutável sozinha.

Revisão e aplicação controladas

Infraestrutura como código só entrega o benefício de "mudança revisável" se a mudança for de fato revisada. O fluxo mínimo:

  • O plano roda automaticamente no pedido de alteração, e o resultado fica visível para quem revisa. Ler o plano é o momento em que se percebe que uma alteração aparentemente simples vai recriar o banco de dados.
  • A aplicação em produção é controlada, com aprovação humana. Aplicar automaticamente ao aprovar um merge é confortável e concentra risco.
  • Atenção a tudo que aparece como recriação. Recurso que será destruído e criado de novo é a origem quase universal dos acidentes com Terraform. Recriação de VM de produção precisa ser decisão consciente, não descoberta.
  • Credenciais do pipeline sem senha de longa duração, usando identidade federada quando o provedor suportar.

O caminho de adoção em ambiente que já existe

Ninguém começa no vazio. Para trazer um parque existente para IaC sem parar a operação:

  1. Comece pelo que é novo. Todo recurso criado de hoje em diante nasce por código. Isso já interrompe o crescimento do problema.
  2. Importe por domínio, não tudo de uma vez. Escolha uma área com fronteira clara — DNS é um bom primeiro passo, de baixo risco e alto valor.
  3. Descreva antes de importar, e confirme que o plano não indica mudança. Plano limpo é a prova de que o código descreve a realidade.
  4. Deixe o mais crítico para depois, quando a equipe já tiver confiança na ferramenta e no fluxo.
  5. Aceite conviver com os dois modelos por um período. Migração de tudo de uma vez é o cenário em que se abandona a iniciativa no meio.

Erros comuns

  • Usar Terraform para configurar sistema operacional, sem poder reaplicar.
  • Arquivo de estado versionado no Git, com credenciais em texto claro.
  • Estado único compartilhado entre produção e desenvolvimento.
  • Módulos genéricos demais antes de haver repetição real.
  • Módulo referenciado por branch em vez de tag.
  • Correção manual no painel que nunca volta para o código.
  • Comando de shell no Ansible onde existe módulo idempotente.
  • Inventário estático mantido à mão.
  • Aplicar em produção automaticamente, sem ler o plano.
  • Ignorar avisos de recriação de recurso.

Onde a Solvefy/Cloud entra

Em consultoria DevOps, essa é uma das frentes mais pedidas — e boa parte do trabalho é organizar o que já existe, não começar de zero. Definimos a fronteira entre provisionamento e configuração, estruturamos o estado remoto com travamento e separação por ambiente, montamos o fluxo de revisão e aplicação no pipeline e trazemos o parque existente para o código por domínios, começando pelo de menor risco. Também treinamos a equipe, porque IaC que só uma pessoa entende é um ponto único de falha com outro nome.

Quer organizar a sua infraestrutura como código? Fazemos um diagnóstico gratuito, sem compromisso, em solvefy.cloud.

Solvefy/Cloud — Infraestrutura que cresce com você.

Faça agora o seu diagnóstico e orçamento

Inicie com um diagnóstico gratuito da sua infraestrutura e receba uma proposta personalizada — com escopo, cronograma e valores.