Em 17 de julho, o AWS Cost Explorer mostrou a clientes faturas estimadas de milhões, bilhões e, em algumas capturas de tela, trilhões de dólares. Os números estavam errados, ninguém foi cobrado e a AWS corrigiu os dados em um dia. O detalhe que vale guardar: quem percebeu primeiro foram as pessoas com alertas de billing configurados. Este post é o guia básico para configurá-los com o aws_budgets_budget do Terraform, de um alerta simples de custo mensal até orçamentos de uso e acompanhamento de utilização de Savings Plan.

Qualquer pessoa que abriu o LinkedIn ou o X naquela manhã viu o mesmo feed: capturas de tela de estimativas de cobrança da AWS com mais dígitos do que alguns orçamentos nacionais. Um usuário que pagou US$ 0,19 no mês anterior viu uma estimativa de quase US$ 2,5 bilhões. Outros publicaram números de até US$ 2,5 trilhões.

O que aconteceu

À 1h33, horário do Pacífico, a AWS publicou no Health Dashboard que o Cost Explorer estava "reflecting inaccurate estimated billing data", ou seja, refletindo dados estimados de cobrança imprecisos. A causa raiz, nas palavras da AWS, foi "an issue with unit pricing within the estimated billing computation subsystem". Em resumo:

  • Os números eram estimativas, não uso ou cobranças reais.
  • Ninguém foi cobrado e nenhuma ação dos clientes foi necessária.
  • A AWS reprocessou os dados e os números voltaram ao normal em 18 de julho.

Aqui está a parte interessante: muita gente ficou sabendo do bug por um e-mail de billing threshold exceeded. Contas com alertas configurados detectaram a anomalia em minutos. Contas sem eles descobriram pelas redes sociais, ou nem descobriram.

Desta vez foi um alarme falso. Um NAT Gateway esquecido, uma Lambda presa em um loop de retry ou uma chave de acesso vazada produzem uma fatura bem real. Então esta é uma boa semana para configurar alertas de billing, e fazer isso com código em vez de cliques no console.

Por que IaC e não o console

Um alerta criado no console vive em uma conta e na memória de uma pessoa. Com Terraform:

  • Ele vive no controle de versão. Quem mudou o quê, e quando, fica visível.
  • Conta nova? Aplique o mesmo módulo e mantenha o padrão.
  • Uma mudança de limite é um pull request que passa por revisão.

O recurso que faz o trabalho é o aws_budgets_budget, que encapsula o AWS Budgets.

1. Um orçamento de custo mensal com alerta por e-mail

Um orçamento mensal de US$ 100 que envia e-mail quando o gasto real ultrapassa 80%:

resource "aws_budgets_budget" "monthly_cost" {
  name         = "monthly-cost-budget"
  budget_type  = "COST"
  limit_amount = "100"
  limit_unit   = "USD"
  time_unit    = "MONTHLY"

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 80
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["ops@example.com"]
  }
}

2. Aviso antecipado baseado em previsão

Com notification_type = "FORECASTED", a AWS avisa antes de o dinheiro ser gasto, quando a previsão de fim de mês está a caminho de estourar o orçamento. Combiná-la com uma notificação ACTUAL cobre as duas direções:

resource "aws_budgets_budget" "with_forecast" {
  name         = "monthly-cost-budget"
  budget_type  = "COST"
  limit_amount = "100"
  limit_unit   = "USD"
  time_unit    = "MONTHLY"

  # Avisa cedo se a previsão for exceder o orçamento
  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 100
    threshold_type             = "PERCENTAGE"
    notification_type          = "FORECASTED"
    subscriber_email_addresses = ["ops@example.com"]
  }

  # Avisa de novo quando o gasto real ultrapassa 90%
  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 90
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["ops@example.com"]
  }
}

3. Slack ou PagerDuty via SNS

E-mail se perde. Envie o alerta para um tópico SNS e conecte o tópico a um webhook do Slack ou ao PagerDuty:

resource "aws_sns_topic" "billing_alerts" {
  name = "billing-alerts"
}

resource "aws_budgets_budget" "sns_alert" {
  name         = "monthly-cost-budget-sns"
  budget_type  = "COST"
  limit_amount = "100"
  limit_unit   = "USD"
  time_unit    = "MONTHLY"

  notification {
    comparison_operator       = "GREATER_THAN"
    threshold                 = 80
    threshold_type            = "PERCENTAGE"
    notification_type         = "ACTUAL"
    subscriber_sns_topic_arns = [aws_sns_topic.billing_alerts.arn]
  }
}

O modo de falha aqui: a política do tópico precisa conceder SNS:Publish ao service principal budgets.amazonaws.com. Sem isso, o Budgets não consegue entregar e seus alertas somem em silêncio. Não há nenhum erro do lado do budget.

4. Um orçamento por serviço

Para acompanhar um único serviço, digamos EC2, adicione um cost_filter:

resource "aws_budgets_budget" "ec2_only" {
  name         = "ec2-monthly-budget"
  budget_type  = "COST"
  limit_amount = "50"
  limit_unit   = "USD"
  time_unit    = "MONTHLY"

  cost_filter {
    name   = "Service"
    values = ["Amazon Elastic Compute Cloud - Compute"]
  }

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 80
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["ops@example.com"]
  }
}

5. Um orçamento de uso: 3 GB de S3

FinOps não é só acompanhar dólares; acompanhar consumo faz parte do trabalho. Com budget_type = "USAGE" o orçamento é definido em unidades de uso em vez de moeda. Um orçamento que limita o armazenamento do S3 a 3 GB:

resource "aws_budgets_budget" "s3" {
  name         = "s3-3GB-limit"
  budget_type  = "USAGE"
  limit_amount = "3"
  limit_unit   = "GB"
  time_unit    = "MONTHLY"

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 80
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["ops@example.com"]
  }
}

Útil para projetos paralelos que querem ficar dentro do free tier, e para pegar o "por que esse bucket está crescendo" antes de virar uma linha na fatura.

6. Um orçamento de utilização de Savings Plan

A outra metade do FinOps: detectar gasto excessivo importa, mas não desperdiçar o desconto que você pagou antecipadamente também. Se você comprou um Savings Plan e a utilização está baixa, o compromisso está queimando dinheiro enquanto suas cargas de trabalho rodam on-demand em outro lugar. O tipo de orçamento SAVINGS_PLANS_UTILIZATION acompanha exatamente isso:

resource "aws_budgets_budget" "savings_plan_utilization" {
  name         = "savings-plan-utilization"
  budget_type  = "SAVINGS_PLANS_UTILIZATION"
  limit_amount = "100.0"
  limit_unit   = "PERCENTAGE"
  time_unit    = "MONTHLY"

  cost_types {
    include_credit             = false
    include_discount           = false
    include_other_subscription = false
    include_recurring          = false
    include_refund             = false
    include_subscription       = true
    include_support            = false
    include_tax                = false
    include_upfront            = false
    use_blended                = false
  }

  notification {
    comparison_operator        = "LESS_THAN"
    threshold                  = 90
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["finops@example.com"]
  }
}

Repare no operador invertido: comparison_operator = "LESS_THAN". O alerta dispara não quando o gasto sobe, mas quando a utilização cai abaixo de 90%. O mesmo padrão funciona para Reserved Instances com RI_UTILIZATION.

Concluindo

As capturas de tela trilionárias de 17 de julho eram um bug de exibição. Ninguém pagou esse dinheiro, e a AWS corrigiu os dados em um dia. A lição permanece de qualquer forma: uma anomalia na sua fatura deve chegar até você pelos seus próprios alertas, não pela sua timeline.

  • Defina um orçamento mensal com aws_budgets_budget.
  • Combine notificações FORECASTED e ACTUAL para aviso em dois níveis.
  • Encaminhe os alertas via SNS para um canal que o time realmente acompanha.
  • Complete o quadro com orçamentos de uso (3 GB de S3) e acompanhamento de utilização de Savings Plan.

Na próxima vez que "minha fatura da AWS explodiu" estiver em alta, você pode acompanhar tomando seu café. Leitura de contexto sobre o incidente: The Register e TechCrunch cobriram o caso enquanto acontecia.

Leia a seguir

Referências