Pular para o conteúdo

Mostrar o custo da mudança no pull request

Intermediário12 min de leituraiac

Infraestrutura tem uma dimensão que código de aplicação não tem: cada linha aprovada vira uma fatura mensal. Descobrir isso 30 dias depois é caro e desconfortável. Este guia traz o número para a revisão, onde a decisão ainda pode mudar.

Janela do terminal
terraform init -input=false
terraform plan -out=plano.bin
terraform show -json plano.bin > plano.json

O JSON do plano é o insumo de tudo que vem a seguir — estimativa de custo, política e verificações próprias.

Janela do terminal
infracost breakdown --path plano.json --format table
infracost diff --path plano.json --format json --out-file custo.json

A saída mostra o custo mensal por recurso e o delta em relação ao estado atual. Entenda os limites antes de confiar cegamente: a estimativa usa preço de tabela e não enxerga tráfego, requisições, armazenamento que cresce, nem descontos e compromissos que você já tem. Ela é ótima para “isto custa dezenas ou milhares?” e imprecisa para centavos.

name: custo
on: pull_request
jobs:
estimar:
runs-on: ubuntu-latest
permissions: { pull-requests: write, id-token: write, contents: read }
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: |
terraform init -input=false
terraform plan -out=plano.bin
terraform show -json plano.bin > plano.json
- uses: infracost/actions/setup@v3
with: { api-key: ${{ secrets.INFRACOST_API_KEY }} }
- run: infracost diff --path plano.json --format json --out-file custo.json
- uses: infracost/actions/comment@v3
with:
path: custo.json
behavior: update # atualiza o mesmo comentário a cada push

behavior: update evita o pior efeito colateral desse tipo de automação: dez comentários no mesmo PR, que treinam o time a ignorar todos.

Bloquear por qualquer aumento é inviável — infraestrutura nova sempre custa mais. O que funciona é exigir uma segunda aprovação acima de um limite.

Janela do terminal
DELTA=$(jq '.diffTotalMonthlyCost | tonumber' custo.json)
LIMITE=500
if (( $(echo "$DELTA > $LIMITE" | bc -l) )); then
echo "Aumento de US$ $DELTA/mês acima do limite de US$ $LIMITE."
gh pr edit "$PR" --add-label "custo-alto" --add-reviewer empresa/plataforma
exit 1
fi

Combine com política, para o caso que nenhum limite pega:

# um recurso caro específico exige justificativa explícita
deny contains msg if {
r := input.resource_changes[_]
r.type == "aws_nat_gateway"
r.change.actions[_] == "create"
not input.variables.justificativa_nat
msg := sprintf("%s criado sem justificativa de NAT", [r.address])
}

O objetivo não é impedir gasto: é tornar a decisão consciente. Duas perguntas que o comentário de custo destrava na revisão:

  • “US$ 380/mês em NAT Gateway — dá para usar endpoint privado aqui?”
  • “Este ambiente de teste precisa ficar ligado à noite?”

E ligue o custo à unidade de negócio quando o valor for relevante: US$ 400/mês pode ser barato ou caríssimo dependendo de quantos pedidos ele atende — veja unit economics.

Sintoma Causa provável
Estimativa muito abaixo da fatura Tráfego e requisições não são estimados; use infracost-usage.yml
Comentário não aparece Falta permissions: pull-requests: write
Falha em PR de fork Segredo não é exposto a forks — rode com pull_request_target e cuidado, ou pule
Custo muda sem mudança de código Preço de tabela atualizado, ou plano diferente por drift
Time ignora o comentário Excesso de ruído: comente só quando houver delta relevante
  • Plano exportado em JSON no CI.
  • Estimativa comentada no PR, atualizando o mesmo comentário.
  • Limite definido que exige revisão adicional.
  • Política para recursos caros específicos.
  • Limites da estimativa comunicados ao time.
  • Custo revisado junto do valor entregue, não isolado.