Em duas semanas, refazer o CI/CD e a infraestrutura como código precisa deixar quatro coisas funcionando de ponta a ponta. Uma trava que roda antes de cada push. A infraestrutura descrita em código, com o state criptografado. Uma etapa de plan que barra mudanças destrutivas. E releases com tag, publicados por digest, a impressão digital única da imagem. Nosso pacote de CI/CD e IaC faz isso por US$ 4.000.
Se você ainda está decidindo o que é DevOps na sua empresa, comece por O que é DevOps. Aqui, prefiro mostrar os comandos, porque “montamos um pipeline” não diz nada. Essa é a configuração que usamos nos nossos projetos. Para uma plataforma SaaS de análise de portfólios, o pipeline termina conferindo a mesma coisa: que o que roda em produção é o que foi publicado.
Como saber se o seu CI/CD funciona?
Não é contando ferramentas. As métricas DORA medem duas coisas: velocidade (lead time da mudança, frequência de deploy) e instabilidade (taxa de falha, tempo de recuperação e retrabalho de deploys). O guia insiste que velocidade e estabilidade não se opõem. Se uma reforma faz você publicar mais rápido e quebrar mais, ela não funcionou. Se prefere que montemos para você, o pacote de CI/CD e IaC é a nossa versão de escopo fixo.
Antes de começar, veja se hoje você mede isso de verdade. Na The Platform Radar contei de um CTO que tinha certeza de que o time dele medisse DORA. Três minutos de perguntas depois, nenhum dos dois estava tão seguro (a edição está aqui, em inglês). Acontece mais do que se admite. O grave é descobrir depois de passar um trimestre melhorando um número em que ninguém confia. Como tirar cada métrica de dados crus está em métricas DORA.
O que faz a trava antes do push?
O lugar mais barato para pegar um build quebrado é a máquina de quem programa, antes de qualquer coisa sair de lá. A nossa roda quatro verificações em paralelo antes de cada push: detecção de segredos, typecheck, lint e build. Se uma falha, o push não acontece.
Uma versão mínima para um projeto Node:
#!/usr/bin/env bash
# scripts/push-gate.sh, usado assim: scripts/push-gate.sh && git push
set -euo pipefail
gitleaks git --redact --log-opts="origin/main..HEAD" &
pnpm typecheck & pnpm lint & pnpm build &
for job in $(jobs -p); do wait "$job"; done
O wait em cada processo propaga o código de saída, então uma única verificação vermelha derruba tudo. Em alguns repositórios somamos regras de arquitetura e um orçamento de código morto. Roda em segundos e em local, com as mesmas regras para todo mundo. Esse último ponto pesa mais do que parece: regra que só vale na máquina de algumas pessoas não é regra.
Como proteger o state da infraestrutura?
O arquivo de state liga o seu código aos recursos reais e muitas vezes guarda valores sensíveis. Perdê-lo dói. Vazá-lo é pior. Usamos OpenTofu, o fork de código aberto do Terraform que compartilha a linguagem HCL, com o state criptografado. Segundo a documentação, ele criptografa state e plans em repouso, em disco local ou em um backend, com poucas linhas:
terraform {
encryption {
key_provider "pbkdf2" "main" {
passphrase = var.state_passphrase
}
method "aes_gcm" "main" {
keys = key_provider.pbkdf2.main
}
state {
method = method.aes_gcm.main
enforced = true
}
plan {
method = method.aes_gcm.main
enforced = true
}
}
}
A documentação traz dois avisos que vale repetir. Com a criptografia ligada, state e plans ficam irrecuperáveis sem a chave. E em um projeto que já existe você precisa de um método unencrypted temporário para migrar. Em produção eu usaria o serviço de gestão de chaves da nuvem em vez de uma passphrase, e a chave nunca vai para o repositório.
Se você chegou aqui procurando “Terraform”, quase tudo vale igual. A criptografia nativa do state é a única parte exclusiva do OpenTofu.
O que é um freio de mudanças destrutivas?
Um plan que apaga um banco de dados parece igual a um que adiciona uma tag, a menos que algo o leia. O nosso lê. O plan em JSON do OpenTofu lista cada mudança com suas actions, e procurar "delete" ali pega tanto exclusões quanto substituições:
tofu plan -out=plan.bin
apagados=$(tofu show -json plan.bin \
| jq '[.resource_changes[] | select(.change.actions | index("delete"))] | length')
if [ "$apagados" -gt 0 ]; then
echo "O plan apaga ou substitui $apagados recurso(s); exige aprovação explícita." >&2
exit 1
fi
Os recursos que guardam dados levam ainda prevent_destroy no ciclo de vida. Remover um deles exige um commit deliberado, não um acidente.
O que significa publicar por tag e fazer deploy por digest?
Cada versão é uma tag SemVer (o formato v1.4.0: maior, menor, correção) anotada na branch principal: git tag -a v1.4.0 -m "..." && git push origin v1.4.0. A tag dispara o pipeline, que constrói a imagem, roda as migrações se o repositório tiver e faz o deploy.
A promoção dessa versão de um ambiente ao seguinte, com verificações, está no texto sobre Argo CD e Kargo.
O deploy usa o hash de conteúdo da imagem, registry/app@sha256:…, nunca uma tag mutável como latest. Um digest nomeia exatamente um conjunto de bytes, e por isso você consegue provar que o que roda em produção é o que foi construído e testado:
docker buildx build --push -t "$IMAGE:$TAG" --metadata-file meta.json .
DIGEST=$(jq -r '."containerimage.digest"' meta.json)
gcloud run deploy app --image="$IMAGE@$DIGEST" --region="$REGION"
No fim, o pipeline lê o digest que a plataforma está de fato executando e compara com o que construiu. Se forem diferentes, a publicação não terminou. É assim que verificamos cada deploy de produção de uma plataforma de publicidade com IA que construímos para um cliente: 90 versões em 11 dias. E foi assim que se conferiu a primeira versão da plataforma de análise de portfólios pelo pipeline novo, com as 12 imagens em execução batendo. Um rollback ensaiado em desenvolvimento levou 72 segundos para voltar e 124 para avançar. Foi só em desenvolvimento. Um rollback em produção ainda não medimos.
O que acontece durante as duas semanas?
O plano exato se fecha no primeiro dia, mas a ordem costuma ser esta.
A primeira semana é de leitura e de colocar a trava. Fazemos o inventário do que existe: repositórios, pipelines, contas de nuvem, passos manuais, segredos. Subimos a trava local antes do push e levamos a infraestrutura atual para código, importando o que já roda em vez de recriar, com state remoto criptografado.
A segunda semana é o caminho de publicação. Colocamos o freio de plan e o prevent_destroy em tudo o que guarda dados e construímos o pipeline por tags: compilar, migrar, publicar por digest, conferir. Depois passamos um release real por ali e revertemos um.
O critério de saída é uma mudança real indo do commit à produção pelo caminho novo, com você olhando. Um pipeline que nunca publicou nada não está entregue.
Preciso trocar de ferramenta de CI?
Quase nunca. A idade não é a pergunta para nenhum servidor de CI, Jenkins incluído. Faça três: a definição do pipeline vive no repositório? Uma execução pode ser reproduzida? O deploy está preso a um artefato imutável? Se as três respostas são sim, trocar de ferramenta é opcional. Se alguma é não, uma ferramenta nova não resolve.
Raramente a ferramenta é a parte difícil. Difíceis são as decisões que ninguém quer tomar: quem aprova um plan destrutivo, o que bloqueia uma versão, como funciona o rollback e quem o testou de verdade. Duas semanas bastam quando o escopo é um produto com seus ambientes. Se você tem vários produtos em tecnologias diferentes, comece por um Discovery ou use o primeiro produto como modelo para os demais.
Por onde começar?
Descreva numa frase como sai uma versão hoje. Se aparecer “alguém roda”, este pacote é para você. O escopo completo está em serviços de DevOps, e os outros pacotes, em preços.
Fontes
- DORA, métricas de desempenho de entrega de software, consultada em 6 de outubro de 2026.
- OpenTofu, State and Plan Encryption, consultada em 6 de outubro de 2026 (última versão publicada naquele dia: v1.13.1, de 1 de outubro).
- As duas plataformas: números de medições próprias, outubro de 2026.
