microsoft / microsoft/finops-toolkit

FOCUS Prices: ""negotiated"" discount on SavingsPlan rows mirrors the on-demand meter - original SP MarketPrice/UnitPrice are dropped

Open
#2,198 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Skill: KQL Status: 🕵️‍♀️ Investigating Tool: FinOps hubs
Dominant language
PowerShell
Stars
603
Forks
249
Avg merge
7d 11h
Merged PRs (30d)
11

Description

Area: FinOps hubs / FOCUS price sheet transform (Prices_transform_v1_2(), Prices_v1_2())

Summary

On SavingsPlan rows, ListUnitPrice, ContractedUnitPrice, and x_BaseUnitPrice are all back-filled from the matching on-demand (Consumption) row, and the row's raw MarketPrice / UnitPrice are discarded (raw UnitPrice survives only as x_EffectiveUnitPrice). As a result the negotiated-discount columns on SP rows are not SP-specific — they just echo the underlying PayGo meter's discount, so you cannot compute a "negotiated discount per SP meter" from Prices_v1_2().

Where (Prices_transform_v1_2())

| extend ContractedUnitPrice = iff(x_SkuPriceType != 'SavingsPlan', UnitPrice, real(null))
| extend ListUnitPrice       = iff(x_SkuPriceType != 'SavingsPlan', MarketPrice, real(null))
...
// SP rows look up the Consumption twin by (MeterId, ProductId, SkuId, Tier, OfferId) - NOTE: no Term
| lookup kind=leftouter (Consumption | distinct tmp_SavingsPlanKey, ListUnitPrice, ContractedUnitPrice, x_BaseUnitPrice) on tmp_SavingsPlanKey
| extend ListUnitPrice       = coalesce(ListUnitPrice, ListUnitPrice1)
| extend ContractedUnitPrice = coalesce(ContractedUnitPrice, ContractedUnitPrice1)
| extend x_EffectiveUnitPrice = iff(x_SkuPriceType == 'SavingsPlan', UnitPrice, real(null))
| extend x_ContractedUnitPriceDiscount = ListUnitPrice - ContractedUnitPrice

Consequences

  1. x_ContractedUnitPriceDiscount(Percent) on an SP row = the on-demand meter's negotiated discount, not anything about the SP. Across a tenant it collapses to the flat PayGo EA/MCA discount (e.g. a uniform ~24.5% on compute), which is misleading when read as "SP negotiated discount."
  2. Because the back-fill key omits Term, ListUnitPrice / ContractedUnitPrice are identical for the 1-yr and 3-yr SP rows of the same meter; only x_EffectiveUnitPrice varies by term. So x_ContractedUnitPriceDiscountPercent is term-independent on SP rows.
  3. The original SP MarketPrice is not retained in any output column of Prices_v1_2().

Questions / requests

  • Is populating x_ContractedUnitPriceDiscount* on SP rows intended, given it only reflects the on-demand twin?
  • Could the transform preserve the raw SP MarketPrice (e.g. as x_SkuMarketPrice / x_SavingsPlanListPrice) so consumers can distinguish SP-native list pricing from the back-filled on-demand list price?
  • Suggest documenting that, for SP rows, negotiated-discount columns are inherited from the on-demand meter and only x_EffectiveUnitPriceDiscount* reflects the SP's own benefit.

Observed with toolkit v14, FOCUS 1.2.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with Prices_transform_v1_2() and Prices_v1_2(), then trace the SavingsPlan lookup key and the handling of MarketPrice and UnitPrice. Compare the 1-year and 3-year SavingsPlan rows with their Consumption twins; done means the selected SP pricing behavior is reflected consistently in output columns and documented as requested.

Written by the indexing model from the issue text.

Assessment

Tech stack
powershell
Domain
data-engineering
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.