-
Notifications
You must be signed in to change notification settings - Fork 249
feat(sre-agent): add FinOps recipe content #2168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
8948b1a
feat(queries): add FinOps KPI query catalog
87443aa
feat(sre-agent): add FinOps recipe content
6a01421
feat(sre-agent): add deployable Azure template
a1f7008
fix(queries): remove markdown trailing whitespace
7e609aa
merge: update KPI query catalog base
a019530
fix(sre-agent): remove recipe whitespace
42cc7f4
merge: update SRE Agent recipe base
c044e75
test(sre-agent): keep deployment tests with deploy slice
258ee3c
merge: update SRE Agent recipe base
05601e6
fix(sre-agent): keep deploy checks in deploy slice
b332089
fix(sre-agent): address deploy CI failures
3e83081
test(sre-agent): normalize bash stub path on Windows
60d7857
test(sre-agent): harden bash stub permissions
e46aa39
test(sre-agent): stub extras builder in deploy tests
de97720
test(sre-agent): fix Windows Python extras stub
4ed9fb9
test(sre-agent): preserve Azure resource IDs on Windows
a6d68e6
fix(sre-agent): address recipe review feedback
fe4aa54
chore: update mslearn dates
d07b722
Merge remote-tracking branch 'origin/dev' into features/sre-agent-recipe
4b64484
fix(sre-agent): vendor capacity skill, default read-only access, cust…
f7cca43
fix(sre-agent): unify template with secure deploy defaults and clean …
a1133af
fix(sre-agent): refresh ms.date, default actionMode to review, drop g…
MSBrett 4f3eee1
test(sre-agent): expect review-mode default for portal actionMode
MSBrett File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| [submodule "src/templates/sre-agent/submodules/azcapman"] | ||
| path = src/templates/sre-agent/submodules/azcapman | ||
| url = https://github.com/microsoft/azcapman.git | ||
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| // ============================================================================ | ||
| // Query: Azure OpenAI Cost by Application | ||
| // Description: | ||
| // Breaks down Azure OpenAI costs by application, cost center, team, and environment tags. | ||
| // Useful for AI workload showback, chargeback, and unit economics analysis. | ||
| // Author: FinOps Toolkit Team | ||
| // Parameters: | ||
| // startDate: Start date for the reporting period (e.g., startofmonth(ago(30d))) | ||
| // endDate: End date for the reporting period (e.g., startofmonth(now())) | ||
| // Output: | ||
| // Each row represents a tagged Azure OpenAI cost grouping with token count and cost metrics. | ||
| // Usage: | ||
| // Use this query to allocate Azure OpenAI usage and cost to applications, teams, and environments. | ||
| // Last Updated: 2026-05-26 | ||
| // ============================================================================ | ||
|
|
||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where x_SkuMeterSubcategory has "OpenAI" | ||
| | extend parsedTags = parse_json(Tags) | ||
| | extend Application = tostring(parsedTags["application"]) | ||
| | extend CostCenter = tostring(parsedTags["CostCenter"]) | ||
| | extend Environment = tostring(parsedTags["environment"]) | ||
| | extend Team = tostring(parsedTags["team"]) | ||
| | summarize | ||
| TokenCount = sum(ConsumedQuantity), | ||
| EffectiveCost = sum(EffectiveCost), | ||
| BilledCost = sum(BilledCost) | ||
| by Application, CostCenter, Team, Environment, ResourceName, x_SkuMeterSubcategory | ||
| | extend CostPer1KTokens = iff(TokenCount == 0, 0.0, EffectiveCost / TokenCount * 1000) | ||
| | order by EffectiveCost desc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // ============================================================================ | ||
| // Query: Azure OpenAI Daily Cost and Token Trend | ||
| // Description: | ||
| // Returns daily Azure OpenAI token consumption and effective cost. | ||
| // Useful for AI workload anomaly detection, forecasting, and trend reporting. | ||
| // Author: FinOps Toolkit Team | ||
| // Parameters: | ||
| // startDate: Start date for the reporting period (e.g., ago(30d)) | ||
| // endDate: End date for the reporting period (e.g., now()) | ||
| // Output: | ||
| // Each row represents one day with token count, cost, and cost per 1K tokens. | ||
| // Usage: | ||
| // Use this query to monitor AI workload consumption trends and detect daily cost spikes. | ||
| // Last Updated: 2026-05-26 | ||
| // ============================================================================ | ||
|
|
||
| let startDate = ago(30d); | ||
| let endDate = now(); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where x_SkuMeterSubcategory has "OpenAI" | ||
| | summarize | ||
| DailyTokens = sum(ConsumedQuantity), | ||
| DailyCost = sum(EffectiveCost) | ||
| by bin(ChargePeriodStart, 1d) | ||
| | extend CostPer1KTokens = iff(DailyTokens == 0, 0.0, DailyCost / DailyTokens * 1000) | ||
| | order by ChargePeriodStart asc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| // ============================================================================ | ||
| // Query: Azure OpenAI Model Cost Comparison | ||
| // Description: | ||
| // Compares token volume, effective cost, list cost, and discount percentage by model. | ||
| // Useful for AI model cost efficiency analysis and rate optimization. | ||
| // Author: FinOps Toolkit Team | ||
| // Parameters: | ||
| // startDate: Start date for the reporting period (e.g., startofmonth(ago(30d))) | ||
| // endDate: End date for the reporting period (e.g., startofmonth(now())) | ||
| // Output: | ||
| // Each row represents one Azure OpenAI model or SKU description with cost per 1K tokens. | ||
| // Usage: | ||
| // Use this query to compare model economics and identify where model or commitment changes may reduce AI spend. | ||
| // Last Updated: 2026-05-26 | ||
| // ============================================================================ | ||
|
|
||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where x_SkuMeterSubcategory has "OpenAI" | ||
| | extend Model = x_SkuDescription | ||
| | summarize | ||
| TokenCount = sum(ConsumedQuantity), | ||
| EffectiveCost = sum(EffectiveCost), | ||
| ListCost = sum(ListCost) | ||
| by Model | ||
| | extend CostPer1KTokens = iff(TokenCount == 0, 0.0, EffectiveCost / TokenCount * 1000) | ||
| | extend ListPer1KTokens = iff(TokenCount == 0, 0.0, ListCost / TokenCount * 1000) | ||
| | extend DiscountPercent = iff(ListCost == 0, 0.0, (ListCost - EffectiveCost) / ListCost * 100) | ||
| | order by EffectiveCost desc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // ============================================================================ | ||
| // Query: Azure OpenAI Token Usage Breakdown | ||
| // Description: | ||
| // Breaks Azure OpenAI token consumption down by model version and input/output direction. | ||
| // Calculates effective unit cost per token and cost per 1K tokens. | ||
| // Author: FinOps Toolkit Team | ||
| // Parameters: | ||
| // startDate: Start date for the reporting period (e.g., startofmonth(ago(30d))) | ||
| // endDate: End date for the reporting period (e.g., startofmonth(now())) | ||
| // Output: | ||
| // Each row represents one model and direction with token count and cost metrics. | ||
| // Usage: | ||
| // Use this query to analyze AI workload unit economics, token direction mix, and model cost efficiency. | ||
| // Last Updated: 2026-05-26 | ||
| // ============================================================================ | ||
|
|
||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where x_SkuMeterSubcategory has "OpenAI" | ||
| | extend Model = x_SkuDescription | ||
| | extend Direction = case( | ||
| Model contains "Input", "Input", | ||
| Model contains "Output", "Output", | ||
| "Other") | ||
| | summarize | ||
| TokenCount = sum(ConsumedQuantity), | ||
| EffectiveCost = sum(EffectiveCost), | ||
| BilledCost = sum(BilledCost), | ||
| ListCost = sum(ListCost) | ||
| by Model, Direction, x_SkuDescription | ||
| | extend UnitCostPerToken = iff(TokenCount == 0, 0.0, EffectiveCost / TokenCount) | ||
| | extend CostPer1KTokens = UnitCostPerToken * 1000 | ||
| | order by EffectiveCost desc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // ============================================================================ | ||
| // Query: Allocation Accuracy Index | ||
| // Description: | ||
| // Calculates the percentage of total effective cost that is directly attributed using a | ||
| // three-signal heuristic: allocation rule, cost center, or ownership-tag evidence. | ||
| // KPI: Allocation Accuracy Index (AAI) | ||
| // Formula: Allocation Accuracy Index (AAI) = (Directly Attributed Costs / Total Infrastructure Costs) × 100 | ||
| // Author: FinOps toolkit | ||
| // Parameters: | ||
| // startDate: datetime; start date for the reporting period (default: startofmonth(ago(30d))) | ||
| // endDate: datetime; end date for the reporting period (default: startofmonth(now())) | ||
| // allocationEvidenceTagKeys: dynamic; tag keys treated as ownership evidence (default: dynamic(['cost-center','team','owner','application','product'])) | ||
| // Output: | ||
| // Each row represents one BillingCurrency and returns DirectlyAttributedCost, TotalEffectiveCost, | ||
| // and AAI for Hub-visible CSP costs in the reporting window. | ||
| // Usage: | ||
| // Use this query to measure how much effective cost is directly attributable within FinOps Hub. | ||
| // Scope Notes: Hub-only AAI. Does not include on-prem, SaaS, or other infrastructure outside Hub schema. | ||
| // Last Tested: 2026-05-28 against msbwftktreyhub.westus.kusto.windows.net/Hub (1,366,763 cost rows in 2026-04 window). UAT result: PASS — 1 row returned | ||
| // ========================================================================= | ||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| let allocationEvidenceTagKeys = dynamic(['cost-center','team','owner','application','product']); | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where not(ChargeCategory == 'Purchase' and isnotempty(CommitmentDiscountCategory)) | ||
| | extend tmp_IsAttributed = isnotempty(x_CostAllocationRuleName) | ||
| or isnotempty(x_CostCenter) | ||
| or array_length(set_intersect(bag_keys(Tags), allocationEvidenceTagKeys)) > 0 | ||
| | summarize | ||
| DirectlyAttributedCost = todouble(sumif(EffectiveCost, tmp_IsAttributed)), | ||
| TotalEffectiveCost = todouble(sum(EffectiveCost)) | ||
| by BillingCurrency | ||
| | extend AAI = iff(TotalEffectiveCost == 0, 0.0, DirectlyAttributedCost / TotalEffectiveCost * 100.0) | ||
| | project BillingCurrency, DirectlyAttributedCost, TotalEffectiveCost, AAI |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| // ============================================================================ | ||
| // Query: Anomaly Detection Rate | ||
| // Description: | ||
| // Calculates the percentage of effective spend attributable to anomaly-flagged days. | ||
| // Builds daily cost series per service category and billing currency, then applies time-series anomaly detection. | ||
| // KPI: Anomaly Detection Rate | ||
| // Formula: Total Cost of Anomaly Spikes / Total Spend = Anomaly Cost % | ||
| // Author: FinOps toolkit | ||
| // Parameters: | ||
| // startDate: datetime; Start date for the reporting period (default: startofmonth(ago(30d))) | ||
| // endDate: datetime; End date for the reporting period (default: startofmonth(now())) | ||
| // sensitivity: real; Anomaly detection sensitivity for series_decompose_anomalies() (default: 1.5) | ||
| // Output: | ||
| // Each row returns a BillingCurrency and ServiceCategory pair (plus an Overall rollup row) with AnomalyCost, TotalCost, and AnomalyRatePercent as double values. | ||
| // Usage: | ||
| // Use this query to quantify how much effective spend falls on anomaly-flagged days by service category and by billing currency. | ||
| // Scope Notes: | ||
| // Treats both positive spikes and negative drops as anomalies (AnomalyFlags != 0); the Overall row is per BillingCurrency only. | ||
| // Missing days are zero-filled via make-series default=0.0, and commitment purchase rows are excluded to avoid amortization double-counting. | ||
| // Last Tested: 2026-05-28 against msbwftktreyhub.westus.kusto.windows.net/Hub (1,366,763 cost rows in 2026-04 window). UAT result: PASS — 13 rows returned (per service category) | ||
| // ========================================================================= | ||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| let sensitivity = 1.5; | ||
| let expanded = materialize( | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where not(ChargeCategory == 'Purchase' and isnotempty(CommitmentDiscountCategory)) | ||
| | summarize DailyCost = sum(todouble(EffectiveCost)) | ||
| by bin(ChargePeriodStart, 1d), ServiceCategory, BillingCurrency | ||
| | make-series CostSeries = sum(DailyCost) default=0.0 | ||
| on ChargePeriodStart from startDate to endDate step 1d | ||
| by ServiceCategory, BillingCurrency | ||
| | extend AnomalyFlags = series_decompose_anomalies(CostSeries, sensitivity) | ||
| | mv-expand CostSeries to typeof(double), AnomalyFlags to typeof(int) | ||
| ); | ||
| let perCategory = | ||
| expanded | ||
| | summarize | ||
| AnomalyCost = todouble(sumif(CostSeries, AnomalyFlags != 0)), | ||
| TotalCost = todouble(sum(CostSeries)) | ||
| by BillingCurrency, ServiceCategory | ||
| | extend AnomalyRatePercent = todouble(iff(TotalCost == 0.0, 0.0, AnomalyCost / TotalCost * 100.0)); | ||
| let overall = | ||
| expanded | ||
| | summarize | ||
| AnomalyCost = todouble(sumif(CostSeries, AnomalyFlags != 0)), | ||
| TotalCost = todouble(sum(CostSeries)) | ||
| by BillingCurrency | ||
| | extend ServiceCategory = 'Overall' | ||
| | extend AnomalyRatePercent = todouble(iff(TotalCost == 0.0, 0.0, AnomalyCost / TotalCost * 100.0)); | ||
| union perCategory, overall | ||
| | project BillingCurrency, ServiceCategory, AnomalyCost, TotalCost, AnomalyRatePercent |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| // ============================================================================ | ||
| // Query: Total Unpredicted Variance of Spend | ||
| // Description: | ||
| // Calculates the net unpredicted variance between actual effective cost and the anomaly baseline | ||
| // for anomaly-flagged daily buckets by service category and billing currency. | ||
| // KPI: Total Unpredicted Variance of Spend | ||
| // Formula: Total effective cost associated with all anomaly events detected less the predicted spend of the services related to the identified anomalies. | ||
| // Author: FinOps toolkit | ||
| // Parameters: | ||
| // startDate: datetime; start of the reporting period (default: startofmonth(ago(12 * 30d))) | ||
| // endDate: datetime; end of the reporting period (default: now()) | ||
| // anomalyThreshold: real; anomaly detection sensitivity threshold (default: 1.5) | ||
| // Output: | ||
| // Each row returns BillingCurrency, ServiceCategory, AnomalyEventCount, UnpredictedVarianceSigned, | ||
| // and UnpredictedVarianceAbs for anomaly-detected daily buckets; "(All Services)" rows provide | ||
| // per-currency totals across all service categories. | ||
| // Usage: | ||
| // Use this query to quantify net anomalous overspend or underspend by service category and currency. | ||
| // Scope Notes: | ||
| // Per-group anomaly detection runs independently per (ServiceCategory, BillingCurrency), and groups | ||
| // with sparse history are filtered when no anomaly baseline is produced. Each BillingCurrency is | ||
| // reported separately and must not be summed across currencies without FX conversion. The default | ||
| // 12-month window supports STL seasonality decomposition, and UnpredictedVarianceAbs is defined as | ||
| // abs(sum(actual - baseline)) rather than sum(abs(actual - baseline)). | ||
| // Last Tested: 2026-05-28 against msbwftktreyhub.westus.kusto.windows.net/Hub (1,366,763 cost rows in 2026-04 window). UAT result: PASS — 13 rows returned (per service category) | ||
| // ========================================================================= | ||
| let startDate = startofmonth(ago(12 * 30d)); | ||
| let endDate = now(); | ||
| let anomalyThreshold = 1.5; | ||
| let anomalyBuckets = | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where not(ChargeCategory == 'Purchase' and isnotempty(CommitmentDiscountCategory)) | ||
| | summarize DailyCost = sum(EffectiveCost) by ServiceCategory, BillingCurrency, bin(ChargePeriodStart, 1d) | ||
| | make-series CostSeries = sum(DailyCost) default=0.0 on ChargePeriodStart from startDate to endDate step 1d by ServiceCategory, BillingCurrency | ||
| | extend (ad_flag, ad_score, ad_baseline) = series_decompose_anomalies(CostSeries, anomalyThreshold) | ||
| | mv-expand ChargePeriodStart to typeof(datetime), CostSeries to typeof(real), ad_flag to typeof(real), ad_score to typeof(real), ad_baseline to typeof(real) | ||
| | extend ad_flag = toint(ad_flag), CostSeries = toreal(CostSeries), ad_score = toreal(ad_score), ad_baseline = toreal(ad_baseline) | ||
| | where isnotnull(ad_baseline) | ||
| | where ad_flag != 0 | ||
| | extend Variance = todouble(CostSeries) - todouble(ad_baseline); | ||
| union | ||
| ( | ||
| anomalyBuckets | ||
| | summarize | ||
| AnomalyEventCount = count(), | ||
| UnpredictedVarianceSigned = todouble(sum(Variance)), | ||
| UnpredictedVarianceAbs = todouble(abs(sum(Variance))) | ||
| by BillingCurrency, ServiceCategory | ||
| ), | ||
| ( | ||
| anomalyBuckets | ||
| | summarize | ||
| AnomalyEventCount = count(), | ||
| UnpredictedVarianceSigned = todouble(sum(Variance)), | ||
| UnpredictedVarianceAbs = todouble(abs(sum(Variance))) | ||
| by BillingCurrency | ||
| | extend ServiceCategory = "(All Services)" | ||
| ) | ||
| | project | ||
| BillingCurrency, | ||
| ServiceCategory, | ||
| AnomalyEventCount, | ||
| UnpredictedVarianceSigned = todouble(UnpredictedVarianceSigned), | ||
| UnpredictedVarianceAbs = todouble(UnpredictedVarianceAbs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| // ============================================================================ | ||
| // Query: Percentage of Commitment Discount Waste | ||
| // Description: | ||
| // Computes the percentage of commitment discount waste for each commitment by | ||
| // comparing unused amortized EffectiveCost to total commitment EffectiveCost. | ||
| // Includes a grand-total row per BillingCurrency across all commitments in the | ||
| // reporting window. | ||
| // KPI: Percentage of Commitment Discount Waste | ||
| // Formula: (Cost of Commitment Discount unused / total cost Commitment Discount) x 100 | ||
| // Author: FinOps toolkit | ||
| // Parameters: | ||
| // startDate: datetime = startofmonth(ago(30d)) | ||
| // endDate: datetime = startofmonth(now()) | ||
| // Output: | ||
| // BillingCurrency: string. Billing currency for the commitment or grand-total row. | ||
| // CommitmentDiscountId: string. Commitment identifier; empty string on the grand-total row. | ||
| // CommitmentDiscountName: string. Commitment name; '(All Commitments)' on the grand-total row. | ||
| // CommitmentDiscountType: string. Commitment type; empty string on the grand-total row. | ||
| // UnusedCost: double. Sum of EffectiveCost for rows where CommitmentDiscountStatus == 'Unused'. | ||
| // TotalCost: double. Sum of EffectiveCost across all commitment rows after filters. | ||
| // WastePercent: double. Percentage of TotalCost represented by UnusedCost. | ||
| // Usage: | ||
| // Use this query to identify underutilized commitment discounts and quantify waste by commitment and billing currency. | ||
| // Scope Notes: | ||
| // - Double-counting prevention: This query operates on amortized-style rows only | ||
| // (purchase rows excluded). | ||
| // - Unused row semantics: CommitmentDiscountStatus == 'Unused' rows represent | ||
| // wasted amortized commitment cost for the charge period. | ||
| // - CommitmentDiscountStatus values: Only 'Used' and 'Unused' are expected. | ||
| // - Currency mixing: Grand-total output is scoped per BillingCurrency; cross- | ||
| // currency aggregation is out of scope. | ||
| // - Period window: Default startDate/endDate cover one calendar month; adjust | ||
| // the let bindings for rolling windows. | ||
| // - KPI limitation vs canonical definition: This implementation uses | ||
| // EffectiveCost as the cost basis for commitment-discount waste analytics. | ||
| // Last Tested: 2026-05-28 against msbwftktreyhub.westus.kusto.windows.net/Hub (1,366,763 cost rows in 2026-04 window). UAT result: PASS_SCHEMA_WITH_DATA_GAP — query executed and returned expected columns; the hub has 0 commitment-discount rows in the test window, so value semantics require re-UAT on a commitment-active hub. | ||
| // ========================================================================= | ||
| let startDate = startofmonth(ago(30d)); | ||
| let endDate = startofmonth(now()); | ||
| let filteredCosts = | ||
| Costs() | ||
| | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate | ||
| | where isnotempty(CommitmentDiscountId) | ||
| | where not(ChargeCategory == 'Purchase' and isnotempty(CommitmentDiscountCategory)); | ||
| let commitmentWaste = | ||
| filteredCosts | ||
| | summarize | ||
| UnusedCost = sum(iff(CommitmentDiscountStatus == 'Unused', EffectiveCost, real(0))), | ||
| TotalCost = sum(EffectiveCost) | ||
| by BillingCurrency, CommitmentDiscountId, CommitmentDiscountName, CommitmentDiscountType | ||
| | extend WastePercent = iff(TotalCost == 0.0, 0.0, todouble(UnusedCost) / todouble(TotalCost) * 100.0) | ||
| | project | ||
| BillingCurrency, | ||
| CommitmentDiscountId, | ||
| CommitmentDiscountName, | ||
| CommitmentDiscountType, | ||
| UnusedCost = todouble(UnusedCost), | ||
| TotalCost = todouble(TotalCost), | ||
| WastePercent = todouble(WastePercent); | ||
| let grandTotals = | ||
| filteredCosts | ||
| | summarize | ||
| UnusedCost = sum(iff(CommitmentDiscountStatus == 'Unused', EffectiveCost, real(0))), | ||
| TotalCost = sum(EffectiveCost) | ||
| by BillingCurrency | ||
| | extend | ||
| CommitmentDiscountId = '', | ||
| CommitmentDiscountName = '(All Commitments)', | ||
| CommitmentDiscountType = '' | ||
| | extend WastePercent = iff(TotalCost == 0.0, 0.0, todouble(UnusedCost) / todouble(TotalCost) * 100.0) | ||
| | project | ||
| BillingCurrency, | ||
| CommitmentDiscountId, | ||
| CommitmentDiscountName, | ||
| CommitmentDiscountType, | ||
| UnusedCost = todouble(UnusedCost), | ||
| TotalCost = todouble(TotalCost), | ||
| WastePercent = todouble(WastePercent); | ||
| union commitmentWaste, grandTotals | ||
| | order by BillingCurrency asc, WastePercent desc, CommitmentDiscountName asc | ||
| | project | ||
| BillingCurrency, | ||
| CommitmentDiscountId, | ||
| CommitmentDiscountName, | ||
| CommitmentDiscountType, | ||
| UnusedCost, | ||
| TotalCost, | ||
| WastePercent |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Submodule makes the recipe build non-hermetic and is currently broken.
azcapmanis pinned only by gitlink SHA (nobranch), is uninitialized, and three files underrecipes/finops-hub/config/skills/azure-capacity-management/(SKILL.md, references/docs, references/scripts) are symlinks into it.build-extras.pyraisesExpected skill directory missing SKILL.md or has a broken symlink: azure-capacity-management, soBuild-SreAgentTemplate.ps1fails unlessgit submodule update --initwas run first — and no build doc/README states that prerequisite. Adding a submodule also burdens every toolkit clone and anygit archive/source zip (empty submodule → broken symlinks). Recommend vendoring the azcapman skill/docs/scripts directly into the template and dropping the submodule + symlinks; if the submodule must stay, pin abranchand add an enforced, documentedsubmodule update --initstep in the build.