Terraform e infraestrutura como código: um início seguro
Terraform só melhora a operação quando configuração, estado, plano e aplicação possuem controle, revisão e responsabilidades claras.
O primeiro terraform apply costuma ser fácil demais É possível começar com poucos arquivos: Depois: Se o provider estiver configurado corretamente, a infraestrutura pode ser criada em minutos. O problema aparece no segundo dia: outra pessoa altera o mesmo ambiente; o arquivo de estado fica em um notebook; uma credencial aparece no histórico do terminal; uma atualização de provider muda o plano; ninguém sabe qual plano foi aprovado; uma execução manual destrói um recurso importante; o código e a infraestrutura deixam de corresponder. Terraform não torna uma infraestrutura segura apenas por descrevê la em HCL. Ele introduz um sistema de controle que depende de quatro elementos diferentes: Se um deles for tratado como detalhe local, a reprodutibilidade desaparece. O que o Terraform realmente controla A linguagem do Terraform é declarativa. A configuração descreve recursos e relações desejadas; o Terraform consulta providers, compara configuração e estado e calcula ações para aproximar a infraestrutura do resultado declarado. Isso não significa que o código seja a única fonte de verdade. O Terraform precisa do estado para relacionar objetos da configuração aos objetos reais. Também consulta APIs externas, que podem ter sido alteradas por: console administrativo; outro pipeline; outro projeto Terraform; automação externa; operador humano; política do provedor. O modelo mental mais preciso é: O plano é uma proposta de mudança. Não é garantia de que a infraestrutura permanecerá igual até a aplicação. Laboratório: uma configuração sem infraestrutura externa Para aprender o fluxo sem criar recursos em nuvem, use o recurso interno terraform data . Crie uma pasta vazia: Adicione versions.tf : Adicione variables.tf : Adicione main.tf : Adicione outputs.tf : Crie dev.tfvars : Inicialize e valide: Até aqui, nenhum recurso externo foi criado. O laboratório permite observar configuração, estado e plano. Salve o plano que foi revisado Executar: em momentos diferentes permite que o segundo comando produza um novo plano interativo. Esse novo plano pode não ser exatamente o que alguém revisou. Para ligar revisão e aplicação: Inspecione em formato legível: Aplique o plano salvo: O comando terraform plan diferencia o modo especulativo, usado para avaliar mudanças, do plano salvo, que pode ser aplicado posteriormente. Há um cuidado decisivo: arquivos de plano podem conter valores sensíveis. Não os envie indiscriminadamente para logs públicos nem os retenha sem controle. Em CI/CD, um fluxo comum é: Para ambientes críticos, o plano aplicado deve ser produzido a partir do commit aprovado e dentro da mesma fronteira de confiança da aplicação. O estado não é um cache descartável Por padrão, o Terraform cria terraform.tfstate localmente. Esse arquivo relaciona a configuração à infraestrutura administrada. Perder ou substituir o estado não apaga os recursos reais, mas pode impedir que o Terraform reconheça corretamente o que administra. Não faça isto: O estado pode conter: IDs; endereços; topologia; nomes; atributos retornados pelo provider; senhas iniciais; tokens; strings de conexão; dados marcados como sensíveis. A documentação de dados sensíveis esclarece que marcar uma variável como sensitive oculta a exibição normal, mas não impede que o valor seja armazenado em estado e plano. No .gitignore : Nem todo arquivo .tfvars contém segredo. A exclusão é uma política conservadora; arquivos não sensíveis podem ser versionados conscientemente. Estado remoto é uma necessidade de equipe A documentação de remote state recomenda armazenamento remoto para compartilhar o estado e evitar coordenação manual. Um backend adequado deve ser avaliado por: locking; criptografia em trânsito; criptografia em repouso; controle de acesso; versionamento; auditoria; retenção; recuperação; disponibilidade. O locking impede que duas aplicações concorrentes modifiquem o mesmo estado quando o backend oferece suporte. Ele não protege contra: dois estados diferentes administrando o mesmo recurso; alteração manual no console; credencial privilegiada; plano mal revisado; remoção deliberada; erro lógico no código. Organize estados por limite operacional. Exemplo: Não coloque toda a organização em um único estado apenas para compartilhar outputs. Um estado muito amplo aumenta: alcance de credenciais; tempo de plano; risco de concorrência; impacto de erro; número de pessoas com acesso. Também não fragmente cada recurso em um estado separado. A fronteira deve acompanhar propriedade, ciclo de mudança e dependências. Não use workspaces como substituto automático de isolamento Workspaces permitem múltiplas instâncias de estado para uma mesma configuração. Eles podem ser úteis em ambientes temporários e cenários homogêneos. Para produção com: credenciais próprias; controles distintos; backends diferentes; aprovações; redes separadas; políticas específicas; diretórios, pipelines ou configurações de raiz independentes costumam deixar a fronteira mais explícita. A escolha não é puramente sintática. Pergunte: Um erro de seleção de workspace poderia aplicar uma alteração no ambiente errado? Se a resposta for sim, reforce a separação. O arquivo de lock deve entrar no Git O terraform init gera: A documentação do dependency lock file orienta versionar esse arquivo para que mudanças de providers possam ser revisadas. Faça: Não faça atualizações de provider implicitamente em cada pipeline. Para atualizar conscientemente: Revise: versão selecionada; changelog; mudanças de schema; recursos recriados; deprecações; comportamento do provider. O arquivo de lock controla providers. Módulos remotos seguem suas próprias restrições de versão; use versões explícitas. Exemplo: Não use uma branch mutável como fonte de módulo de produção sem uma política específica. Providers precisam de limites de versão Exemplo: Uma restrição excessivamente aberta pode trazer incompatibilidades inesperadas. Uma restrição exata em todos os lugares pode tornar atualizações difíceis. Combine: faixa compatível na configuração; versão escolhida no lock; processo periódico de atualização; plano e testes. Segredos: ocultar não é eliminar Exemplo: Isso reduz exposição no output normal, mas o token ainda pode entrar no estado. Nas versões atuais documentadas pela HashiCorp, valores ephemeral e argumentos write only podem impedir armazenamento em estado e plano em contextos suportados. Exemplo de credencial temporária para provider: O suporte depende da versão do Terraform e do provider. Prefira: identidade de workload; OIDC; tokens curtos; variáveis protegidas; cofre de segredos; credenciais por ambiente; privilégios mínimos. Evite: chave permanente no .tf ; segredo em .tfvars versionado; token em parâmetro de linha de comando visível; plano publicado como artefato público; output de conexão sensível. O guia sobre segredos no CI/CD detalha essas fronteiras. Importe antes de assumir infraestrutura existente Se um recurso já existe, adicionar apenas um bloco resource não faz o Terraform reconhecê lo automaticamente. Fluxo: 1. inventarie o objeto; 2. escreva a configuração; 3. use o mecanismo de importação apropriado; 4. gere o plano; 5. ajuste diferenças; 6. valide que não haverá substituição indevida. Nunca execute um plano destrutivo apenas para “fazer o código combinar” com o ambiente. Infraestrutura como código não exige recriar tudo. Exige trazer o estado existente para um processo administrável. Módulos não devem esconder decisões críticas Um módulo útil possui: responsabilidade clara; entradas limitadas; outputs necessários; documentação; versão; testes; política de compatibilidade. Módulo problemático: O mapa genérico esconde contratos e permite combinações não previstas. Prefira entradas explícitas: Não crie um módulo depois de usar um bloco uma única vez apenas para “organizar”. Abstraia quando houver repetição real ou uma fronteira de responsabilidade. A arquitetura sem complexidade desnecessária vale também para IaC. Testes não substituem o plano O comando terraform test permite testar configurações e módulos. Um arquivo de teste pode verificar outputs e condições: Execute: Alguns testes podem criar infraestrutura real conforme a configuração e o modo usado. Leia o plano de teste, use credenciais restritas e ambientes descartáveis. Pipeline mínimo: O plano continua necessário porque testes não conhecem todas as mudanças da infraestrutura real. Drift precisa ser detectado, não apenas discutido Drift ocorre quando a infraestrutura real difere do estado ou da configuração esperada. Fontes: mudança manual; automação externa; política do provedor; recurso removido; alteração emergencial; outro state. Execute planos periódicos somente leitura, com credenciais adequadas, para detectar diferenças. Uma alteração emergencial pode ser necessária. Depois dela: 1. registre o motivo; 2. atualize o código; 3. importe ou ajuste o estado; 4. revise o plano; 5. remova a exceção. Proibir mudanças manuais sem oferecer resposta de incidente apenas cria mudanças manuais escondidas. Pipeline recomendado por ambiente Produção deve usar identidade própria e controles descritos na separação de ambientes. Checklist de um início seguro Repositório [ ] Arquivos .tf versionados. [ ] .terraform.lock.hcl versionado. [ ] Estado e planos ignorados. [ ] Formatação e validação automatizadas. [ ] Owners para módulos e pipelines sensíveis. Estado [ ] Backend remoto. [ ] Locking quando suportado. [ ] Criptografia. [ ] Controle de acesso. [ ] Logs de auditoria. [ ] Versionamento ou recuperação. [ ] Estados separados por fronteira operacional. Credenciais [ ] Nenhum segredo no código. [ ] Identidades por ambiente. [ ] Escopo mínimo. [ ] Expiração curta quando possível. [ ] Estado tratado como dado sensível. Fluxo [ ] Plano revisável. [ ] Aplicação ligada ao commit aprovado. [ ] Mudanças destrutivas destacadas. [ ] Importação de recursos existentes. [ ] Drift acompanhado. [ ] Recuperação planejada. Manutenção [ ] Terraform e providers atualizados conscientemente. [ ] Módulos versionados. [ ] Testes de módulos. [ ] Documentação de owners. [ ] Exceções registradas. Infraestrutura como código não significa que toda infraestrutura deve ser criada automaticamente desde o primeiro dia. O início seguro é menor: nenhuma mudança relevante deve depender de memória individual, estado perdido ou credencial sem controle. Quando configuração, estado, plano e identidade fazem parte do mesmo fluxo revisável, Terraform deixa de ser apenas um comando de provisionamento e passa a ser um mecanismo de governança operacional.