Le 17 juillet, AWS Cost Explorer a affiché à des clients des factures estimées en millions, en milliards, et sur quelques captures d'écran en billions de dollars. Les chiffres étaient faux, personne n'a été facturé, et AWS a corrigé les données en moins d'une journée. Le détail qui mérite d'être retenu : les premiers à remarquer l'anomalie étaient ceux qui avaient configuré des alertes de facturation. Ce billet couvre les bases de leur mise en place avec la ressource aws_budgets_budget de Terraform, de la simple alerte de coût mensuel aux budgets d'usage et au suivi d'utilisation d'un Savings Plan.

Quiconque a ouvert LinkedIn ou X ce matin-là a vu le même fil : des captures d'écran d'estimations de facturation AWS avec plus de chiffres que certains budgets nationaux. Un utilisateur qui avait payé 0,19 $ le mois précédent a vu une estimation de près de 2,5 milliards de dollars. D'autres ont publié des montants allant jusqu'à 2 500 milliards.

Ce qui s'est passé

À 1 h 33, heure du Pacifique, AWS a indiqué sur le Health Dashboard que Cost Explorer était "reflecting inaccurate estimated billing data", autrement dit qu'il affichait des données de facturation estimées inexactes. La cause racine, dans les termes d'AWS, était "an issue with unit pricing within the estimated billing computation subsystem", un problème de prix unitaires dans le sous-système de calcul des estimations. En bref :

  • Les chiffres étaient des estimations, pas de l'usage ni des montants réellement facturés.
  • Personne n'a été facturé, et aucune action n'était requise côté client.
  • AWS a réinjecté les données corrigées, et les chiffres étaient revenus à la normale le 18 juillet.

Voici la partie intéressante : beaucoup de gens ont appris l'existence du bug par un e-mail de dépassement de seuil de facturation. Les comptes avec des alertes configurées ont repéré l'anomalie en quelques minutes. Ceux qui n'en avaient pas l'ont découverte sur les réseaux sociaux, ou pas du tout.

Cette fois, c'était une fausse alerte. Une NAT Gateway oubliée, une Lambda coincée dans une boucle de retry ou une clé d'accès qui a fuité produisent une facture bien réelle. C'est donc une bonne semaine pour mettre en place des alertes de facturation, et pour le faire avec du code plutôt qu'avec des clics dans la console.

Pourquoi l'IaC et pas la console

Une alerte créée dans la console vit dans un seul compte et dans la mémoire d'une seule personne. Avec Terraform :

  • Elle vit dans le contrôle de version. Qui a changé quoi, et quand, reste visible.
  • Nouveau compte ? Appliquez le même module et conservez le standard.
  • Un changement de seuil est une pull request qui passe en revue.

La ressource qui fait le travail est aws_budgets_budget, qui encapsule AWS Budgets.

1. Un budget de coût mensuel avec une alerte par e-mail

Un budget mensuel de 100 $ qui vous envoie un e-mail quand la dépense réelle franchit 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. Alerte précoce basée sur la prévision

Avec notification_type = "FORECASTED", AWS vous prévient avant que l'argent ne soit dépensé, quand la prévision de fin de mois est en passe de faire exploser le budget. L'associer à une notification ACTUAL couvre les deux directions :

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

  # Alerter tôt si la prévision dépasse le budget
  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 100
    threshold_type             = "PERCENTAGE"
    notification_type          = "FORECASTED"
    subscriber_email_addresses = ["ops@example.com"]
  }

  # Alerter à nouveau quand la dépense réelle franchit 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

Les e-mails se perdent. Envoyez plutôt l'alerte vers un topic SNS, puis reliez le topic à un webhook Slack ou à 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]
  }
}

Le piège ici : la politique du topic doit accorder SNS:Publish au service principal budgets.amazonaws.com. Sans cela, Budgets ne peut pas livrer les notifications et vos alertes disparaissent en silence. Aucune erreur n'apparaît côté budget.

4. Un budget par service

Pour surveiller un seul service, disons EC2, ajoutez un 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. Un budget d'usage : 3 Go de S3

Le FinOps ne se limite pas au suivi des dollars ; suivre la consommation fait partie du travail. Avec budget_type = "USAGE", le budget est défini en unités d'usage plutôt qu'en devise. Un budget qui plafonne le stockage S3 à 3 Go :

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"]
  }
}

Utile pour les projets personnels qui veulent rester dans le free tier, et pour attraper le "pourquoi ce bucket grossit-il" avant que cela ne devienne une ligne sur la facture.

6. Un budget d'utilisation de Savings Plan

L'autre moitié du FinOps : détecter les dépassements compte, mais ne pas gaspiller la remise que vous avez prépayée compte tout autant. Si vous avez acheté un Savings Plan et que votre utilisation est faible, l'engagement brûle de l'argent pendant que vos charges de travail tournent en on-demand ailleurs. Le type de budget SAVINGS_PLANS_UTILIZATION suit exactement cela :

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"]
  }
}

Notez l'opérateur inversé : comparison_operator = "LESS_THAN". L'alerte se déclenche non pas quand la dépense monte, mais quand l'utilisation passe sous 90 %. Le même schéma fonctionne pour les Reserved Instances avec RI_UTILIZATION.

Pour conclure

Les captures d'écran à mille milliards du 17 juillet étaient un bug d'affichage. Personne n'a payé cet argent, et AWS a corrigé les données en moins d'une journée. La leçon reste valable : une anomalie sur votre facture doit vous parvenir par vos propres alertes, pas par votre fil d'actualité.

  • Définissez un budget mensuel avec aws_budgets_budget.
  • Associez des notifications FORECASTED et ACTUAL pour un avertissement à deux niveaux.
  • Routez les alertes via SNS vers un canal que votre équipe regarde vraiment.
  • Complétez le tableau avec des budgets d'usage (3 Go de S3) et le suivi d'utilisation des Savings Plans.

La prochaine fois que "ma facture AWS a explosé" fera le tour des réseaux, vous pourrez suivre cela avec votre café. Pour le contexte sur l'incident : The Register et TechCrunch l'ont couvert en direct.

À lire ensuite

Références