Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

01 - Terraform (Multi-cloud)

#hcl#opentofu#providers#state#terraform
video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

Terraform (Multi-cloud)

Terraform é a ferramenta de IaC declarativa mais adotada do mercado, responsável por descrever infraestrutura em HCL (HashiCorp Configuration Language) e convergir recursos em praticamente qualquer nuvem ou serviço que exponha uma API. Seu modelo é baseado em providers, plugins que traduzem recursos declarados em chamadas de API, e em um arquivo de state que mapeia recursos do código para recursos reais. A adoção dominante vem da combinação de sintaxe única, cobertura gigantesca de providers no registro público e ecossistema de módulos maduro, o que permite à mesma equipe gerenciar AWS, GCP, Azure, Kubernetes, DNS e SaaS em um único fluxo de trabalho. Em produção, Terraform é a espinha dorsal típica do provisioning: redes, clusters, bancos e políticas nascem dele, e pipelines de CI o executam com plan revisado e state remoto. O contexto recente de licenciamento, BSL desde 2023 e a aquisição da HashiCorp pela IBM concluída em fevereiro de 2025, reforçou a relevância do OpenTofu, fork mantido pela Linux Foundation que preserva a sintaxe HCL e a compatibilidade de código.

Conceito: infraestrutura descrita em HCL

HCL é uma linguagem de configuração legível, com blocos, argumentos, referências e expressões, desenhada para descrever recursos e relações entre eles. Um arquivo Terraform não é um script: é uma declaração do estado desejado, em que resource define um recurso real, variable define a entrada parametrizável, output expõe um resultado e locals calcula valores derivados. A referência direta entre recursos, aws_subnet.privada.id, é o que constrói o grafo de dependências que ordena a execução.

O modelo mental correto é o de um compilador de infraestrutura. O código fonte é a descrição desejada; o state é a tabela de símbolos que liga nomes do código a recursos reais; o provider é o backend que sabe falar com a API alvo; e o plan é a saída do compilador, o delta executável entre desejado e real. Quem domina esse quadro diagnostica a maioria dos problemas de Terraform sem ferramenta externa.

A expressividade da HCL cobre o essencial sem virar linguagem de programação: expressões condicionais, laços com for_each e count, funções utilitárias e blocos dinâmicos para atributos repetidos. Essa fronteira deliberada, mais que YAML, menos que TypeScript, é parte do desenho e do debate que o arquivo de Pulumi aprofunda.

O problema que resolve

Terraform resolve três problemas ao mesmo tempo. O primeiro é o provisioning manual: sem a ferramenta, criar uma stack de produção em AWS envolve dezenas de recursos interdependentes no console, cada um uma chance de erro e nenhuma chance de reprodução fiel. Com a ferramenta, a mesma stack é código revisável, aplicável em qualquer ambiente e recriável em minutos.

O segundo problema é a fragmentação por nuvem. Ferramentas nativas, CloudFormation para AWS e ARM para Azure, entregam profundidade, mas forçam o time a aprender um dialeto por provedor e impedem fluidez em operações híbridas. Terraform oferece sintaxe e fluxo de trabalho únicos sobre dezenas de providers, mantendo os detalhes específicos de cada nuvem nos argumentos dos recursos, onde pertencem.

O terceiro problema é o ciclo de vida do recurso. Provisionar é a parte fácil; atualizar sem quebrar, destruir na ordem certa e substituir recursos que não aceitam edição in-place são as partes que não existem em scripts manuais. O plano explícito e o grafo de dependências transformam essas operações de alto risco em eventos revisáveis antes de acontecer.

Providers: a abstração sobre as APIs

O provider é um plugin distribuído pelo registro público (registry.terraform.io) que implementa a tradução entre recursos declarados e chamadas de API. Cada provider tem seu próprio schema: o recurso aws_s3_bucket só existe no provider AWS, e o google_pubsub_topic só no provider Google. A unidade de reuso é o fluxo de trabalho, não a abstração de recursos, e tentar construir uma camada genérica "multicloud" sobre schemas distintos é o erro clássico de desenho.

Providers são versionados, e fixar versão é obrigação de produção: uma versão nova de provider pode alterar comportamento de recursos, introduzir validações e mudar o plano. O bloco required_providers com restrição de versão, combinado ao lock file gerado pelo init, garante que todos os membros do time e a pipeline calculem o mesmo plano.

Um mesmo provider pode ser instanciado múltiplas vezes com o argumento alias, cenário comum para criar recursos em duas regiões ou duas contas no mesmo código. Credenciais nunca entram no código: entram por variável de ambiente, arquivo de credenciais do provedor ou role assumida, e o código apenas declara a região e a configuração estrutural.

O protocolo de plugins entre core e provider é o detalhe que permite ao ecossistema escalar: qualquer pessoa pode escrever um provider para qualquer serviço com API, e é assim que existem providers de SaaS, monitoramento, DNS e sistemas internos. O lado operacional dessa flexibilidade é o gerenciamento de versões em escala: um projeto grande pode pinçar dezenas de providers, e o upgrade precisa ser planejado e executado por partes, com plano revisado a cada passo.

# Requisitos do projeto: versão da ferramenta e providers fixados
terraform {
  required_version = "~> 1.9"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.60"          # fixar versão evita planos mutantes
    }
  }

  backend "s3" {                   # state remoto obrigatório em produção
    bucket         = "infra-state-producao"
    key            = "rede/terraform.tfstate"
    region         = "sa-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

provider "aws" {
  region = "sa-east-1"
}

# Recurso declarado: bucket com versionamento habilitado
resource "aws_s3_bucket" "app" {
  bucket = "meu-app-arquivos-prod"
  tags = { ManagedBy = "terraform" }
}

resource "aws_s3_bucket_versioning" "app" {
  bucket = aws_s3_bucket.app.id
  versioning_configuration { status = "Enabled" }
}

O state e o ciclo plan e apply

O state é o mapeamento entre nomes do código e identificadores reais dos recursos, e é também o cache que permite ao plan calcular deltas sem interrogar cada recurso do zero. Sem state, a ferramenta não sabe o que já criou; com state local, dois engenheiros aplicam sobre realidades diferentes e corrompem o inventário. Em produção, state remoto com lock é pré-requisito, tema detalhado no arquivo de remote state deste módulo.

O ciclo de trabalho segue o mesmo ritual em qualquer escala: init para baixar providers e inicializar o backend, plan para calcular e revisar o delta, apply para executar o plano aprovado. O plano pode ser gravado em arquivo e aplicado literalmente depois, o que fecha a janela de divergência entre o que o revisor viu e o que a pipeline executou. Destruições completas usam destroy com o mesmo plano explícito, e nunca com apagar-à-mão.

# Ciclo operacional canônico
terraform init                # baixa providers e inicializa o backend
terraform plan -out=tfplan    # gera o plano com diff para revisão
terraform apply tfplan        # aplica exatamente o plano revisado
terraform destroy             # destrói os recursos rastreados no state

Módulos e registro

Módulos são a unidade de reuso de Terraform: pacotes de código que encapsulam um desenho, por exemplo, uma VPC com sub-redes públicas e privadas por AZ, e o expõem como contrato de variáveis e outputs. O diretório de trabalho é o módulo raiz, e todo o resto vem de módulos filhos locais, do registro público ou de repositórios privados, sempre com versão fixada em produção.

O registro público consolidou o hábito de consumir desenho pronto, e o módulo da comunidade para VPC é o exemplo canônico: centenas de argumentos opcionais em torno de um desenho testado em escala. O lado perigoso é o acoplamento cego: consumir módulo complexo sem ler a implementação é transferir decisões de rede e de segurança para um bloco de código que ninguém do time entende de verdade.

Times grandes desenvolvem bibliotecas internas de módulos, publicadas em repositório privado ou registry próprio, com versionamento semântico, changelog e pipeline de teste por módulo. O critério de maturidade é simples: quando três raízes de código precisam do mesmo desenho, o desenho vira módulo; antes disso, duplicação consciente é aceitável e evita abstração prematura.

# Consumo de módulo versionado do registro
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.8.1"              # versão fixa, mudanças explícitas

  name = "producao"
  cidr = "10.0.0.0/16"
  azs  = ["sa-east-1a", "sa-east-1b"]
}

Multicloud: onde brilha e onde engana

O cenário de brilho do Terraform em multicloud é a orquestração entre provedores: um mesmo código cria o cluster no EKS, o DNS no Route 53, o certificado no ACM, o monitoramento no Datadog e o repositório de imagens no ECR, com dependências explícitas entre eles. Esse é o fluxo que nenhuma ferramenta nativa cobre, e é nele que a sintaxe única se paga de forma inequívoca.

O cenário onde engana é a promessa de abstração: trocar de nuvem não é trocar o source do provider. Schemas são incompatíveis por desenho, uma VPC não é um VNet, e um grupo de segurança não é um firewall rule do GCP, e uma migração real reescreve os recursos, não só a régua de sintaxe. O valor multicloud honesto é a fluência operacional do time e o portfólio de ferramentas, não a portabilidade gratuita do código.

Complementarmente, Terraform não cobre a operação contínua dentro das máquinas: ele cria a instância, não gerencia patches, usuários e configuração de runtime. Essa é a fronteira com gerenciamento de configuração, Ansible, Chef e Puppet, e com o modelo imutável de imagens; operações maduras combinam as duas camadas com fronteiras explícitas.

Licenciamento e o ecossistema: BSL, IBM e OpenTofu

Terraform foi distribuído por anos sob licença MPL 2.0, e em 2023 a HashiCorp mudou o licenciamento para BSL 1.1 (Business Source License), uma licença de código disponível que não é open source nos critérios OSI: o código é visível e utilizável na maior parte dos casos, mas o uso em produção que concorra com produtos da HashiCorp é restringido, e cada versão tem cláusula de conversão futura para open source. A mudança, anunciada em 2023, gerou o fork OpenTofu sob a Linux Foundation, com promessa de licença permissiva permanente.

A aquisição da HashiCorp pela IBM, concluída em fevereiro de 2025, devolveu o tema ao debate: o futuro do produto ficou sob a governança de um gigante corporativo, e a percepção de risco de vendor lock-in e de continuidade do modelo de licenciamento cresceu em parte da comunidade. O OpenTofu, por sua vez, consolidou-se no período: manteve compatibilidade de código com a sintaxe e o comportamento da versão em que forcou, e passou a evoluir com recursos próprios, como criptografia nativa de state, sob governança de fundação neutra.

Para a operação, o cenário prático é de dualidade estável. As duas ferramentas compartilham a mesma sintaxe HCL, o mesmo modelo de providers e, em grande medida, o mesmo protocolo de plugins, e repositórios que evitem recursos proprietários exclusivos do Terraform Cloud transitam entre as duas com atrito baixo. Times em migração para OpenTofu usam ferramentas de troca de binário nas pipelines, e times que permanecem em Terraform monitoram os termos da BSL contra seu caso de uso, em especial se operam plataformas que revendem infraestrutura como serviço.

A decisão racional separa três perguntas. O caso de uso cai nas restrições da BSL, em geral não cai. A dependência de recursos proprietários do Terraform Cloud é real. E o valor de governança neutra, fundação sem interesse comercial direto, justifica a troca de CLI. Para a maior parte das operações, o código continua idêntico, e a decisão se concentra na CLI executada e na governança aceita.

Comparação entre as principais ferramentas

Ferramenta Linguagem Alcance State Licença atual
Terraform HCL Multicloud via providers Remoto obrigatório em produção BSL 1.1
OpenTofu HCL Multicloud, compatível com Terraform Remoto, com criptografia nativa MPL 2.0
CloudFormation YAML ou JSON AWS nativo Gerenciado pelo serviço AWS Proprietária, serviço AWS
Pulumi TypeScript, Python, Go, C# Multicloud via providers Remoto, serviço ou self-hosted Apache 2.0
Ansible YAML (playbooks) Configuração e orquestração Stateful opcional (inventário) GPL 3.0

A leitura de decisão: Terraform e OpenTofu dividem o mesmo nicho, e a escolha entre eles é de governança e licenciamento, não de técnica; CloudFormation ganha quando a operação é pura AWS e quer integração nativa profunda; Pulumi ganha quando a infraestrutura exige lógica de programação real; Ansible complementa todas as anteriores na camada de configuração interna.

Erros comuns e boas práticas

  • Não fixar versão de provider e de ferramenta; planos que mudam sozinhos entre execuções são incidentes silenciosos em produção.
  • Usar state local em equipe; state remoto com lock, criptografia e backup é o primeiro requisito de produção, antes de qualquer módulo.
  • Tratar Terraform como camada de abstração multicloud e prometer portabilidade que o desenho não entrega; a sintaxe é única, os schemas não são.
  • Ignorar o plano e aplicar em produção com -auto-approve sem gate de revisão; auto-approve existe para pipeline controlada, não para atalho humano.
  • Misturar provisioning e configuração no mesmo código, com provisioners longos e scripts embutidos; provisionamento cria o recurso, configuração e imagem cuidam do conteúdo.
  • Aplicar a partir da máquina local sem lock e sem trilha de auditoria; toda execução em produção deve sair de pipeline identificável.
  • Consumir módulos complexos do registro sem ler a implementação; desenho de rede e de segurança não deve ser caixa preta.
  • Não ter plano de continuidade frente ao licenciamento; manter o código dentro da sintaxe compatível e testar a CLI alternativa custa pouco e reduz risco.