Terraform
Infrastructure as Code: por que existe
Seção intitulada “Infrastructure as Code: por que existe”Antes de IaC, provisionar era clicar em consoles ou rodar scripts imperativos — processo não reprodutível, sem histórico e sujeito a snowflake servers (cada ambiente ligeiramente diferente). IaC trata a infraestrutura como artefato de software:
- Versionamento: a infra vive no Git, com histórico,
blamee a possibilidade de reverter. - Revisão: mudanças passam por Pull Request e code review, exatamente como o código de aplicação.
- Reprodutibilidade: o mesmo
.tfrecria ambientes idênticos (dev, staging, prod) — adeus “funciona na minha conta”.
Este é o ponto-chave: os princípios de código limpo — legibilidade, DRY (via módulos), pequenas mudanças revisáveis — aplicam-se diretamente à infraestrutura quando ela é código.
Declarativo x imperativo
Seção intitulada “Declarativo x imperativo”| Aspecto | Imperativo (bash/SDK) | Declarativo (Terraform) |
|---|---|---|
| O que você escreve | O passo a passo (“crie, depois faça”) | O estado final desejado |
| Idempotência | Você garante manualmente | Nativa: reaplicar não recria o que já existe |
| Rodar duas vezes | Pode falhar/duplicar | Converge para o mesmo estado (no-op) |
| Detecção de drift | Não há | plan mostra o diff estado real vs. desejado |
Um script imperativo diz “execute aws ec2 run-instances”. Terraform diz “deve existir uma instância com estas propriedades” — e ele decide se cria, atualiza ou não faz nada. Essa é a base da idempotência.
Conceitos centrais
Seção intitulada “Conceitos centrais”Provider
Seção intitulada “Provider”Plugin que ensina o Terraform a falar com uma API (AWS, GCP, Azure, Cloudflare, Kubernetes…). Traduz recursos HCL em chamadas de API.
Resource
Seção intitulada “Resource”A unidade básica: um objeto de infra (um bucket, uma instância, uma zona DNS). Você declara seu tipo e atributos desejados.
State (o coração)
Seção intitulada “State (o coração)”Terraform mantém um arquivo de estado (terraform.tfstate) que mapeia os recursos do HCL para os objetos reais no provedor. É como ele sabe o que já existe e o que mudou.
Por que o state remoto importa:
- Fonte única da verdade em equipe. State local no laptop de um dev é um desastre: dois
applysimultâneos corrompem tudo. - State locking. Backends remotos (S3 + DynamoDB, Terraform Cloud) travam o state durante um
apply, evitando concorrência. - Segurança. O state pode conter segredos (senhas, chaves); remoto permite criptografia e controle de acesso, fora do Git.
- Colaboração e CI. Um pipeline de CI - GitHub Actions roda
plan/applycontra o mesmo state compartilhado.
plan / apply
Seção intitulada “plan / apply”terraform plan: mostra o diff entre o desejado (HCL) e o real (state/API). É o “dry-run” revisável — o equivalente a ler um PR antes de mergear.terraform apply: executa as mudanças para convergir ao estado desejado.
Módulos
Seção intitulada “Módulos”Empacotam um conjunto de recursos reutilizável e parametrizável (ex.: um módulo “vpc-padrão”). São o DRY da infraestrutura e a expressão de código limpo em IaC: abstração, entradas/saídas claras, reuso entre ambientes.
Exemplo concreto (HCL)
Seção intitulada “Exemplo concreto (HCL)”Um bucket S3 versionado, provisionado de forma declarativa:
# Backend remoto: state compartilhado, com locking via DynamoDBterraform { required_version = ">= 1.6"
required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } }
backend "s3" { bucket = "minha-org-terraform-state" key = "prod/app/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-locks" # state locking encrypt = true }}
# Provider: como falar com a AWSprovider "aws" { region = var.regiao}
# Variável de entrada — parametriza o módulo/ambientevariable "regiao" { type = string default = "us-east-1"}
# Resource: o estado DESEJADO de um bucket (declarativo)resource "aws_s3_bucket" "estaticos" { bucket = "minha-org-assets-estaticos"
tags = { Ambiente = "prod" Gerido = "terraform" # deixa claro que é IaC, não clique manual }}
# Versionamento do bucket como recurso separado (idempotente)resource "aws_s3_bucket_versioning" "estaticos" { bucket = aws_s3_bucket.estaticos.id versioning_configuration { status = "Enabled" }}
# Output: expõe um valor para outros módulos ou para o operadoroutput "bucket_arn" { value = aws_s3_bucket.estaticos.arn}Rodar terraform apply duas vezes: na primeira ele cria os recursos; na segunda, o plan mostra “No changes” — idempotência em ação.
Fluxo de trabalho (diagrama)
Seção intitulada “Fluxo de trabalho (diagrama)”flowchart TB
W[Escreve/edita .tf<br/>HCL declarativo] --> PR[Pull Request<br/>revisão + Git]
PR --> INIT["terraform init<br/>baixa providers + backend"]
INIT --> PLAN["terraform plan<br/>diff desejado x real"]
PLAN -->|revisado no PR| APPLY["terraform apply<br/>converge ao estado"]
APPLY --> STATE[(State remoto<br/>S3 + lock)]
STATE -.consultado por.-> PLAN
APPLY --> CLOUD[Infra provisionada<br/>AWS / etc.]
CLOUD -.drift detectado.-> PLAN
style STATE fill:#155e75,color:#fff
style PLAN fill:#166534,color:#fff
style APPLY fill:#854d0e,color:#fff
Anti-padrões e erros comuns
Seção intitulada “Anti-padrões e erros comuns”- State local em equipe. Sem backend remoto e locking, dois
applyconcorrentes corrompem o state. Sempre use backend remoto com lock. - Commitar
terraform.tfstateno Git. Contém segredos e vira fonte de conflito. State vai para backend remoto, não para o repositório. - ClickOps sobre recursos gerenciados. Alterar no console algo que o Terraform gerencia gera drift e o próximo
applyreverte (ou quebra). A infra gerenciada por IaC muda só por IaC. - Fazer
applysem ler oplan. Oplané a revisão da mudança; ignorá-lo é mergear sem revisar. Cuidado especial com mudanças que forçam replace (destroem e recriam). - Um único arquivo/estado monolítico. Todo o mundo em um
.tfgigante torna oplanlento e arriscado. Divida por domínio/ambiente e use módulos. - Hardcode de segredos no HCL. Chaves em texto plano no código versionado. Use variáveis, cofres (Secrets Manager, Vault) e evite segredos no state quando possível.
- Versões de provider não fixadas. Sem
~>/lockfile, uminitfuturo traz uma versão incompatível e quebra o build.
Relações
Seção intitulada “Relações”- Provisiona os serviços descritos em AWS - Visão Geral dos Serviços e materializa qualquer modelo de Tipos de Infraestrutura.
- Aplica princípios de código limpo à infraestrutura (DRY via módulos, revisão, versionamento).
- Integra-se a pipelines de CI - GitHub Actions para
plan/applyautomatizados. - Faz parte de DevOps & Infraestrutura e do quadro geral em Como Tudo se Conecta.
- Provisiona a base de Containers - Docker e Docker Compose e de Microservices em nuvem, temas de Sistemas Distribuídos.
Perguntas de revisão
Seção intitulada “Perguntas de revisão”- Por que o state remoto é essencial em um time, e o que o state locking previne?
Resposta
O state é a fonte da verdade que mapeia HCL para recursos reais. Remoto, ele é compartilhado e seguro (criptografado, fora do Git). O state locking (ex.: S3 + DynamoDB) impede dois apply concorrentes de corromperem o state, além de proteger segredos e permitir uso em CI.
- Qual a diferença entre declarativo e imperativo, e como isso se conecta à idempotência?
Resposta
Imperativo descreve os passos (“crie X, depois Y”); rodar de novo pode duplicar ou falhar. Declarativo (Terraform) descreve o estado final desejado; o Terraform calcula o diff e converge. Por isso é idempotente: reaplicar sobre um estado já correto resulta em “no changes”.
- Como o IaC traz práticas de código limpo para a infraestrutura?
Resposta
Tratando a infra como código versionado no Git: histórico e reversão, revisão em Pull Request, reprodutibilidade entre ambientes e DRY via módulos (abstrações reutilizáveis com entradas/saídas claras). Mudanças pequenas e revisáveis substituem cliques manuais irreproduzíveis.
- O que é drift e por que alterar recursos gerenciados direto no console é um anti-padrão?
Resposta
Drift é a divergência entre o estado real da infra e o descrito no HCL/state. Alterar no console (ClickOps) algo gerenciado pelo Terraform cria drift: o próximo plan/apply tenta reverter a mudança manual (ou quebra). A regra é que infra gerenciada por IaC só muda via IaC.