Apostila completa de Infraestrutura como Código & Platform Engineering
IaC transforma servidores, redes e bancos em código versionado, revisável e reproduzível — fim dos "snowflake servers" e do "funcionava antes de alguém mexer no console". Platform Engineering é o passo seguinte: empacotar essa capacidade num produto interno que os times de desenvolvimento consomem via self-service, por um golden path. Esta apostila vai de Terraform/OpenTofu ao Internal Developer Platform, com o olho no que empresas pedem em vagas de plataforma, cloud e DevOps.
Por que IaC e como ela leva à plataforma
Objetivo: entender os problemas que a infraestrutura manual cria, os princípios de IaC (declarativo, imutável), e por que "Platform Engineering" é a evolução natural.
1.1 O problema: infraestrutura feita à mão
| Sintoma | Causa |
|---|---|
| "Snowflake server" | Servidor configurado à mão ao longo de anos; ninguém sabe recriá-lo |
| Configuration drift | Ambientes que deveriam ser iguais (staging vs prod) divergiram por mudanças manuais não registradas |
| "Funcionava antes de alguém mexer no console" | Sem trilha de auditoria; mudança não revisada quebrou produção |
| Provisionamento lento | Abrir chamado, esperar dias, alguém clicar em telas |
| Recuperação de desastre impossível | Não há "receita" para reconstruir a infra em outra região |
| Conhecimento na cabeça de uma pessoa | Bus factor 1 |
1.2 O que IaC resolve
Infraestrutura como Código é gerir e provisionar infraestrutura através de arquivos de definição versionados, em vez de configuração manual. Benefícios diretos:
- Versionamento e revisão: toda mudança de infra é um commit / PR, com histórico, blame, e revisão por pares.
- Reprodutibilidade: o mesmo código gera o mesmo ambiente — dev, staging, prod, DR, um novo cliente.
- Automação: CI/CD aplica a infra; humanos aprovam, não digitam.
- Documentação viva: o código é a descrição exata do que existe.
- Rollback: reverter para um commit anterior (com cuidado — Módulo 3).
- Detecção de drift: comparar o mundo real com o código e alarmar diferenças.
1.3 Declarativo × imperativo, imutável × mutável
| Eixo | Opção A | Opção B |
|---|---|---|
| Modelo | Declarativo: você descreve o estado desejado ("quero 3 VMs t3.medium nesta VPC"); a ferramenta calcula o diff e o aplica. (Terraform, CloudFormation, K8s) | Imperativo: você descreve os passos ("crie uma VM, depois instale nginx, depois..."). (scripts, Ansible playbooks em parte) |
| Mudança de servidor | Imutável: nunca altere um servidor rodando; construa uma imagem nova e substitua a instância. (Packer + auto scaling, contêineres) | Mutável: aplique patches e mudanças no servidor existente (config management contínuo). Tende ao drift |
Declarativo + imutável: descrever o estado desejado (Terraform/OpenTofu para a infra, Kubernetes para o runtime), e substituir em vez de mutar (imagens/contêineres reconstruídos, não patched). É previsível, reversível e elimina o drift na raiz. Config management mutável (Ansible) ainda tem lugar — bootstrap, VMs legadas, tarefas de OS — mas não como o modelo central.
1.4 De IaC a Platform Engineering
IaC dá às equipes de plataforma o poder de codificar infra. Mas se cada time de produto precisa escrever seu próprio Terraform, entender VPCs, IAM, Kubernetes e observabilidade, a carga cognitiva explode e a velocidade cai. Platform Engineering resolve isso empacotando as capacidades de infra num produto interno (o Internal Developer Platform) que o desenvolvedor consome por self-service, por um caminho pré-pavimentado (golden path), sem precisar ser especialista em nuvem. IaC é o motor; a plataforma é o carro que o dev dirige. Módulos 7–9.
"Platform Engineer", "Cloud/Infrastructure Engineer", "DevOps Engineer" com forte IaC são vagas abundantes e bem pagas. Perguntas de abertura: "O que é IaC e quais problemas resolve?" (snowflake, drift, reprodutibilidade, auditoria), "Declarativo vs imperativo", "Infra imutável vs mutável", "O que é Platform Engineering e como se relaciona com DevOps?".
✏️ Exercício 1 — Diagnóstico
Uma empresa provisiona tudo pelo console da nuvem. Staging e produção "deveriam ser iguais" mas um bug só aparece em prod. Ninguém consegue recriar o ambiente numa segunda região para DR. Liste três mudanças de IaC e o que cada uma resolve.
Gabarito: (1) Codificar toda a infra em Terraform/OpenTofu com um módulo de ambiente parametrizado, aplicado igual a staging e prod → elimina o drift que causa "só em prod". (2) Colocar a infra num repositório com PR obrigatório e CI (plan em PR) → trilha de auditoria e revisão; ninguém mais muda pelo console. (3) O mesmo código, com variáveis de região, gera o ambiente numa segunda região → DR reprodutível. Bônus: detecção de drift agendada para pegar qualquer mudança manual de emergência.
Terraform / OpenTofu: fundamentos
Objetivo: os conceitos centrais — providers, resources, o ciclo plan/apply, HCL, variáveis e outputs, data sources — e a bifurcação Terraform / OpenTofu.
2.1 O modelo
# providers.tf — de qual API vamos falar terraform { required_providers { aws = { source = "hashicorp/aws", version = "~> 5.0" } } } provider "aws" { region = var.region } # main.tf — o estado DESEJADO, declarativo resource "aws_instance" "web" { ami = data.aws_ami.ubuntu.id instance_type = var.instance_type subnet_id = aws_subnet.public.id tags = { Name = "web-${var.env}", Team = "payments" } } # variables.tf / outputs.tf variable "env" { type = string } output "web_ip" { value = aws_instance.web.public_ip }
- Provider: o plugin que fala com uma API (AWS, GCP, Azure, Cloudflare, GitHub, Datadog, Kubernetes… centenas).
- Resource: um objeto de infra que o Terraform cria/atualiza/destrói.
- Data source: lê algo que já existe (uma AMI, uma VPC criada por outro time) sem gerenciá-lo.
- Variables / outputs: entradas e saídas do módulo (Módulo 4).
- HCL (HashiCorp Configuration Language): declarativa, com
for_each/count,dynamicblocks, funções, expressões condicionais — mas não é uma linguagem de programação completa (por design).
2.2 O ciclo
terraform init # baixa providers, configura o backend do state terraform validate # sintaxe e consistência terraform plan # calcula o DIFF entre o código e o state → mostra o que vai mudar terraform apply # executa o plan (com confirmação); atualiza o state terraform destroy # remove tudo que este state gerencia
Nunca aplique sem ler o plan. Ele diz exatamente o que será criado (+), alterado (~) e destruído (-). Um ~ que força recriação (-/+) de um banco de dados de produção é o tipo de coisa que o plan revela e que salva empregos. Em CI, o plan roda no PR e é revisado como código.
2.3 Terraform × OpenTofu
- Em 2023, a HashiCorp mudou a licença do Terraform de open source (MPL) para BSL (Business Source License — restrições de uso comercial competitivo).
- A comunidade forkou a última versão MPL e criou o OpenTofu, agora um projeto da Linux Foundation, open source, drop-in compatible com a sintaxe HCL do Terraform.
- Na prática: os conceitos e o HCL são os mesmos; o
tofusubstitui oterraformna linha de comando. OpenTofu tem inovado (state encryption nativa, provider iteration antecipado). Escolha organizacional; para aprender, tanto faz — o conhecimento transfere 100%.
Perguntas: "Explique o ciclo do Terraform" (init → plan → apply; plan mostra o diff), "O que é um provider e um data source?", "Diferença entre Terraform e OpenTofu" (mudança de licença; OpenTofu é o fork open source, HCL compatível), "Por que HCL não é Turing-complete?" (previsibilidade, legibilidade, análise estática). A certificação HashiCorp Terraform Associate aparece em muitas vagas.
✏️ Exercício 2 — Leia o plan
Um terraform plan mostra: ~ aws_instance.web com +/- (forces replacement) em subnet_id, e - aws_db_instance.main ... + aws_db_instance.main (forces replacement) por mudança de engine_version. O que você faz antes de aplicar?
Gabarito: Não aplicar cegamente. (1) A instância web será destruída e recriada por mudança de subnet — aceitável se ela é stateless e está atrás de um balanceador; senão, planejar janela / substituição gradual. (2) O banco de dados de produção será recriado (forces replacement) — isso significa perda de dados. Investigar: a mudança de engine_version deveria ser um upgrade in-place (alguns providers suportam via outro atributo), ou o certo é um upgrade gerenciado pela nuvem fora do Terraform e depois só refletir no código. Nunca deixar um -/+ de banco de produção passar num apply automatizado — exige prevent_destroy no lifecycle e revisão humana explícita.
O state e por que ele é sagrado
Objetivo: entender o que o state é, por que ele precisa de backend remoto com locking, e as operações de manutenção (import, moved, state surgery) sem se machucar.
3.1 O que é o state
O state (terraform.tfstate) é o mapeamento entre os recursos que você declarou no código e os objetos reais na nuvem (com seus IDs e atributos). É como o Terraform sabe que aws_instance.web no código corresponde à instância i-0abc123 na AWS — e, portanto, o que precisa mudar no próximo plan.
Sem o state, o Terraform "esquece" o que gerencia e, no próximo apply, tenta recriar tudo (gerando duplicatas ou conflitos). O state também contém valores sensíveis em texto claro (senhas de banco, chaves geradas) — nunca commite tfstate no git. E dois apply simultâneos no mesmo state o corrompem.
3.2 Backend remoto + locking
- Backend remoto: guardar o state num storage compartilhado e criptografado (S3, GCS, Azure Blob, Terraform/HCP Cloud, um backend do Spacelift/env0). Nunca no laptop de alguém.
- State locking: um lock (DynamoDB para o backend S3, ou nativo em outros) impede que dois
applyrodem ao mesmo tempo. - Versionamento do bucket de state para conseguir recuperar uma versão anterior.
- Criptografia at-rest (e, no OpenTofu, opcionalmente client-side).
- Acesso restrito — quem lê o state lê os segredos que estão nele.
3.3 Segmentar o state (blast radius)
Um único state gigante para toda a empresa = todo apply arrisca tudo, e o plan fica lento. Segmente por fronteira de mudança e de risco:
- Por ambiente (dev / staging / prod — states separados, credenciais separadas).
- Por camada / ciclo de vida (rede e IAM mudam raramente; workloads mudam sempre — states diferentes).
- Por time / domínio (cada time dono do seu state).
- Passar valores entre states via
terraform_remote_state(data source) ou, melhor, via outputs publicados / parâmetros (SSM, etc.) para reduzir acoplamento.
3.4 Operações de manutenção
| Situação | Ferramenta |
|---|---|
| Um recurso já existe na nuvem (criado à mão) e você quer que o Terraform passe a gerenciá-lo | terraform import (ou blocos import declarativos, 1.5+) — traz o objeto para o state sem recriá-lo |
| Você renomeou/moveu um recurso ou módulo no código | moved block no código (declarativo, revisável) — evita destruir-e-recriar; melhor que terraform state mv |
| Um recurso foi deletado fora do Terraform e você quer que ele "esqueça" | terraform state rm (cirurgia manual — cuidado) |
| O mundo real mudou e você quer sincronizar o state sem aplicar | terraform apply -refresh-only / plan -refresh-only |
| Detectar mudanças manuais | Drift detection: plan agendado (ou o recurso nativo do TFC/Spacelift) que alarma se o real ≠ código |
Blocos import e moved no código são revisáveis em PR, testáveis com plan e reproduzíveis — muito melhores que comandos terraform state ... executados na mão em produção, que ninguém vê e ninguém pode auditar. "State surgery" manual é o último recurso.
Perguntas: "O que é o state e por que backend remoto + locking?", "Por que não commitar o tfstate?" (segredos em texto claro), "Como você traria um recurso criado à mão para o Terraform?" (import), "Como renomear um módulo sem recriar recursos?" (moved block), "Como você limita o blast radius de um apply?" (segmentar o state por ambiente/camada/time).
✏️ Exercício 3 — Recupere o controle
Você herdou uma conta AWS com 200 recursos criados no console, zero IaC, e um único engenheiro que "sabe onde está tudo". Como você migra para Terraform com risco baixo?
Gabarito (abordagem): (1) Configurar backend remoto (S3 + lock) e uma estrutura de states segmentada. (2) Mapear os recursos (AWS Config / Resource Explorer / ferramentas como former2 ou terraformer para gerar HCL inicial). (3) Migrar por domínio/camada, incremental: começar pela rede/IAM (muda pouco), escrever o HCL, usar blocos import para trazer ao state, rodar plan e garantir que dá "no changes" (o código descreve exatamente o real). Só então o próximo domínio. (4) Nunca destroy nessa fase; ligar prevent_destroy nos recursos críticos. (5) Fechar o console (acesso somente leitura) quando um domínio estiver 100% em código, para não voltar a driftar. (6) Ligar drift detection.
Módulos e estrutura de repositório
Objetivo: escrever módulos reutilizáveis, versioná-los, e organizar o repositório por ambiente e por camada sem cair no excesso de abstração.
4.1 Módulos
Um módulo é um conjunto de recursos empacotado com uma interface (variáveis de entrada, outputs) — a unidade de reuso do Terraform. Um bom módulo:
- Tem uma responsabilidade clara (um módulo "rede VPC", um módulo "serviço ECS", um módulo "bucket com política padrão").
- Expõe poucas variáveis essenciais + defaults sensatos; não vira um "passa-tudo" que só reembrulha o provider.
- Aplica os padrões da organização por dentro (tags obrigatórias, criptografia ligada, logging, políticas de acesso) — é onde a governança mora.
- É versionado (git tag / registry) e consumido por versão fixa (
?ref=v1.4.2). - Tem
README, exemplos, e testes (Módulo 6).
module "api_service" { source = "git::https://github.com/acme/tf-modules.git//ecs-service?ref=v2.3.1" name = "payments-api" env = var.env cpu = 512 memory = 1024 image = var.image_tag # tags, log group, IAM role, alarms, autoscaling: aplicados DENTRO do módulo }
4.2 Estrutura do repositório
| Abordagem | Como | Trade-off |
|---|---|---|
| Por ambiente (diretório por env) | environments/{dev,staging,prod}/, cada um com seu main.tf chamando módulos compartilhados | Explícito, fácil de ver o que cada env tem; alguma repetição |
| Por camada (stacks) | stacks/{network,platform,workloads}/ com state por camada; env via workspace ou variável | Bom para blast radius; a "matriz env × camada" pode confundir |
| Workspaces do Terraform | Um código, N workspaces (um por env), state por workspace | DRY, mas esconde as diferenças de env no código condicional — use com cautela; muitos preferem diretórios explícitos |
| Terragrunt | Wrapper que reduz repetição entre ambientes (DRY do backend, dos providers, das versões) e orquestra dependências entre módulos | Poder e complexidade extra; ótimo em setups multi-conta grandes, exagero em setups pequenos |
A tentação de nunca repetir uma linha leva a módulos com 40 variáveis, condicionais aninhados e lookup(var.config[var.env], ...) por toda parte — impossível de ler e de auditar. Um pouco de repetição explícita entre ambientes (cada env com seu arquivo claro) costuma ser mais fácil de manter que uma abstração genial que só o autor entende. Abstraia o que é genuinamente comum e estável; deixe explícito o que varia por ambiente.
4.3 O registry e a governança de módulos
- Registry (Terraform Registry público, ou privado no TFC/Spacelift/Artifactory) para descoberta e versionamento de módulos.
- Módulos da comunidade (ex.:
terraform-aws-modules/*) são bons pontos de partida — mas fixe a versão e revise o que fazem. - Módulos internos são o "golden path" de infra: se todo serviço é criado pelo módulo
ecs-service, então criptografia, tags, alarmes e IAM mínimo vêm por padrão, sem cada time reinventar (ponte para Platform Engineering — Módulo 7).
Perguntas: "O que faz um bom módulo Terraform?" (uma responsabilidade, interface enxuta, padrões da org embutidos, versionado, testado), "Como você estrutura um repo para múltiplos ambientes?" (diretório por env com módulos compartilhados; workspaces com cautela), "O que é Terragrunt e quando vale a pena?", "DRY vs explícito em IaC".
✏️ Exercício 4 — Desenhe os módulos
Sua empresa vai rodar ~20 microserviços em ECS, em 3 ambientes, e quer que todo serviço tenha por padrão: tags de time e centro de custo, log group com retenção, IAM role de menor privilégio, alarmes de CPU/erro, e autoscaling. Como você organiza?
Gabarito: (1) Um módulo ecs-service versionado que recebe poucas variáveis (nome, time, cpu, memory, imagem, env) e cria por dentro: task definition, service, log group com retenção, IAM role mínima, alarmes CloudWatch, target tracking autoscaling, e aplica as tags obrigatórias. Toda a governança mora aqui. (2) Módulos de base separados: network (VPC, subnets — muda raro, state próprio), ecs-cluster. (3) Repositório com environments/{dev,staging,prod}/, cada um chamando o módulo ecs-service uma vez por serviço, com as diferenças de env explícitas (tamanhos, contagens). (4) Registry interno para o módulo; PRs revisados; plan em CI. Resultado: um serviço novo é ~15 linhas de HCL e já nasce conforme.
O ecossistema de IaC
Objetivo: situar Terraform/OpenTofu entre as alternativas — Pulumi, CloudFormation/CDK, Crossplane, Ansible, Packer — e saber quando cada uma encaixa.
5.1 Provisioning: as ferramentas
| Ferramenta | Modelo | Quando |
|---|---|---|
| Terraform / OpenTofu | Declarativo, HCL, multi-cloud, state próprio, ecossistema de providers gigante | O padrão de mercado; escolha default para infra multi-cloud e híbrida |
| Pulumi | Declarativo, mas em linguagens reais (TypeScript, Python, Go, C#); usa o mesmo modelo de state e muitos dos providers do Terraform | Time que quer loops/abstrações/testes com uma linguagem de programação de verdade; lógica complexa de geração de infra |
| AWS CloudFormation / CDK | Declarativo (YAML/JSON) ou via CDK (linguagens reais que geram CloudFormation); só AWS; sem state para gerir (a AWS gerencia) | Casado 100% com a AWS e quer integração nativa (drift detection, stacksets); CDK para quem prefere código |
| Crossplane | Declarativo dentro do Kubernetes: recursos de nuvem viram CRDs; o control plane do K8s reconcilia a infra continuamente | Você já vive em K8s e quer que a infra seja gerida pelo mesmo modelo (GitOps, RBAC, reconciliação); base de plataformas modernas |
| Outros | Bicep (Azure), Google Config Connector, CDKTF (CDK gerando Terraform) | — |
5.2 Config management (complementar, não substituto)
- Ansible (Chef, Puppet, Salt): configuram o interior de servidores — instalar pacotes, gerir arquivos, serviços, usuários. Provisioning (Terraform) cria a VM; config management a configura.
- Ansible é agentless (SSH), procedural-ish (playbooks com tasks idempotentes), ótimo para bootstrap, VMs legadas, tarefas de OS, e orquestração de operações.
- No mundo imutável/contêiner, config management perde peso: a "config" vira a imagem (Dockerfile) e o manifesto K8s. Ainda relevante para o que não é contêiner.
5.3 Imagens: Packer
Packer (HashiCorp) constrói imagens de máquina (AMI, imagem GCP, imagem Docker) de forma automatizada e versionada — parte-se de uma base, aplica-se provisioners (shell, Ansible), e sela-se a imagem. É o que viabiliza infra imutável: o Terraform lança instâncias a partir de uma AMI que o Packer produziu e testou, em vez de configurar cada instância no boot.
5.4 Como escolher
| Situação | Escolha |
|---|---|
| Padrão, multi-cloud, time de infra/DevOps | Terraform / OpenTofu |
| Quer linguagem de programação real, testes unitários da infra, lógica complexa | Pulumi (ou CDK/CDKTF) |
| 100% AWS e quer o mais nativo possível | CloudFormation / CDK |
| Plataforma sobre Kubernetes, infra gerida por reconciliação e GitOps | Crossplane |
| Configurar o interior de VMs, bootstrap, legado | Ansible (+ Terraform para provisionar) |
| Imagens douradas para infra imutável | Packer |
Perguntas: "Terraform vs Pulumi vs CloudFormation" (HCL declarativo multi-cloud vs linguagem real vs nativo AWS), "Diferença entre provisioning e config management" (criar a infra vs configurar o interior; Terraform + Ansible), "O que é Crossplane e por que usar?" (infra como CRDs, reconciliação contínua no K8s), "Para que serve o Packer?" (imagens douradas → infra imutável).
✏️ Exercício 5 — Escolha a stack
(a) Uma empresa 100% AWS, time pequeno, quer testes unitários da lógica de infra em TypeScript. (b) Uma plataforma interna sobre Kubernetes que quer expor "peça um banco Postgres" como um recurso declarativo que se auto-repara. (c) Provisionar 50 VMs Linux e instalar/configurar um agente de monitoramento em todas.
Gabarito: (a) AWS CDK (TypeScript, nativo AWS, testável) — ou Pulumi se quiser manter a porta aberta para multi-cloud. (b) Crossplane — define uma Composition que materializa "Postgres" em um RDS (ou um operator), gerida pelo control plane do K8s com reconciliação e GitOps; o dev pede via um CRD simples. (c) Terraform (ou OpenTofu) para provisionar as 50 VMs + Ansible para instalar e configurar o agente (playbook idempotente via SSH); ou uma imagem Packer com o agente já embutido se as VMs forem descartáveis.
IaC em produção: CI/CD, policy e testes
Objetivo: rodar IaC com o mesmo rigor de software — plan em PR, apply controlado, policy as code, testes, e gestão de segredos.
6.1 CI/CD para infraestrutura
Pull Request abre ▼ CI: fmt + validate + tflint + plan + policy check + security scan + custo estimado ▼ Revisão humana do PLAN (não só do código — o diff de infra é o que importa) ▼ Merge → CD: apply automático no ambiente-alvo (com aprovação manual para prod) ▼ Notificação + drift detection agendada
- O plan no PR é o coração: o revisor vê exatamente o que vai mudar na nuvem, comentado no PR.
- Ferramentas de orquestração: Atlantis (open source, comenta o plan no PR), Terraform/HCP Cloud, Spacelift, env0, Scalr — cuidam de state, locking, RBAC, política, sequência de stacks e histórico.
- Infracost no PR: estimativa de impacto de custo da mudança.
- Apply: automático para dev/staging; para prod, aprovação manual e janela.
6.2 Policy as Code
| Ferramenta | Como |
|---|---|
| OPA / Conftest / Rego | Políticas em Rego sobre o plan em JSON — genérico, além de Terraform |
| Sentinel | Linguagem de política da HashiCorp (TFC/Enterprise) |
| Checkov, tfsec/Trivy, KICS, Terrascan | Regras prontas de segurança e boas práticas (bucket público, SG aberto para 0.0.0.0/0, sem criptografia, sem tags) |
| terraform-compliance | BDD sobre o plan ("todo RDS deve ter storage_encrypted = true") |
Exemplos de política: "nenhum security group com 0.0.0.0/0 na porta 22"; "todo recurso tem as tags team e cost-center"; "storage sempre criptografado"; "instâncias só de famílias aprovadas"; "nada de IAM *:*". Roda no CI e bloqueia o merge se violar (com exceções auditadas).
6.3 Testes de IaC
terraform test(nativo, 1.6+): testes em HCL que fazemplan/applyem recursos de teste e checam asserções.- Terratest (Go): sobe infra real efêmera, valida (faz uma request HTTP, checa um output), destrói. Mais lento, mais realista.
- Testes de contrato dos módulos: cada exemplo do módulo tem que dar
planlimpo. - Preview / ephemeral environments (Módulo 9) como teste de integração de verdade.
6.4 Segredos
- Nunca em variáveis de texto no código nem no state commitado.
- Buscar em runtime de um cofre: HashiCorp Vault, AWS Secrets Manager, GCP Secret Manager (via data source), ou SOPS (criptografia de arquivos com KMS) para o que precisa ficar no repo.
- Lembrar que o state ainda guarda o valor resolvido → backend criptografado e acesso restrito (Módulo 3); OpenTofu tem state encryption client-side.
- Credenciais do próprio pipeline: OIDC federation (o CI assume um role sem chave estática) > chaves de longa duração.
Perguntas: "Como você roda Terraform em CI/CD com segurança?" (plan no PR revisado, apply com aprovação para prod, state remoto com lock, OIDC em vez de chaves), "O que é policy as code e dê exemplos de políticas?" (OPA/Checkov; SG aberto, sem criptografia, tags obrigatórias), "Como você testa um módulo Terraform?" (terraform test, Terratest, plan limpo nos exemplos), "Onde ficam os segredos?" (cofre em runtime; nunca no state commitado).
✏️ Exercício 6 — Monte o pipeline
Um time aplica Terraform da máquina local, sem revisão, e já teve dois incidentes (um bucket exposto, um SG com SSH aberto para o mundo). Desenhe o pipeline que teria evitado ambos.
Gabarito: (1) State remoto (S3 + lock), acesso via OIDC do CI. (2) Proibir apply local em prod (política de acesso: só o pipeline tem o role). (3) No PR: fmt, validate, tflint, terraform plan comentado no PR (Atlantis/Spacelift), Checkov/tfsec (pegaria o bucket público e o SG 0.0.0.0/0:22) e uma política OPA/Sentinel customizada que bloqueia esses padrões, Infracost. (4) Revisão humana obrigatória do plan. (5) Merge → apply automático em staging, aprovação manual para prod. (6) Drift detection agendada. Os dois incidentes seriam bloqueados no scan de segurança antes do merge.
O que é Platform Engineering
Objetivo: a tese do Platform Engineering — reduzir carga cognitiva com self-service — e os conceitos: IDP, golden path, "platform as a product", Team Topologies.
7.1 O problema que resolve
O movimento "you build it, you run it" deu autonomia aos times de produto — mas também jogou neles a complexidade inteira da nuvem: Kubernetes, IAM, redes, Terraform, CI/CD, observabilidade, secrets, políticas de segurança. A carga cognitiva passou a competir com o tempo de construir features. Sintomas: cada time reinventa o mesmo pipeline, configura observabilidade do zero, copia Terraform de outro time (com os bugs), e leva semanas para pôr um serviço novo no ar.
Construir e manter uma plataforma interna de autoatendimento (Internal Developer Platform) que oferece um caminho pavimentado (golden path / paved road) para as tarefas comuns — criar um serviço, um banco, um ambiente, um pipeline — de forma que o desenvolvedor consiga fazer sozinho, em minutos, sem abrir chamado e sem ser especialista em infra. A plataforma esconde a complexidade sem tirar o poder de quem precisa dele.
7.2 Conceitos-chave
- Internal Developer Platform (IDP): o conjunto integrado de ferramentas e serviços de autoatendimento. Não é uma ferramenta só — é a montagem coerente de várias (Módulo 8).
- Internal Developer Portal: a interface / catálogo (ex.: Backstage) onde o dev descobre serviços, cria novos a partir de templates, e vê docs, donos, saúde. É a "vitrine" do IDP, não o IDP inteiro.
- Golden Path / Paved Road: a forma recomendada e suportada de fazer algo (ex.: "um serviço Go em produção" = este template + este pipeline + este runtime + observabilidade de fábrica). Quem segue o golden path anda rápido e com suporte; quem sai dele pode, mas assume a complexidade.
- Platform as a Product: a plataforma tem usuários (os desenvolvedores), um product owner, um roadmap, e sua adoção é voluntária (ela precisa ser boa o suficiente para as pessoas quererem usá-la, não ser imposta).
- Thinnest Viable Platform (TVP): começar com o mínimo que resolve a dor mais aguda (às vezes é só uma página de wiki bem feita + um template), não um mega-projeto.
7.3 Team Topologies
O modelo de Team Topologies (Skelton & Pais) dá o vocabulário organizacional:
- Stream-aligned team: o time de produto que entrega valor ao usuário final — o "cliente" da plataforma.
- Platform team: constrói e opera o IDP como produto, para reduzir a carga cognitiva dos stream-aligned.
- Enabling team: ajuda os stream-aligned a adotar novas capacidades (coaching temporário).
- Complicated-subsystem team: dono de uma parte que exige especialização profunda.
- Modo de interação preferido entre platform e stream-aligned: X-as-a-Service (consome sem precisar conversar), com colaboração pontual quando algo novo é construído.
Se todo pedido de infra passa por um chamado para o "time de plataforma", que faz na mão — isso não é Platform Engineering, é o velho time de ops com nome novo, e é pior porque agora tem uma marca. Platform Engineering só funciona se for genuinamente self-service. Se a plataforma não pode ser usada sem falar com o time que a fez, ela falhou na sua premissa.
Perguntas: "O que é Platform Engineering e qual problema resolve?" (carga cognitiva; self-service via golden path), "O que é um golden path?", "O que significa 'platform as a product'?" (usuários, PO, roadmap, adoção voluntária), "Qual o anti-padrão mais comum?" (plataforma que vira gargalo de chamados), "Backstage é um IDP?" (não — é o portal/catálogo, uma parte).
✏️ Exercício 7 — TVP
Uma empresa com 15 times leva ~3 semanas para pôr um microserviço novo em produção: cada time copia Terraform de outro, monta pipeline do zero, configura observabilidade e secrets à mão. Qual seria a "Thinnest Viable Platform" para atacar isso?
Gabarito (exemplo): Não construir um IDP completo de cara. TVP: (1) Um template de serviço (repositório-modelo ou backstage scaffolder / cookiecutter) que já vem com Dockerfile, pipeline de CI/CD, manifesto K8s (ou módulo Terraform ecs-service), observabilidade OTel de fábrica, e secrets integrados ao cofre. (2) Um comando/PR que cria o serviço a partir do template e provisiona a infra pelo golden path (módulo versionado, Módulo 4). (3) Documentação do golden path. Isso já derruba as 3 semanas para horas, sem portal chique. Portal (Backstage), catálogo e abstrações mais ricas vêm depois, guiados pela dor seguinte.
Construindo a plataforma
Objetivo: as capacidades que compõem um IDP, as abstrações e ferramentas (Backstage, Crossplane, Humanitec, Score), a decisão construir vs comprar, e como medir sucesso.
8.1 As capacidades de um IDP
| Capacidade | O que entrega ao dev | Ferramentas típicas |
|---|---|---|
| Scaffolding / templates | Criar um serviço novo pronto (repo + CI + infra + observabilidade) | Backstage Software Templates, cookiecutter, Yeoman |
| Provisioning de infra | Pedir banco/fila/bucket/cluster por self-service | Módulos Terraform/OpenTofu, Crossplane, Kratix, Humanitec, Pulumi |
| CI/CD | Pipeline padrão que "só funciona" | GitHub Actions/GitLab CI reutilizáveis, templates de pipeline |
| Runtime / deploy | Um jeito só de subir e escalar workloads | Kubernetes + abstração (Helm/Kustomize/operators), PaaS interno |
| Observabilidade de fábrica | Logs/métricas/traces + dashboards + SLOs sem configurar (ver apostila de Observabilidade) | OTel auto-instrumentação, dashboards gerados |
| Secrets | Injeção segura sem o dev tocar no cofre | Vault + agent/CSI, External Secrets Operator |
| Service catalog | Descobrir serviços, donos, docs, dependências, saúde | Backstage, Port, Cortex, OpsLevel |
| Golden path docs | Como fazer as coisas do jeito suportado | Docs versionadas, TechDocs |
8.2 Abstrações: o "workload spec"
A ideia de ponta: o dev descreve o que a aplicação precisa em termos abstratos ("um serviço web, um banco Postgres, uma fila"), e a plataforma traduz isso para a infra concreta (RDS ou Cloud SQL, SQS ou PubSub) conforme o ambiente e as políticas. Ferramentas/padrões:
- Score (open source, CNCF sandbox): um spec de workload agnóstico de plataforma.
- Crossplane Compositions: definir "Database" como um XRD que compõe recursos reais.
- Kratix: "promises" — a plataforma publica um contrato ("peça um Postgres") e um pipeline o materializa.
- Humanitec, Kubevela, Radius: platform orchestrators comerciais/open source que fazem essa tradução.
8.3 Construir × comprar
| Construir (montar com OSS) | Comprar (plataforma comercial) |
|---|---|
| Backstage + Crossplane + Argo + OTel + Vault, integrados pelo seu time | Humanitec, Port, Northflank, Qovery, Mia-Platform, etc. |
| + controle total, sem lock-in, custo de licença zero | + time-to-value rápido, menos gente para manter |
| − exige um time de plataforma dedicado e competente; Backstage tem curva | − custo, lock-in, menos flexível nas bordas |
| Faz sentido: org grande, requisitos específicos, já tem o time | Faz sentido: org média, quer resultado rápido, sem apetite de manter plataforma |
8.4 Medir o sucesso da plataforma
- Métricas DORA (DevOps Research): frequência de deploy, lead time para mudança, taxa de falha de mudança, tempo de restauração — a plataforma deve melhorá-las.
- DevEx / carga cognitiva: pesquisas ("SPACE framework"), tempo para o primeiro deploy de um novo contratado, NPS da plataforma.
- Adoção: % de serviços no golden path; % de times usando o self-service vs abrindo chamado.
- "Time to hello world": quanto tempo da ideia ao serviço em produção — a métrica-síntese.
- Custo por serviço/ambiente (cruza com FinOps).
Perguntas sénior: "Quais capacidades compõem um IDP?" (scaffolding, provisioning, CI/CD, runtime, observabilidade de fábrica, secrets, catálogo), "O que é uma abstração de workload e por que ajuda?" (dev descreve necessidade, plataforma traduz — Score, Crossplane), "Backstage: o que faz e o que não faz?" (portal/catálogo/scaffolder; não provisiona sozinho), "Como você mede se a plataforma está dando certo?" (DORA + adoção + time to hello world + DevEx).
✏️ Exercício 8 — Priorize as capacidades
Você lidera um platform team novo, 4 pessoas, 20 times de produto, orçamento apertado. Em que ordem você entrega as capacidades e por quê?
Gabarito (uma boa ordem): (1) Golden path + scaffolding de serviço (template com CI/CD e infra por módulo) — ataca a dor nº 1 (semanas para um serviço novo) e não precisa de portal. (2) Observabilidade de fábrica (OTel + dashboards + SLO base) — todo serviço nasce observável, reduz incidentes e chamados. (3) Secrets integrados (External Secrets/Vault) — remove um ponto de dor e de risco recorrente. (4) Self-service de infra comum (banco, fila, bucket via módulos/Crossplane) — elimina os chamados mais frequentes. (5) Portal/catálogo (Backstage) — quando já há o que catalogar e o volume justifica a curva. Cada passo guiado pela próxima dor real e por métricas (adoção, chamados evitados), tratando a plataforma como produto.
GitOps, multi-cluster e temas de fronteira
Objetivo: o modelo GitOps de reconciliação, ambientes efêmeros, multi-cluster/multi-cloud, segurança da supply chain de IaC e o que vem por aí.
9.1 GitOps
GitOps aplica o modelo de reconciliação do Kubernetes ao deploy: o estado desejado vive num repositório git, e um agente no cluster (pull) compara continuamente o cluster com o git e converge — em vez de um pipeline "empurrar" (push) mudanças de fora.
| Princípio GitOps | Significado |
|---|---|
| Declarativo | O estado é descrito, não scriptado |
| Versionado e imutável | Git é a fonte de verdade; histórico e rollback = git revert |
| Pull automático | O agente puxa e aplica; não há credencial de cluster no CI externo |
| Reconciliação contínua | Drift (alguém mudou algo no cluster à mão) é detetado e revertido para o git |
- Ferramentas: Argo CD, Flux (ambos CNCF graduados).
- Estrutura comum: um repo de "config" por ambiente; promoção entre ambientes = PR que atualiza a tag da imagem / os valores.
- GitOps é sobretudo para o runtime (K8s manifests, Helm) — para infra de nuvem, combina-se com Crossplane (infra como CRDs reconciliados por GitOps) ou com o Terraform rodando via Flux/Atlantis.
9.2 Ambientes efêmeros
Um ambiente completo criado por PR (preview environment) e destruído no merge/close — a infra e o app juntos, isolados. Dá teste de integração de verdade, revisão de UX pelo time de produto, e "nada esquecido ligado". Habilitado por IaC parametrizado + namespaces/clusters efêmeros + GitOps. Ferramentas: vCluster, Crossplane, Qovery, Uffizzi, ou pipelines próprios.
9.3 Multi-cluster e multi-cloud
- Multi-cluster (vários clusters K8s por região/tenant/blast radius): gerido por GitOps (Argo CD "app of apps" / ApplicationSets), Cluster API para provisionar clusters como código, fleet management (Rancher, GKE Fleet).
- Multi-cloud é caro em complexidade — faça só com motivo real (soberania, resiliência regulatória, evitar lock-in crítico). O denominador comum costuma ser Kubernetes + Terraform/OpenTofu + Crossplane; evitar depender de serviços proprietários únicos de um provedor no caminho crítico.
9.4 Segurança da supply chain de IaC
- Módulos e providers de terceiros: fixar versões e hashes (
.terraform.lock.hcl), revisar antes de adotar, mirror interno. - Policy as code obrigatória no pipeline (Módulo 6) — o gate que impede o recurso inseguro.
- Least privilege do pipeline: o role que aplica infra deve poder mudar só o que aquele stack gerencia; OIDC em vez de chaves.
- Proteção do state: criptografia, acesso mínimo, versionamento (é onde os segredos moram).
- Assinatura e proveniência das imagens (Packer/contêiner) — cosign, SLSA.
- Compliance as code: mapear controles (CIS Benchmarks, SOC2, ISO 27001) para políticas automatizadas e evidências geradas pelo pipeline.
9.5 O que vem por aí
- IA gerando e revisando IaC: copilots que escrevem módulos, explicam o plan, sugerem correções de política — útil como acelerador, com revisão humana (o plan continua sendo a autoridade).
- Platform orchestrators amadurecendo (Score, Radius, Kratix) — a abstração de workload virando padrão.
- Convergência infra + runtime via Crossplane/GitOps — um só modelo de reconciliação para tudo.
- Plataformas para IA/ML (golden path para treinar/servir modelos — ver apostilas de MLOps e LLMOps).
- FinOps embutido na plataforma (custo por serviço visível no portal, guardrails de custo no provisioning — ver apostila de FinOps).
Perguntas: "O que é GitOps e como difere de um pipeline push?" (estado no git, agente pull, reconciliação contínua, drift revertido), "Argo CD vs Flux" (ambos CNCF; Argo tem UI rica, Flux é mais componível), "Como você faria ambientes efêmeros por PR?", "Riscos de supply chain em IaC e como mitigar" (lockfile, mirror, policy as code, least privilege do pipeline, state protegido).
✏️ Exercício 9 — Desenhe o fluxo GitOps
Uma empresa faz deploy no K8s por um pipeline que roda kubectl apply com credenciais de cluster guardadas no CI. Quer: sem credencial de cluster no CI, rollback trivial, e reversão automática de mudanças manuais no cluster. Desenhe a solução com GitOps.
Gabarito: (1) Um repo de config (manifests/Helm/Kustomize) por ambiente, que é a fonte de verdade. (2) Argo CD (ou Flux) rodando dentro de cada cluster, com acesso somente ao próprio cluster, observando o repo e reconciliando continuamente. O CI externo não tem mais credencial de cluster — ele só faz build/test e abre um PR (ou atualiza a tag da imagem) no repo de config. (3) Deploy = merge no repo de config; o Argo aplica. Rollback = git revert do commit. (4) Self-heal / prune ligados no Argo: qualquer mudança manual no cluster (drift) é detetada e revertida para o estado do git. (5) Promoção entre ambientes = PR que copia os valores de staging para prod, com aprovação.
Mercado de trabalho: roadmap, entrevistas e portfólio
Objetivo: converter o conteúdo dos módulos anteriores em aprovação — perfis, certificações, roadmap, banco de perguntas com respostas e projetos que geram entrevista.
10.1 Os perfis que contratam
| Perfil | Foco |
|---|---|
| Platform Engineer | Construir e operar o IDP; golden paths; abstrações; DevEx |
| Cloud / Infrastructure Engineer | IaC (Terraform/OpenTofu), redes, IAM, multi-conta, custo |
| DevOps Engineer | CI/CD, IaC, GitOps, observabilidade |
| SRE | Confiabilidade (apostila irmã), frequentemente contribui para a plataforma |
| Site/Systems Reliability + Platform | Papéis híbridos em empresas menores |
10.2 Certificações e leituras
- HashiCorp Certified: Terraform Associate — a mais citada; cobre bem os Módulos 2–4.
- CKA / CKAD (Kubernetes) — quase pré-requisito para plataforma moderna.
- Certificações de nuvem a nível de arquitetura/associate (AWS/GCP/Azure).
- Leitura: Terraform: Up & Running (Yevgeniy Brikman); Infrastructure as Code (Kief Morris); Team Topologies (Skelton & Pais); Platform Engineering on Kubernetes (Mauricio Salatino); o site platformengineering.org e o Internal Developer Platform reference architecture; os DORA reports.
10.3 Roadmap de estudo (8–10 semanas)
| Semanas | Foco | Prática |
|---|---|---|
| 1–2 | IaC fundamentos: Terraform/OpenTofu, ciclo, HCL, providers (Módulos 1–2) | Provisionar uma stack real (VPC + serviço + banco) numa conta de estudo |
| 3 | State: backend remoto, locking, import, moved, segmentação (Módulo 3) | Migrar recursos criados à mão para o Terraform via import, chegando a "no changes" |
| 4 | Módulos e estrutura de repo (Módulo 4) | Escrever um módulo service versionado com governança embutida; usar em 3 "ambientes" |
| 5 | Ecossistema: Pulumi, Crossplane, Ansible, Packer — comparar (Módulo 5) | Refazer uma pequena parte da stack em Pulumi ou Crossplane |
| 6 | IaC em produção: CI/CD (Atlantis), policy as code (Checkov/OPA), testes, secrets (Módulo 6) | Pipeline com plan no PR + Checkov + política OPA custom + Infracost |
| 7–8 | Platform Engineering: IDP, golden path, Backstage, abstrações (Módulos 7–8) | Um template de serviço (Backstage scaffolder ou cookiecutter) que cria repo + CI + infra + observabilidade |
| 9–10 | GitOps (Argo CD/Flux), ambientes efêmeros, supply chain (Módulo 9); portfólio | Deploy do serviço via GitOps com self-heal; estudo de caso publicado |
10.4 Banco de perguntas de entrevista (com a resposta que aprova)
Júnior/pleno — "O que é o state do Terraform e por que remoto?"
O state mapeia os recursos do código para os objetos reais na nuvem (IDs, atributos) — é como o Terraform calcula o diff no próximo plan. Precisa ser remoto (S3/GCS/TFC) e com locking porque: dois apply simultâneos o corrompem; ele contém segredos em texto claro (não pode ficar no git nem no laptop); e o time precisa compartilhá-lo. Backend criptografado, versionado e com acesso restrito.
Pleno — "Como você renomeia um recurso/módulo sem destruí-lo?"
Um bloco moved no código (declarativo, revisável em PR, testável com plan) — ele diz ao Terraform que o endereço antigo virou o novo, então ele atualiza o state sem destruir-e-recriar. É melhor que terraform state mv na mão, que não é auditável.
Pleno — "Declarativo vs imperativo; imutável vs mutável"
Declarativo: você descreve o estado desejado e a ferramenta calcula os passos (Terraform, K8s). Imperativo: você escreve os passos (scripts). Imutável: nunca alterar um servidor rodando — construir imagem nova e substituir (Packer + ASG, contêineres); elimina drift. Mutável: aplicar mudanças no servidor existente (config management contínuo); tende ao drift. O padrão moderno é declarativo + imutável.
Pleno/sénior — "Como você roda Terraform em CI/CD com segurança?"
State remoto com lock; o CI assume um role via OIDC (sem chave estática) com permissão só para o stack que gerencia. No PR: fmt/validate/tflint, plan comentado no PR, scan de segurança (Checkov/tfsec), policy as code (OPA/Sentinel) que bloqueia o merge, Infracost. Revisão humana do plan. Merge → apply automático em dev/staging, aprovação manual para prod. Drift detection agendada. prevent_destroy nos recursos críticos.
Sénior — "O que é Platform Engineering e como difere de 'ops com outro nome'?"
É construir uma plataforma interna de autoatendimento (IDP) que dá aos times de produto um caminho pavimentado (golden path) para as tarefas comuns — criar serviço, banco, ambiente, pipeline — sem abrir chamado e sem ser especialista em infra. Difere de "ops renomeado" porque é genuinamente self-service: se o dev precisa falar com o platform team para usar a plataforma, ela falhou. Trata-se como produto: usuários, PO, roadmap, adoção voluntária, métricas (DORA, tempo até hello world, adoção).
Sénior — "O que é GitOps?"
O estado desejado vive num repo git (declarativo, versionado, imutável); um agente dentro do cluster (Argo CD/Flux) puxa e reconcilia continuamente o cluster com o git. Deploy = merge; rollback = git revert; drift (mudança manual no cluster) é detetado e revertido. Vantagens: sem credencial de cluster no CI externo, histórico e auditoria completos, e o cluster nunca "diverge em silêncio".
Armadilha — "Vamos abstrair tudo num módulo genérico para nunca repetir código"
DRY excessivo em IaC produz módulos com dezenas de variáveis e condicionais aninhados que ninguém consegue ler nem auditar — e o custo de manutenção supera o da repetição. Abstraia o que é genuinamente comum e estável (o módulo de serviço com a governança embutida); deixe explícito o que varia por ambiente (cada env com seu arquivo claro). Legibilidade e auditabilidade valem mais que zero repetição.
10.5 Projetos de portfólio que geram entrevista
- Stack multi-ambiente (âncora): uma aplicação real provisionada com Terraform/OpenTofu em dev/staging/prod, via um módulo de serviço versionado com governança embutida (tags, criptografia, IAM mínimo, alarmes), state remoto segmentado, e CI com plan no PR + Checkov + política OPA custom + Infracost. README com as decisões.
- Golden path de serviço: um template (Backstage scaffolder ou cookiecutter) que cria repo + pipeline + infra + observabilidade OTel de fábrica — "do zero a produção em minutos", demonstrado.
- GitOps end-to-end: Argo CD/Flux com self-heal e prune, promoção entre ambientes por PR, e a demonstração de drift sendo revertido.
- Crossplane ou Pulumi: refazer uma parte da stack com uma segunda ferramenta, comparando os trade-offs por escrito.
- Migração para IaC: pegar recursos criados à mão e trazê-los para o Terraform via blocos
import, chegando a "no changes", documentando o processo.
Quatro ideias sustentam IaC e Platform Engineering: (1) infra é código — versionada, revisada em PR, aplicada por pipeline, e o plan é o que se revisa; (2) o state é sagrado — remoto, com lock, criptografado, segmentado por blast radius; (3) declarativo + imutável + policy as code elimina o drift e os recursos inseguros na raiz; (4) Platform Engineering empacota tudo isso num produto self-service com golden paths — e só funciona se o dev consegue usar sem abrir chamado. As ferramentas mudam; esses princípios, não.