Aller au contenu principal

Ressources

Coût facturé, coût amorti, crédits : réconcilier des montants AWS qui ne tombent jamais juste

Pourquoi Cost Explorer, l'export CUR 2.0 et la facture AWS ne tombent jamais juste : coût amorti, non combiné, crédits, et une méthode de réconciliation.

Par , publié le · 25 min de lecture

Base d'expérience : Construction d'une couche de réconciliation de coûts AWS multi-sources en lecture seule, généralisée sans donnée de compte client.

Relecture factuelle : Corentin Mas, le

Trois totaux existent pour le même mois et aucun ne tombe juste : Cost Explorer affiche un montant, la somme des lignes de l'export de coûts et d'usage en affiche un autre, la facture émise un troisième. L'écart n'est pas nécessairement une erreur de facturation : il peut venir simplement d'avoir additionné des grandeurs qui ne répondent pas à la même question. Tant qu'il reste non qualifié, une refacturation interne ne se défend pas et une décision d'engagement se prend sur une base instable.

La méthode est figée sur l'état de la documentation Amazon Web Services (AWS) vérifié le et sur trois artefacts nommés : l'export Cost and Usage Report 2.0 (CUR 2.0, table COST_AND_USAGE_REPORT d'AWS Data Exports), l'export FOCUS 1.2 du même service (FinOps Open Cost and Usage Specification, spécification inter-fournisseurs), et l'API Cost Explorer en version 2017-10-25. Définitions d'agrégats, noms de colonnes et canaux d'export évoluent séparément : comparez cette référence à l'export réellement configuré dans votre compte payeur, à sa granularité et à ses colonnes. L'objectif est informatif : construire une lecture contradictoire, pas certifier un montant.

Trois sources qui ne répondent pas à la même question

Une réconciliation commence souvent par une identité posée au tableau : facturé égale amorti plus net plus résiduel. Elle ne tient pas. Le coût amorti et le coût non combiné ne s'ajoutent pas : ce sont deux lectures de la même ligne, et les additionner compte deux fois le même engagement. Le coût net n'est pas non plus une composante, c'est la même lecture diminuée des remises. Les crédits sont des lignes appliquées après coup selon un ordre que l'usage ne détermine pas ; les taxes et les frais d'abonnement sont des types de lignes qui n'entrent pas dans tous les agrégats. Il n'existe donc pas une équation, mais un jeu de comparaisons valables chacune sur un périmètre et un instant donnés.

Cost Explorer est un service d'agrégation. Son API impose le paramètre Metrics, dont les valeurs valides sont AmortizedCost, BlendedCost, NetAmortizedCost, NetUnblendedCost, NormalizedUsageAmount, UnblendedCost et UsageQuantity. La granularité est MONTHLY, DAILY ou HOURLY, le regroupement accepte au plus deux entrées GroupBy, de type DIMENSION, TAG ou COST_CATEGORY dans n'importe quelle combinaison, et BillingViewArn désigne la vue de facturation interrogée. Deux captures du même mois qui diffèrent par la métrique, par la vue ou par le découpage ne sont pas comparables, même si l'écran affiche le même libellé « coût ».

L'export de coûts et d'usage répond à une autre question : quelle ligne, sur quelle ressource, à quel instant. Les colonnes bill_* portent la période et l'identité du document, line_item_* l'usage et son coût, reservation_* et savings_plan_* la vie des engagements, discount_* les remises. La clé de grain à l'intérieur d'une version donnée du rapport est le couple identity_line_item_id et identity_time_interval. La documentation précise que identity_line_item_id n'est pas stable d'une version de rapport à l'autre et ne permet pas d'identifier la même ligne entre deux exports : un rapprochement entre deux captures se fait sur des agrégats déclarés, jamais ligne à ligne sur cet identifiant. La granularité TIME_GRANULARITY se choisit entre HOURLY, DAILY et MONTHLY ; les données de ressources n'existent que si INCLUDE_RESOURCES a été activé.

L'export FOCUS 1.2 décrit la même facturation dans un vocabulaire normalisé, pensé pour être commun à plusieurs fournisseurs. Il sépare explicitement BilledCost, le montant porté à la facture, EffectiveCost, la lecture amortie des engagements, ContractedCost et ListCost, et il qualifie chaque ligne par ChargeCategory et ChargeClass. Cette séparation des noms est précisément ce que le CUR 2.0 laisse au lecteur : là où il faut choisir entre line_item_unblended_cost et reservation_effective_cost, FOCUS impose deux colonnes distinctes. Le recoupement entre les deux exports se vérifie néanmoins agrégat par agrégat : la correspondance entre une colonne FOCUS et une colonne CUR 2.0 n'est pas une identité de définition, et un total FOCUS ne remplace pas la comparaison avec la facture.

La facture, elle, dit ce qui est dû, à qui, pour quelle période close. La page Bills distingue un statut Pending, où les totaux sont des estimations fondées sur l'usage mesuré à ce jour, et un statut Issued, où la période est close et la facture générée. Elle expose les charges par fournisseur, les taxes par service et des factures fiscales distinctes que tous les fournisseurs n'émettent pas : pour un compte facturé par AWS EMEA SARL, le document fiscal se télécharge séparément du document commercial. Un utilisateur d'AWS Billing Conductor peut de plus y activer une vue pro forma, dont les montants ne sont pas ceux de la facture réelle.

Question à laquelle chaque source de coût AWS répond, son grain, sa fraîcheur et ce qu'elle ne prouve pas
SourceQuestion traitéeGrain et fraîcheurCe qu'elle ne prouve pas
Facture et page BillsCe qui est dû, à quelle entité, pour quelle période closeDocument par période ; statut Pending puis Issued ; page rafraîchie plusieurs fois par jourNi l'origine technique d'une ligne, ni la répartition par ressource ou par équipe
Export CUR 2.0Quelle ligne, sur quelle ressource, sous quel type de chargeLigne de facturation ; granularité choisie dans la configuration de table ; jusqu'à trois mises à jour cumulatives par jourQu'un montant est arrêté tant que bill_invoice_id est vide, ni qu'il ne sera plus révisé ensuite
Export FOCUS 1.2La même facturation dans un vocabulaire commun à plusieurs fournisseursColonnes normalisées dont BilledCost, EffectiveCost, ContractedCost, ListCost, ChargeCategory et ChargeClassQue ses colonnes se recoupent ligne à ligne avec celles du CUR 2.0 sans vérification
API Cost ExplorerUn agrégat exploré par métrique, période et au plus deux entrées de regroupementGranularité mensuelle ou quotidienne ; granularité horaire sur activation explicite, limitée aux quatorze derniers jours et facturée à l'enregistrement d'usageQu'un total vaut pour une autre métrique, une autre vue de facturation ou un autre découpage

Coût non combiné et coût amorti : deux lectures d'un même engagement

Un même agrégat porte trois noms selon l'endroit où on le lit : la console Cost Explorer en français, la métrique de l'API et la colonne de l'export. La table ci-dessous sert de dictionnaire pour la suite ; les libellés français sont ceux de la documentation AWS.

Correspondance entre le libellé français de la console Cost Explorer, la métrique de l'API et la colonne principale de l'export CUR 2.0
Console Cost ExplorerMétrique de l'APIColonne CUR 2.0
Coûts non combinésUnblendedCostline_item_unblended_cost
Coûts amortisAmortizedCostPas de colonne unique : reconstruction à partir de reservation_effective_cost et savings_plan_savings_plan_effective_cost
Coûts combinésBlendedCostline_item_blended_cost
Coûts nets non combinésNetUnblendedCostline_item_net_unblended_cost, présente seulement si une remise s'applique
Coûts amortis netsNetAmortizedCostreservation_net_effective_cost et savings_plan_net_savings_plan_effective_cost

Le coût non combiné (unblended cost, line_item_unblended_cost) est le produit du taux non combiné par la quantité d'usage, tel qu'il est facturé à l'instant de l'usage. Une de ses propriétés, peu intuitive, est pourtant écrite noir sur blanc : pour une ligne couverte par une instance réservée (Reserved Instance, RI), le taux non combiné vaut zéro. La dépense vit sur deux autres types de ligne. Fee porte le paiement initial d'une réservation All Upfront ou Partial Upfront. RIFee porte la redevance mensuelle récurrente, ajoutée au jour de l'achat puis au premier jour de chaque période, et reste présent même à zéro afin de transporter reservation_amortized_upfront_fee_for_billing_period. Un total non combiné filtré sur les seules lignes d'usage perd donc tout le coût d'une réservation.

Le coût amorti (amortized cost) répond à la question inverse : combien cet engagement a-t-il coûté pour l'heure ou le mois observés ? Sur une ligne DiscountedUsage, reservation_amortized_upfront_cost_for_usage porte la part initiale rapportée au temps d'usage, et reservation_effective_cost est défini comme la somme de cette part amortie et de la redevance récurrente pour l'usage. Sur une ligne RIFee, reservation_unused_recurring_fee et reservation_unused_amortized_upfront_fee_for_billing_period isolent ce qui a été payé sans être consommé. Une réservation inutilisée n'existe que dans ces colonnes.

Les Savings Plans déclinent la même structure avec un piège supplémentaire. L'achat produit une ligne SavingsPlanUpfrontFee pour un plan All Upfront ou Partial Upfront seulement, et une ligne SavingsPlanRecurringFee qui porte la charge récurrente horaire des plans No Upfront et Partial Upfront : cette dernière reste émise, à charge nulle, pour un plan All Upfront, afin de transporter savings_plan_amortized_upfront_commitment_for_billing_period, savings_plan_total_commitment_to_date et savings_plan_used_commitment. L'usage couvert produit une ligne SavingsPlanCoveredUsage, dont le coût non combiné vaut la charge à la demande qu'on aurait payée sans le plan, et une ligne SavingsPlanNegation négative qui l'annule. Les négations sont regroupées à l'heure par identifiant de plan, opération, type d'usage et zone de disponibilité : une seule peut correspondre à plusieurs lignes d'usage couvert. Sommer l'usage couvert sans les négations gonfle le total du montant de la remise : c'est une cause directe, et mécanique, d'un export supérieur au montant facturé.

La lecture amortie d'un Savings Plan passe par savings_plan_savings_plan_effective_cost, défini comme la proportion de l'engagement mensuel, part initiale et part récurrente comprises, allouée à chaque ligne d'usage. Reste l'engagement non consommé, qui se lit comme la différence entre savings_plan_total_commitment_to_date et savings_plan_used_commitment, deux colonnes renseignées sur les seules lignes SavingsPlanRecurringFee, à raison d'une par heure et par plan. Aucune colonne ne le nomme comme reservation_unused_recurring_fee côté réservations : c'est une asymétrie de nommage, et une ligne de réconciliation à filtrer explicitement sur line_item_line_item_type = 'SavingsPlanRecurringFee' avant toute somme.

Les lignes qu'un Savings Plan produit dans l'export, et les lectures qu'elles portent

Quatre types de ligne portent un Savings Plan dans l'export CUR 2.0. La lecture non combinée les somme toutes, négations incluses ; la lecture amortie et l'engagement non consommé se lisent dans des colonnes dédiées, jamais additionnées à la première.

Schéma défilable horizontalement ; sa version textuelle complète suit.

Lire le schéma sous forme textuelle
  1. SavingsPlanRecurringFee. Émise chaque heure et par plan ; charge nulle pour un plan All Upfront. Elle alimente la lecture non combinée et porte les colonnes d'engagement à date et d'engagement consommé.
  2. SavingsPlanUpfrontFee. Émise à l'achat d'un plan All Upfront ou Partial Upfront seulement ; elle entre dans la lecture non combinée.
  3. SavingsPlanCoveredUsage. Porte l'usage couvert au tarif à la demande ; elle entre dans la lecture non combinée et sa part d'engagement se lit dans savings_plan_savings_plan_effective_cost, la lecture amortie.
  4. SavingsPlanNegation. Montant négatif qui annule l'usage couvert dans la lecture non combinée. L'oublier fait dépasser la facture du montant de la remise.
  5. Engagement non consommé. Engagement à date moins engagement consommé, calculé sur les seules lignes SavingsPlanRecurringFee.
Modèle explicatif, sans donnée client, d'après les pages de colonnes et de types de ligne Savings Plans de la documentation AWS citées en fin d'article.

Le coût combiné (blended cost), enfin, ne sert à aucune réconciliation avec une facture. Dans une organisation gérée par AWS Organizations, les paliers tarifaires sont calculés sur l'usage agrégé de tous les comptes, les comptes membres n'atteignent pas les seuils individuellement, et le taux combiné redistribue le tarif moyen. line_item_blended_cost est de plus vide pour les lignes de type Discount : une somme de coûts combinés est structurellement incomplète dès qu'une remise existe.

Crédits, remises et taxes : ce qui casse l'égalité comptable

Les métriques nettes de Cost Explorer, NetUnblendedCost et NetAmortizedCost, et leurs équivalents dans l'export, line_item_net_unblended_cost, reservation_net_effective_cost et savings_plan_net_savings_plan_effective_cost, décrivent la même lecture après remises négociées ; discount_total_discount et discount_bundled_discount en portent le détail. Ces colonnes ne sont incluses dans l'export que si une remise s'applique à la période de facturation : sur un compte sans accord de remise, elles sont absentes du schéma, pas seulement vides. Le contrôle préalable porte donc sur l'existence de la colonne, et une requête qui la somme échoue en erreur de colonne inconnue au lieu de renvoyer des valeurs nulles.

Les crédits AWS obéissent à une logique différente, et ce sont eux qui rendent l'identité initiale indéfendable. Ils sont appliqués automatiquement jusqu'à épuisement ou expiration, sans sélection du client. Sur un compte isolé, l'ordre documenté est : le crédit qui expire le plus tôt, puis celui qui couvre le moins de services éligibles, puis le plus ancien. Dans une organisation où le partage est actif : le compte propriétaire est d'abord couvert pour ses charges de service, puis le crédit va au compte membre le plus dépensier ; dans ce compte, les charges sont regroupées selon des champs de facturation et le crédit s'applique d'abord au groupe le plus élevé, puis, dans ce groupe, à la charge la plus élevée.

Cette allocation n'est ni proportionnelle à l'usage, ni stable, ni reconstructible depuis les quantités consommées. Un compte peut recevoir la totalité d'un crédit un mois et rien le suivant, sans qu'aucune configuration n'ait changé, parce qu'il n'est plus le plus gros consommateur. Le partage se désactive par le compte payeur dans les préférences de facturation, et les factures sont calculées avec la préférence active le dernier jour du mois : un basculement en cours de mois modifie rétroactivement tout le mois. Une refacturation calculée au prorata des crédits ne reflète donc pas l'allocation réellement appliquée ; seule la lecture directe des lignes de type Credit restitue le montant imputé à chaque compte. Le choix de la règle de refacturation relève de vos fonctions comptables.

Les taxes forment un troisième registre. Elles apparaissent en type de ligne Tax, qualifiées par line_item_tax_type, et la console les expose par service sous forme d'un triplet : montant hors taxes, montant de la taxe, montant toutes taxes comprises. L'entité qui facture se lit dans bill_billing_entity et bill_invoicing_entity, ou dans les dimensions BILLING_ENTITY, INVOICING_ENTITY et LEGAL_ENTITY_NAME de Cost Explorer. La valeur AWS Marketplace désigne une entité distincte de celle qui vend les services AWS : sans déclaration explicite, deux lectures comparent deux périmètres. Une somme qui mélange AWS Marketplace et les services vendus par l'entité AWS agrège deux périmètres de facturation, pas deux parts d'un même total.

Granularité, fraîcheur et révisions rétroactives

La période ne suffit pas à désigner un document. bill_bill_type prend trois valeurs documentées : Anniversary pour l'usage du mois, Purchase pour les frais de service initiaux, Refund pour les remboursements ; un achat All Upfront génère une facture immédiate, distincte de la facture mensuelle. Les frais de support Developer, Business et Enterprise sont calculés sur les charges d'usage finales : selon la page « What are AWS Cost and Usage Reports ? », ils n'apparaissent dans l'export du mois écoulé que le 6 ou le 7 du mois suivant. Une réconciliation lancée le 3 ne peut pas les voir.

Un écart mesuré entre deux sources capturées à deux instants différents n'est pas un écart, c'est un décalage. L'export est mis à jour jusqu'à trois fois par jour, et chaque mise à jour est cumulative : elle contient l'ensemble des données du mois à date. Les rapports produits en cours de mois sont explicitement qualifiés d'estimations, et les services AWS ne remontent pas leur usage au même moment. AWS n'arrête les charges d'usage qu'après la clôture du mois, au moment où la facture est émise ; tout ce qui est lu avant reste une estimation.

Le marqueur de finalisation est une colonne, pas une date : bill_invoice_id reste vide tant que le rapport n'est pas final, et une ligne portant un identifiant de facture est arrêtée à la date de finalisation, ce qui n'est pas la même chose qu'immuable. Cette colonne sépare, dans un même fichier, ce qui est arrêté de ce qui ne l'est pas. La documentation ajoute qu'AWS peut mettre à jour des rapports déjà finalisés si des remboursements, des crédits ou des frais de support sont appliqués après coup : un fichier final n'est pas figé.

Le mode de livraison conditionne votre capacité à rejouer une lecture passée. Dans la configuration de destination Amazon Simple Storage Service (S3), l'option d'écrasement détermine si chaque livraison remplace le rapport précédent ou en crée un nouveau. Un export en écrasement ne conserve aucune trace de la veille, sauf versionnement du compartiment : sans version antérieure, affirmer qu'un montant a changé n'est pas vérifiable. La granularité, elle, fait partie de la configuration de table. Depuis l'annonce de juin 2026, cette configuration se met à jour depuis la console ou le kit de développement sans supprimer ni recréer l'export ; la nouvelle préférence s'applique à partir de la livraison programmée suivante et ne réécrit pas l'historique déjà livré. Une série temporelle qui traverse un changement de granularité comporte donc une rupture de définition, à déclarer avec sa date.

Côté Cost Explorer, les limites se lisent dans l'API. GetCostAndUsageWithResources, qui donne le détail par ressource, exige une période comprise dans les quatorze derniers jours, impose un filtre ou un regroupement sur l'identifiant de ressource, exige en outre l'expression de filtre documentée SERVICE = "Amazon Elastic Compute Cloud - Compute", réserve la granularité horaire aux ressources Amazon Elastic Compute Cloud (EC2) et exige une activation explicite. Cette activation horaire se règle dans les préférences de gestion des coûts du compte payeur, ne couvre que les quatorze derniers jours et se facture à l'enregistrement d'usage : une réconciliation horaire planifiée sur une fenêtre plus longue n'est pas réalisable par cette voie. GetSavingsPlansUtilization exige une date de début dans les treize derniers mois et n'accepte que les granularités quotidienne et mensuelle. GetCostForecast renvoie une moyenne ponctuelle, encadrée d'un intervalle de prédiction seulement si un niveau de confiance est demandé.

La page Bills, enfin, est mise à jour plusieurs fois par jour. Trois sources qui bougent à trois cadences imposent une seule et même discipline : horodater chaque capture, conserver le fichier ou la réponse d'API telle quelle, et n'autoriser une comparaison qu'entre captures dont les instants sont déclarés.

Construire une réconciliation qui expose son écart

La grille remplace l'identité fausse par un tableau de comparaisons, chacune tenant sur une seule métrique, un seul périmètre, une seule période et un seul instant de capture. Les requêtes ci-dessous sont en lecture seule et ne concluent rien : elles produisent les nombres qu'une conclusion devra expliquer.

Ordre d'exécution d'une réconciliation multi-sources

Sept étapes bornées : déclarer le périmètre, établir l'état du document, reconstruire séparément la lecture non combinée et la lecture amortie, isoler les registres non proportionnels, confronter à l'agrégat, publier le résiduel signé.

Schéma défilable horizontalement ; sa version textuelle complète suit.

Lire le schéma sous forme textuelle
  1. Déclarer le périmètre. Compte payeur, comptes membres, vue de facturation, devise lue dans line_item_currency_code, période bornée par bill_billing_period_start_date et non par la date d'usage.
  2. Établir l'état du document. Relever le statut Pending ou Issued, compter les lignes dont bill_invoice_id est vide ou nul. Une période non close se mesure en convergence, pas en écart.
  3. Reconstruire la lecture non combinée. Sommer line_item_unblended_cost par line_item_line_item_type, négations de Savings Plans incluses. Ce total est la seule base de comparaison avec le montant facturé.
  4. Construire la lecture amortie à part. Utiliser reservation_effective_cost, savings_plan_savings_plan_effective_cost et les colonnes d'engagement non consommé. Ne jamais additionner cette lecture à la précédente.
  5. Isoler les registres non proportionnels. Crédits, remboursements, taxes et frais d'abonnement forment des lignes propres, jamais un pourcentage appliqué à l'usage.
  6. Confronter à Cost Explorer. Interroger la même période avec UnblendedCost puis AmortizedCost, sur la même vue de facturation, et vérifier que chaque lecture retrouve son homologue dans l'export.
  7. Publier le résiduel signé. La part inexpliquée sort du calcul et entre dans le tableau, en dernière ligne, avant toute décision d'engagement.

L'ordre ne convertit jamais une lecture amortie en complément d'une lecture non combinée : les étapes 3 et 4 restent deux totaux distincts, comparés chacun à son homologue et jamais l'un à l'autre. L'enchaînement ne prouve pas non plus qu'un écart résiduel soit une erreur : il garantit seulement que chaque comparaison porte sur une métrique, un périmètre et deux instants déclarés.

Modèle explicatif, sans donnée client. L'ordre décrit une méthode de lecture, pas une hiérarchie contractuelle : le document de facturation de référence reste la facture émise.

Total non combiné par type de ligne, et état de finalisation

-- Lecture seule. Remplacer la base et la table par celles de votre export CUR 2.0.
-- La période est bornée par la période de facturation, jamais par la date d'usage.
-- line_item_net_unblended_cost n'existe dans le schéma que si une remise s'applique
-- à la période : vérifier la colonne avant d'exécuter, et retirer la ligne sinon.
SELECT
  bill_bill_type,
  bill_billing_entity,
  bill_invoicing_entity,
  line_item_line_item_type,
  line_item_currency_code,
  count(*)                                                   AS lignes,
  count_if(bill_invoice_id IS NULL OR bill_invoice_id = '')   AS lignes_non_finalisees,
  count(DISTINCT bill_invoice_id)                            AS identifiants_facture,
  sum(line_item_unblended_cost)                              AS cout_non_combine,
  sum(line_item_net_unblended_cost)                          AS cout_net_non_combine
FROM cur2.cur2
WHERE bill_billing_period_start_date = TIMESTAMP '2026-08-01 00:00:00'
GROUP BY 1, 2, 3, 4, 5
ORDER BY 4;

Le résultat est un tableau par type de ligne, pas un total unique. Il rend visibles les trois pièges décrits plus haut : la présence ou l'absence de SavingsPlanNegation, la part de lignes sans identifiant de facture, et une entité de facturation non déclarée dans le périmètre. Le test de finalisation couvre les deux formes de vide, la chaîne nulle et la valeur absente, car un export au format colonnaire livre indifféremment l'une ou l'autre. Si lignes_non_finalisees n'est pas nul, la comparaison avec la facture close est prématurée : le rapport porte alors le nombre de lignes non finalisées à la place d'un écart.

Lecture amortie, construite séparément

-- Reconstruction à valider contre la métrique AmortizedCost de Cost Explorer,
-- sur exactement le même périmètre et la même période. AWS ne publie pas
-- cette expression comme formule de référence : c'est une hypothèse de lecture.
SELECT
  line_item_line_item_type,
  sum(reservation_effective_cost)                AS ri_cout_effectif,
  sum(savings_plan_savings_plan_effective_cost)  AS sp_cout_effectif,
  sum(reservation_unused_amortized_upfront_fee_for_billing_period)
                                                 AS ri_initial_non_consomme,
  sum(reservation_unused_recurring_fee)          AS ri_recurrent_non_consomme,
  -- Colonnes renseignées sur les seules lignes SavingsPlanRecurringFee :
  -- les sommer sur un autre type de ligne double compte l'engagement.
  sum(CASE WHEN line_item_line_item_type = 'SavingsPlanRecurringFee'
           THEN savings_plan_total_commitment_to_date END)  AS sp_engagement_a_date,
  sum(CASE WHEN line_item_line_item_type = 'SavingsPlanRecurringFee'
           THEN savings_plan_used_commitment END)           AS sp_engagement_consomme
FROM cur2.cur2
WHERE bill_billing_period_start_date = TIMESTAMP '2026-08-01 00:00:00'
GROUP BY 1
ORDER BY 1;

Cette requête est délibérément séparée de la première : aucune de ses colonnes ne doit être additionnée à un coût non combiné. La différence entre sp_engagement_a_date et sp_engagement_consomme ne doit pas non plus être présentée comme un engagement perdu tant que la correspondance avec AmortizedCost n'a pas été établie sur le même mois. C'est le point où la documentation nomme le calcul sans nommer la colonne : une réconciliation honnête signale la lacune au lieu de la combler par une formule supposée.

Écart signé entre deux captures déclarées

-- La comparaison ne vaut que si les deux instants sont déclarés. Les montants de
-- reference sont relevés à la main : facture émise pour la période close, et
-- réponse GetCostAndUsage en UnblendedCost sur la même vue de facturation.
WITH reference AS (
  SELECT * FROM (VALUES
    ('facture emise',              DECIMAL '0.00', TIMESTAMP '2026-09-08 09:00:00'),
    ('cost_explorer_unblended',    DECIMAL '0.00', TIMESTAMP '2026-09-08 09:05:00')
  ) AS t(source_reference, montant_reference, instant_reference)
),
capture_export AS (
  SELECT
    sum(line_item_unblended_cost)                             AS total_non_combine,
    count_if(bill_invoice_id IS NULL OR bill_invoice_id = '') AS lignes_non_finalisees,
    max(identity_time_interval)                               AS dernier_intervalle
  FROM cur2.cur2
  WHERE bill_billing_period_start_date = TIMESTAMP '2026-08-01 00:00:00'
    AND bill_billing_entity = 'AWS'
)
SELECT
  r.source_reference,
  e.total_non_combine,
  r.montant_reference,
  e.total_non_combine - r.montant_reference AS ecart_signe,
  e.lignes_non_finalisees,
  e.dernier_intervalle,
  r.instant_reference
FROM capture_export e CROSS JOIN reference r;

La sortie est une ligne par comparaison, avec son montant, son signe et les deux instants qui la rendent recevable. Le filtre sur bill_billing_entity matérialise le périmètre déclaré : le retirer change la comparaison, pas seulement le résultat. Le signe n'est pas décoratif. Un écart positif signifie que l'export dépasse la référence, ce que produisent notamment des négations de Savings Plans manquantes ou un périmètre plus large que celui de la facture ; un écart négatif signale plutôt des lignes arrivées après la capture, des crédits appliqués entre les deux relevés ou des frais de support encore absents.

Grille des comparaisons recevables : métrique comparée, périmètre déclaré, instants des deux captures et hypothèse à instruire en cas d'écart
ComparaisonGrandeurs confrontéesPérimètre à déclarerInstants comparésHypothèse nommée si écart
Export contre facturesum(line_item_unblended_cost) contre le montant de la facture émiseComptes inclus, bill_billing_entity, devise, période de facturationDernière livraison de l'export ; date d'émission de la factureNégations absentes, entité Marketplace incluse à tort, frais de support pas encore livrés
Export contre agrégat brutsum(line_item_unblended_cost) contre UnblendedCostMême BillingViewArn, mêmes comptes, mêmes bornes de périodeHorodatage de la livraison ; horodatage de l'appel d'APIVue de facturation différente, période bornée sur la date d'usage, capture antérieure à une mise à jour cumulative
Export contre agrégat amortireservation_effective_cost et savings_plan_savings_plan_effective_cost contre AmortizedCostMêmes comptes ; lignes hors engagement traitées explicitementHorodatage de la livraison ; horodatage de l'appel d'APIHypothèse de reconstruction non validée, engagement non consommé compté deux fois
CréditsLignes de type Credit contre les crédits portés à la factureCompte propriétaire, état du partage, préférence active le dernier jour du moisLivraison de l'export ; facture closeBasculement de préférence en cours de mois, crédit expiré entre les deux relevés
Engagement non consommésavings_plan_total_commitment_to_date moins savings_plan_used_commitment contre GetSavingsPlansUtilizationLignes SavingsPlanRecurringFee seules ; granularité quotidienne ou mensuelleLivraison de l'export ; horodatage de l'appel d'APISomme étendue à d'autres types de ligne, période de début au-delà de treize mois

Cette grille tient à une règle : le résiduel est une ligne du rapport, pas une gêne. Il porte un montant signé, la métrique sur laquelle il a été mesuré, l'instant des deux captures comparées, une hypothèse nommée et le contrôle qui la départagera. Un résiduel réparti au prorata réapparaît le mois suivant, plus grand ; un résiduel publié se réduit à mesure que les hypothèses sont testées. Un écart compensé en silence n'est pas un écart traité : il redevient une hypothèse non instruite à la période suivante.

Sources officielles et limites de lecture

Les mécanismes ci-dessus ont été vérifiés le contre les pages officielles suivantes, à relire avant toute décision : définitions d'agrégats, noms de colonnes et options d'export évoluent indépendamment.

Cette lecture n'établit pas le montant que vous devez : le document de facturation de référence reste la facture émise. Elle n'établit pas non plus qu'un écart soit une erreur de facturation, ni qu'un engagement soit mal dimensionné ; elle produit des nombres et des hypothèses à instruire. Les cadences de mise à jour, les règles d'application des crédits, les fenêtres d'API et les définitions d'agrégats cités ici sont des faits datés, à revérifier sur ces mêmes pages avant toute décision d'engagement ou de refacturation. La méthode vaut enfin pour les artefacts nommés en introduction : si votre export utilise une autre version de format, une autre granularité ou un autre mode de livraison, la documentation de cette version devient prioritaire et la grille doit être reconstruite. Pour appliquer cette grille à votre compte payeur, voir l'audit FinOps.

Périmètre du droit

CTN Solutions formule des avis techniques et organisationnels, jamais un avis juridique ni un audit légal. Le conseil juridique relève d'un avocat (loi n° 71-1130) ; la certification des comptes d'un commissaire aux comptes.

Chiffrage fondé sur vos données

CTN Solutions ne publie aucun pourcentage d'économie type : les écarts dépendent des usages réels et des contrats en cours.

Vérifié le

Parlons de votre contexte.

Cet article expose une pratique générale ; votre situation a ses propres contraintes. Décrivez-la, nous répondons avec un périmètre.

Ouvrir le formulaire