Pular para o conteúdo

Promover o mesmo artefato entre ambientes

Intermediário12 min de leituracicd

O objetivo deste guia é simples de enunciar e frequentemente violado: o binário que roda em produção é exatamente o que passou nos testes. Um build por ambiente quebra isso, e o sintoma clássico é o bug que “só acontece em produção”.

1. Reconheça o problema de reconstruir por ambiente

Seção intitulada “1. Reconheça o problema de reconstruir por ambiente”

Rebuildar para homologação e de novo para produção produz artefatos diferentes, mesmo com o mesmo commit: dependência transitiva que mudou de versão, imagem base atualizada, ordem de arquivos, cache que acertou de outro jeito. O teste validou um artefato; produção recebeu outro.

Além disso, o build de produção passa a ser o único que nunca foi exercitado antes de importar.

Janela do terminal
IMAGE="registry.exemplo.com/loja"
docker buildx build --push -t "$IMAGE:${GIT_SHA}" .
# o digest é a identidade imutável do artefato; a tag é só um ponteiro
DIGEST=$(docker buildx imagetools inspect "$IMAGE:${GIT_SHA}" \
--format '{{json .Manifest.Digest}}' | tr -d '"')
echo "$DIGEST" # sha256:...

Guarde o digest como saída do job e propague-o pelos estágios seguintes:

jobs:
build:
outputs:
digest: ${{ steps.build.outputs.digest }}
homologacao:
needs: build
uses: ./.github/workflows/deploy.yml
with: { ambiente: hom, digest: "${{ needs.build.outputs.digest }}" }
producao:
needs: [build, homologacao]
uses: ./.github/workflows/deploy.yml
with: { ambiente: prod, digest: "${{ needs.build.outputs.digest }}" }

No manifest, referencie por digest, nunca por tag móvel:

image: registry.exemplo.com/loja@sha256:SUBSTITUA_PELO_DIGEST_VALIDADO

Se você usa tags para leitura humana, mantenha as duas: a tag descreve, o digest garante.

Se a imagem carrega a URL do banco de homologação, ela não pode ir para produção — e você volta ao build por ambiente. A separação:

  • Na imagem: código, dependências, runtime. Nada específico de ambiente.
  • Fora da imagem: variáveis, endpoints, limites, feature flags — em ConfigMap, parâmetros ou repositório de ambiente.
  • Nunca em lugar nenhum do artefato: segredos, que vêm do cofre em tempo de execução.
# overlays/prod/kustomization.yaml — a diferença entre ambientes é este arquivo
images:
- name: registry.exemplo.com/loja
digest: sha256:SUBSTITUA_PELO_DIGEST_VALIDADO
configMapGenerator:
- name: loja-config
literals: [LOG_LEVEL=info, TIMEOUT_MS=3000]

Um teste útil: se você não consegue explicar por que a imagem de homologação não serviria para produção, ela serve — e deve ser promovida.

Promoção é uma decisão, e decisões precisam de registro. Em GitOps, o próprio pull request no repositório de ambiente é a trilha:

Janela do terminal
# o job de promoção altera uma linha e abre o PR
yq -i '.images[0].digest = strenv(DIGEST)' overlays/prod/kustomization.yaml
git commit -am "promove loja ${GIT_SHA:0:7} para produção"
gh pr create --title "Promover loja para produção" \
--body "Digest: $DIGEST — aprovado em homologação na execução #${RUN_ID}"

O que o registro precisa responder depois: qual digest, quem aprovou, quando e com base em que evidência (testes verdes, canário estável). Ambientes protegidos do CI, com revisores obrigatórios, resolvem a parte de aprovação.

5. Verifique que o que subiu é o que foi aprovado

Seção intitulada “5. Verifique que o que subiu é o que foi aprovado”
Janela do terminal
kubectl get deployment loja -n prod \
-o jsonpath='{.spec.template.spec.containers[0].image}' # deve conter o digest aprovado
# se você assina as imagens, verifique também a assinatura antes de promover
cosign verify registry.exemplo.com/loja@sha256:SUBSTITUA \
--certificate-identity-regexp '^https://github.com/empresa/loja/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com

Melhor ainda: torne isso uma política de admissão, para o cluster recusar imagem por tag ou sem assinatura, em vez de depender de disciplina.

Sintoma Causa provável
Produção rodando versão diferente da testada Manifest com tag móvel em vez de digest
“Funciona em homologação” Configuração dentro da imagem, ou dados diferentes
Digest não encontrado no registry Retenção apagou a imagem — proteja as promovidas
Deploy sem mudança aparente O digest não mudou: o build foi reproduzível, e está certo
  • Um único build por commit, com digest registrado.
  • Todos os ambientes recebem o mesmo digest.
  • Configuração e segredos fora da imagem.
  • Promoção registrada com aprovador e evidência.
  • Verificação pós-deploy compara o digest em execução com o aprovado.
  • Política de admissão recusa tag móvel em produção.