From 998573aa522362215397f3645e1ddbfa9a7a91b9 Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Wed, 15 Jul 2026 14:25:22 -0700 Subject: [PATCH 1/2] docs(copilot-studio): refresh knowledge files and query catalog for FOCUS 1.4 Rewrite schema-reference.md for Costs_v1_4() with all 10 new FOCUS 1.3/1.4 columns (Allocated*, ContractApplied, ServiceProviderName, HostProviderName, CommitmentProgramEligibilityDetails, InvoiceDetailId, 12 ContractCommitment* row fields), remove the deleted ProviderName/PublisherName columns, and cross-check every listed column against the Costs_final_v1_4 table definition. Update agent-instructions.md, knowledge-descriptions.md, and weekly-report-guide.md from Costs_v1_2()/FOCUS 1.2 to Costs_v1_4(), replacing removed-column usage (PublisherName -> ServiceProviderName) in weekly-report-guide.md's KQL queries. Bump Build-QueryCatalog.ps1's hardcoded Costs() -> Costs_v1_2() rewrite to Costs_v1_4(). Co-Authored-By: Claude Fable 5 --- src/scripts/Build-QueryCatalog.ps1 | 8 ++-- .../agent-instructions.md | 8 ++-- .../knowledge-descriptions.md | 2 +- .../knowledge/schema-reference.md | 47 +++++++++++++++---- .../knowledge/weekly-report-guide.md | 20 ++++---- 5 files changed, 58 insertions(+), 27 deletions(-) diff --git a/src/scripts/Build-QueryCatalog.ps1 b/src/scripts/Build-QueryCatalog.ps1 index bb23eccf8..eed6536a4 100644 --- a/src/scripts/Build-QueryCatalog.ps1 +++ b/src/scripts/Build-QueryCatalog.ps1 @@ -7,7 +7,7 @@ .DESCRIPTION Reads all .kql files from src/queries/catalog, includes the full file content - (comments and query), replaces Costs() with Costs_v1_2(), and writes a combined + (comments and query), replaces Costs() with Costs_v1_4(), and writes a combined markdown file to the Copilot Studio knowledge folder. .EXAMPLE @@ -46,7 +46,7 @@ $output = @" This document contains ready-to-use KQL query patterns for common FinOps analysis tasks. Use these as templates when answering cost questions. Always execute queries via the Kusto MCP tool — never answer from this document alone. -All queries use the ``Costs_v1_2()`` function unless noted otherwise. +All queries use the ``Costs_v1_4()`` function unless noted otherwise. "@ # Process each KQL file @@ -69,8 +69,8 @@ foreach ($file in $kqlFiles) $title = ($file.BaseName -replace '-', ' ') $title = $title.Substring(0, 1).ToUpper() + $title.Substring(1) - # Replace Costs() with Costs_v1_2() - $content = $content -replace '\bCosts\(\)', 'Costs_v1_2()' + # Replace Costs() with Costs_v1_4() + $content = $content -replace '\bCosts\(\)', 'Costs_v1_4()' # Guard against triple backticks in KQL content breaking the markdown code fence if ($content -match '``````') diff --git a/src/templates/finops-hub-copilot-studio/agent-instructions.md b/src/templates/finops-hub-copilot-studio/agent-instructions.md index 49102acc8..a8da33268 100644 --- a/src/templates/finops-hub-copilot-studio/agent-instructions.md +++ b/src/templates/finops-hub-copilot-studio/agent-instructions.md @@ -11,7 +11,7 @@ Database: Hub ## Knowledge references (use to BUILD queries, not to answer directly) -- **`schema-reference.md`** — Column names, types, usage notes, and edge cases for `Costs_v1_2()`. Check BEFORE every query. Never quote as answers. +- **`schema-reference.md`** — Column names, types, usage notes, and edge cases for `Costs_v1_4()`. Check BEFORE every query. Never quote as answers. - **`query-catalog.md`** — Ready-to-use KQL query templates for cost breakdowns, trends, anomalies, savings, forecasting, and commitment analysis. Adapt and execute; never return as-is. - **`weekly-report-guide.md`** — Workflow for structured weekly cost anomaly reports with severity classification and report structure. Follow when asked for weekly report. @@ -22,7 +22,7 @@ On first interaction, run these steps automatically: **Step 1: Detect currency** ```kusto -Costs_v1_2() | where ChargePeriodStart >= ago(7d) | summarize count() by BillingCurrency | top 1 by count_ +Costs_v1_4() | where ChargePeriodStart >= ago(7d) | summarize count() by BillingCurrency | top 1 by count_ ``` Use the returned currency symbol for the session ($ for USD, CA$ for CAD, € for EUR, £ for GBP, etc.). @@ -38,7 +38,7 @@ Query and present available scopes. Ask the user to pick ONE: | Tag | First query tag keys: `... \| mv-expand bagexpansion=array Tags \| summarize count() by tostring(Tags[0]) \| top 10 by count_` Then query values for chosen key. | `Tags[''] == ""` | | All | No query needed | No filter | -All discovery queries use: `Costs_v1_2() | where ChargePeriodStart >= ago(7d)` +All discovery queries use: `Costs_v1_4() | where ChargePeriodStart >= ago(7d)` Apply the selected scope filter to EVERY subsequent query. Mention active scope in each response. User can change scope anytime. @@ -49,7 +49,7 @@ Apply the selected scope filter to EVERY subsequent query. Mention active scope ## Core rules -1. ALWAYS query `Costs_v1_2()` for cost data. NEVER query raw tables directly. +1. ALWAYS query `Costs_v1_4()` for cost data. NEVER query raw tables directly. 2. VERIFY column names against `schema-reference.md` before every query. 3. SHOW the KQL query you will run before executing it. 4. NEVER guess column names or values. If unsure, check `schema-reference.md`. diff --git a/src/templates/finops-hub-copilot-studio/knowledge-descriptions.md b/src/templates/finops-hub-copilot-studio/knowledge-descriptions.md index d0a64265b..d4f4c3563 100644 --- a/src/templates/finops-hub-copilot-studio/knowledge-descriptions.md +++ b/src/templates/finops-hub-copilot-studio/knowledge-descriptions.md @@ -4,7 +4,7 @@ Use these descriptions when uploading knowledge files to your Copilot Studio age ## schema-reference.md -Column reference for building KQL queries against Costs_v1_2(). Contains all column names, data types, usage notes, and edge cases like blank meter categories and BilledCost vs EffectiveCost divergence. Use to look up correct column names before writing queries. +Column reference for building KQL queries against Costs_v1_4(). Contains all column names, data types, usage notes, and edge cases like blank meter categories and BilledCost vs EffectiveCost divergence. Use to look up correct column names before writing queries. ## query-catalog.md diff --git a/src/templates/finops-hub-copilot-studio/knowledge/schema-reference.md b/src/templates/finops-hub-copilot-studio/knowledge/schema-reference.md index 9e7908f32..ef316d292 100644 --- a/src/templates/finops-hub-copilot-studio/knowledge/schema-reference.md +++ b/src/templates/finops-hub-copilot-studio/knowledge/schema-reference.md @@ -1,10 +1,10 @@ -# KQL column reference for Costs_v1_2() +# KQL column reference for Costs_v1_4() -This document lists all columns available in the `Costs_v1_2()` function in the FinOps Hub database. +This document lists all columns available in the `Costs_v1_4()` function in the FinOps Hub database. **IMPORTANT: This is a SCHEMA REFERENCE for constructing KQL queries. Do NOT use values from this document to answer questions. Always EXECUTE a KQL query to get actual data.** -Based on FOCUS 1.2 (FinOps Open Cost and Usage Specification). Columns with `x_` prefix are Azure extensions. +Based on FOCUS 1.4 (FinOps Open Cost and Usage Specification). Columns with `x_` prefix are Azure extensions. ## Time @@ -46,6 +46,7 @@ Relationship: `ListCost >= ContractedCost >= EffectiveCost` for discounted usage | BillingCurrency | string | Currency code (e.g. CAD, USD, EUR). | | x_BillingAccountAgreement | string | Agreement type: "EA", "MCA", "MOSP". | | x_BillingAccountId | string | Numeric billing account ID. | +| x_BillingAccountName | string | Numeric billing account display name (source value before FOCUS normalization). | | x_BillingProfileId | string | MCA billing profile ID. Not used for EA. | | x_BillingProfileName | string | MCA billing profile name. | | x_AccountId | string | EA enrollment account ID. | @@ -61,6 +62,11 @@ Relationship: `ListCost >= ContractedCost >= EffectiveCost` for discounted usage | x_CostAllocationRuleName | string | Cost allocation rule name. | | x_CostCategories | dynamic | Cost categories from allocation rules. | | x_Project | string | Project label from allocation or tags. | +| AllocatedResourceId | string | (FOCUS 1.3+) ARM path of the resource the cost was allocated to, if split-allocated. Null for hubs today (no Cost Management source). | +| AllocatedResourceName | string | (FOCUS 1.3+) Display name of the allocated-to resource. Null for hubs today. | +| AllocatedMethodId | string | (FOCUS 1.3+) Identifier of the allocation method/rule applied. Null for hubs today. | +| AllocatedMethodDetails | dynamic | (FOCUS 1.3+) JSON metadata describing the allocation method. Null for hubs today. | +| AllocatedTags | dynamic | (FOCUS 1.3+) Tags associated with the allocation target (JSON). Null for hubs today. | ## Resource @@ -102,7 +108,7 @@ To handle in queries, use a synthetic category: ```kusto | extend Category = iif(isempty(x_SkuMeterCategory), - iif(x_PublisherCategory == "Vendor", strcat("Vendor: ", PublisherName), + iif(x_PublisherCategory == "Vendor", strcat("Vendor: ", ServiceProviderName), iif(CommitmentDiscountStatus == "Unused" and CommitmentDiscountType == "Savings Plan", "Savings Plan Unused", iif(isnotempty(ServiceName), ServiceName, "Uncategorized"))), @@ -128,6 +134,27 @@ To handle in queries, use a synthetic category: | x_CommitmentDiscountUtilizationAmount | real | Utilized amount. | | x_CommitmentDiscountUtilizationPotential | real | Maximum potential utilization. | | x_AmortizationClass | string | "Amortized Charge" or "Principal". | +| CommitmentProgramEligibilityDetails | dynamic | (FOCUS 1.4+) JSON metadata describing eligibility for provider commitment programs. Null for hubs today (no Cost Management source). | + +## Contracts + +| Column | Type | Usage | +|--------|------|-------| +| ContractApplied | dynamic | (FOCUS 1.3+) JSON array of contract commitments applied to this row. Null for hubs today (no Cost Management source). See `ContractCommitments()` for the referenced metadata — no data until a FOCUS 1.4 export ships. | +| ContractCommitmentBenefitCategory | string | (FOCUS 1.4+) Category of benefit granted by the contract commitment. Null for hubs today. | +| ContractCommitmentCreated | datetime | (FOCUS 1.4+) When the contract commitment was created. Null for hubs today. | +| ContractCommitmentDiscountPercentage | real | (FOCUS 1.4+) Discount percentage granted by the contract commitment. Null for hubs today. | +| ContractCommitmentDurationType | string | (FOCUS 1.4+) Duration type of the contract commitment (e.g. fixed, recurring). Null for hubs today. | +| ContractCommitmentFulfillmentInterval | string | (FOCUS 1.4+) Interval over which the commitment is fulfilled. Null for hubs today. | +| ContractCommitmentLastUpdated | datetime | (FOCUS 1.4+) When the contract commitment was last updated. Null for hubs today. | +| ContractCommitmentLifecycleStatus | string | (FOCUS 1.4+) Lifecycle status of the contract commitment. Null for hubs today. | +| ContractCommitmentModel | string | (FOCUS 1.4+) Commitment model (e.g. spend-based, usage-based). Null for hubs today. | +| ContractCommitmentOfferCategory | string | (FOCUS 1.4+) Offer category for the contract commitment. Null for hubs today. | +| ContractCommitmentPaymentInterval | string | (FOCUS 1.4+) Payment interval for the contract commitment. Null for hubs today. | +| ContractCommitmentPaymentModel | string | (FOCUS 1.4+) Payment model for the contract commitment. Null for hubs today. | +| ContractCommitmentPaymentUpfrontPercentage | real | (FOCUS 1.4+) Percentage of the contract commitment paid upfront. Null for hubs today. | + +> All `ContractCommitment*` columns above are null for hubs today (no Cost Management source) and are duplicated as row-level fields per FOCUS 1.4. For full contract commitment metadata, use `ContractCommitments()` — no data until Microsoft Cost Management ships a FOCUS 1.4 export (not yet available). ## Capacity reservation @@ -162,16 +189,18 @@ To handle in queries, use a synthetic category: | x_PricingBlockSize | real | Block size for pricing. | | x_PricingUnitDescription | string | Original CM unit description with block size. | -## Publisher +## Provider | Column | Type | Usage | |--------|------|-------| | x_PublisherCategory | string | "Cloud Provider" (first-party) or "Vendor" (marketplace). | -| PublisherName | string | Publisher name (e.g. "Microsoft"). | +| ServiceProviderName | string | Vendor that makes the service available (Marketplace publisher or Microsoft). Never null. Replaces the removed `PublisherName`/`ProviderName`. | +| HostProviderName | string | Infrastructure provider that hosts the resource. Always "Microsoft" for Cost Management data. Replaces the removed `ProviderName`. | | x_PublisherId | string | Publisher as billed by. | -| ProviderName | string | Always "Microsoft" for Azure. | | InvoiceIssuerName | string | Entity that issued the invoice. | +> **Removed in FOCUS 1.4**: `ProviderName` and `PublisherName` no longer exist in `Costs_v1_4()`. Use `ServiceProviderName` and `HostProviderName` instead — see above. Original source values are preserved in `x_SourceValues` for auditing. + ## Geography | Column | Type | Usage | @@ -180,6 +209,7 @@ To handle in queries, use a synthetic category: | RegionName | string | e.g. "Canada Central". | | AvailabilityZone | string | Availability zone, if applicable. | | x_SkuRegion | string | SKU region from CM. Different format than RegionId. | +| x_Location | string | Original location string (GCP source data). Blank for Azure. | ## Tags @@ -218,6 +248,7 @@ To handle in queries, use a synthetic category: | Column | Type | Usage | |--------|------|-------| | InvoiceId | string | FOCUS invoice identifier. | +| InvoiceDetailId | string | (FOCUS 1.4+) Identifier of the invoice line item associated with this row. Null for hubs today (no Cost Management source). Join to `InvoiceDetails()` — no data until a FOCUS 1.4 export ships. | | x_InvoiceIssuerId | string | Invoice issuer ID. | | x_InvoiceSectionId | string | MCA invoice section / EA department ID. | | x_InvoiceSectionName | string | MCA invoice section / EA department name. | @@ -295,4 +326,4 @@ To handle in queries, use a synthetic category: | x_SourceType | string | Type of data source. | | x_SourceVersion | string | Schema version of source data. | | x_SourceChanges | string | Changes applied during ingestion. | -| x_SourceValues | dynamic | Original source values before transformation (JSON). | +| x_SourceValues | dynamic | Original source values before transformation (JSON), including removed columns like `ProviderName`/`PublisherName`. | diff --git a/src/templates/finops-hub-copilot-studio/knowledge/weekly-report-guide.md b/src/templates/finops-hub-copilot-studio/knowledge/weekly-report-guide.md index 0a16b36cd..82b0aa312 100644 --- a/src/templates/finops-hub-copilot-studio/knowledge/weekly-report-guide.md +++ b/src/templates/finops-hub-copilot-studio/knowledge/weekly-report-guide.md @@ -24,7 +24,7 @@ All queries filter `ChargeCategory == "Usage" and x_PublisherCategory == "Cloud let LastWeekEnd = startofweek(now()); let LastWeekStart = datetime_add('day', -7, LastWeekEnd); let PriorWeekStart = datetime_add('day', -14, LastWeekEnd); -Costs_v1_2() +Costs_v1_4() | where ChargePeriodStart >= PriorWeekStart and ChargePeriodStart < LastWeekEnd and ChargeCategory == "Usage" and x_PublisherCategory == "Cloud Provider" | summarize Cost = round(sum(EffectiveCost), 2), Days = dcount(ChargePeriodStart) @@ -38,7 +38,7 @@ Costs_v1_2() let LastWeekEnd = startofweek(now()); let LastWeekStart = datetime_add('day', -7, LastWeekEnd); let PriorWeekStart = datetime_add('day', -14, LastWeekEnd); -Costs_v1_2() +Costs_v1_4() | where ChargePeriodStart >= PriorWeekStart and ChargePeriodStart < LastWeekEnd and ChargeCategory == "Usage" and x_PublisherCategory == "Cloud Provider" | extend Week = iff(ChargePeriodStart >= LastWeekStart, "LastWeek", "PriorWeek") @@ -56,7 +56,7 @@ Costs_v1_2() let LastWeekEnd = startofweek(now()); let LastWeekStart = datetime_add('day', -7, LastWeekEnd); let PriorWeekStart = datetime_add('day', -14, LastWeekEnd); -Costs_v1_2() +Costs_v1_4() | where ChargePeriodStart >= PriorWeekStart and ChargePeriodStart < LastWeekEnd and ChargeCategory == "Usage" and x_PublisherCategory == "Cloud Provider" | extend Week = iff(ChargePeriodStart >= LastWeekStart, "LastWeek", "PriorWeek") @@ -77,7 +77,7 @@ Same as Q3 but filter for decreases: let LastWeekEnd = startofweek(now()); let LastWeekStart = datetime_add('day', -7, LastWeekEnd); let PriorWeekStart = datetime_add('day', -14, LastWeekEnd); -Costs_v1_2() +Costs_v1_4() | where ChargePeriodStart >= PriorWeekStart and ChargePeriodStart < LastWeekEnd and ChargeCategory == "Usage" and x_PublisherCategory == "Cloud Provider" | extend Week = iff(ChargePeriodStart >= LastWeekStart, "LastWeek", "PriorWeek") @@ -96,7 +96,7 @@ Costs_v1_2() let LastWeekEnd = startofweek(now()); let LastWeekStart = datetime_add('day', -7, LastWeekEnd); let PriorWeekStart = datetime_add('day', -14, LastWeekEnd); -Costs_v1_2() +Costs_v1_4() | where ChargePeriodStart >= PriorWeekStart and ChargePeriodStart < LastWeekEnd | extend Week = iff(ChargePeriodStart >= LastWeekStart, "LastWeek", "PriorWeek") | summarize @@ -118,12 +118,12 @@ Costs_v1_2() let LastWeekEnd = startofweek(now()); let LastWeekStart = datetime_add('day', -7, LastWeekEnd); let PriorWeekStart = datetime_add('day', -14, LastWeekEnd); -Costs_v1_2() +Costs_v1_4() | where ChargePeriodStart >= PriorWeekStart and ChargePeriodStart < LastWeekEnd and x_PublisherCategory == "Vendor" | extend Week = iff(ChargePeriodStart >= LastWeekStart, "LastWeek", "PriorWeek") | summarize Cost = round(sum(EffectiveCost), 2) - by ResourceId, ResourceName, x_ResourceGroupName, PublisherName, ChargeCategory, Week + by ResourceId, ResourceName, x_ResourceGroupName, ServiceProviderName, ChargeCategory, Week | evaluate pivot(Week, sum(Cost)) | extend LastWeek = coalesce(LastWeek, 0.0), PriorWeek = coalesce(PriorWeek, 0.0) | extend Change = round(LastWeek - PriorWeek, 2), @@ -135,13 +135,13 @@ Costs_v1_2() ### Q7: Marketplace purchases (13-month lookback) ```kusto -Costs_v1_2() +Costs_v1_4() | where ChargePeriodStart >= datetime_add('month', -13, startofmonth(now())) and ChargeCategory == "Purchase" and x_PublisherCategory == "Vendor" | summarize Cost = round(sum(EffectiveCost), 2) - by BillingMonth = startofmonth(ChargePeriodStart), PublisherName + by BillingMonth = startofmonth(ChargePeriodStart), ServiceProviderName | where Cost >= 10 -| order by PublisherName asc, BillingMonth asc +| order by ServiceProviderName asc, BillingMonth asc ``` Classify each publisher by frequency: 10+ months = Monthly recurring, 3-9 months = Intermittent, 2 months = Annual, 1 month (current) = New, 1 month (older) = One-time. From b2d138a4c6baa175434bf0ac95db8d53e5122bab Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Wed, 15 Jul 2026 14:38:02 -0700 Subject: [PATCH 2/2] fix(queries): migrate removed ProviderName/PublisherName columns to FOCUS 1.4 successors FOCUS 1.4 removes ProviderName and PublisherName from the Costs dataset; these queries read unversioned Costs(), which now resolves to the v1_4 schema and would fail on the removed columns. - costs-enriched-base.kql: ProviderName == 'Microsoft' -> HostProviderName == 'Microsoft' (infrastructure-provider check per the D3 mapping; identical behavior since down-conversion defines ProviderName = HostProviderName), with an explanatory comment. - top-other-transactions.kql: project ServiceProviderName (vendor that makes the service available - Marketplace publisher or Microsoft) in place of ProviderName/PublisherName for third-party purchase analysis. - finops-hub-database-guide.md: same HostProviderName fix in the "All available columns" example; Costs() table reference swaps the ProviderName/PublisherName rows for HostProviderName and ServiceProviderName. The Recommendations() and Transactions() table rows keep ProviderName - those datasets still carry it in v1_4 (hubs add-on column; not a FOCUS CostAndUsage dataset). Build-QueryCatalog.ps1 re-run to confirm a clean v1_4 catalog; its output (query-catalog.md) is gitignored, so there is nothing to commit. Co-Authored-By: Claude Fable 5 --- src/queries/catalog/costs-enriched-base.kql | 3 ++- src/queries/catalog/top-other-transactions.kql | 5 +++-- src/queries/finops-hub-database-guide.md | 7 ++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/queries/catalog/costs-enriched-base.kql b/src/queries/catalog/costs-enriched-base.kql index 98d66d707..3677b36a8 100644 --- a/src/queries/catalog/costs-enriched-base.kql +++ b/src/queries/catalog/costs-enriched-base.kql @@ -72,7 +72,8 @@ Costs() | extend x_CommitmentDiscountKey = iff(tmp_IsVMUsage and isnotempty(x_SkuDetails.ServiceType), strcat(x_SkuDetails.ServiceType, x_SkuMeterId), '') | extend x_CommitmentDiscountUtilizationPotential = case( ChargeCategory == 'Purchase', toreal(0), - ProviderName == 'Microsoft' and isnotempty(CommitmentDiscountCategory), toreal(EffectiveCost), + // HostProviderName (FOCUS 1.4) = infrastructure provider; replaces the removed ProviderName for "is this Microsoft-billed data" checks + HostProviderName == 'Microsoft' and isnotempty(CommitmentDiscountCategory), toreal(EffectiveCost), CommitmentDiscountCategory == 'Usage', toreal(ConsumedQuantity), CommitmentDiscountCategory == 'Spend', toreal(EffectiveCost), toreal(0) diff --git a/src/queries/catalog/top-other-transactions.kql b/src/queries/catalog/top-other-transactions.kql index ffca4f30f..4840f5a80 100644 --- a/src/queries/catalog/top-other-transactions.kql +++ b/src/queries/catalog/top-other-transactions.kql @@ -12,7 +12,8 @@ // // Output: // Each row represents a single cost record for a non-commitment purchase, with key financial and allocation metadata. -// Columns: ChargePeriodStart, ChargeCategory, BilledCost, BillingCurrency, SubAccountName, x_InvoiceSectionName, PricingCategory, PricingQuantity, PricingUnit, ProviderName, PublisherName +// Columns: ChargePeriodStart, ChargeCategory, BilledCost, BillingCurrency, SubAccountName, x_InvoiceSectionName, PricingCategory, PricingQuantity, PricingUnit, ServiceProviderName +// Note: ServiceProviderName (FOCUS 1.4) identifies the vendor (Marketplace publisher or Microsoft) and replaces the removed ProviderName/PublisherName columns. // // Usage: // Use this query to analyze miscellaneous Azure purchases that are not usage-based and not covered by Reserved Instances or Savings Plans. @@ -24,4 +25,4 @@ let endDate = startofmonth(now()); Costs() | where ChargePeriodStart >= startDate and ChargePeriodStart < endDate and tolower(tostring(ChargeCategory)) != 'usage' and isempty(CommitmentDiscountType) and toreal(BilledCost) > 0 | top N by toreal(BilledCost) -| project ChargePeriodStart, ChargeCategory, BilledCost, BillingCurrency, SubAccountName, x_InvoiceSectionName, PricingCategory, PricingQuantity, PricingUnit, ProviderName, PublisherName \ No newline at end of file +| project ChargePeriodStart, ChargeCategory, BilledCost, BillingCurrency, SubAccountName, x_InvoiceSectionName, PricingCategory, PricingQuantity, PricingUnit, ServiceProviderName \ No newline at end of file diff --git a/src/queries/finops-hub-database-guide.md b/src/queries/finops-hub-database-guide.md index a04e8efb1..9f57b9fb7 100644 --- a/src/queries/finops-hub-database-guide.md +++ b/src/queries/finops-hub-database-guide.md @@ -296,7 +296,8 @@ Costs() | extend x_CommitmentDiscountKey = iff(tmp_IsVMUsage and isnotempty(x_SkuDetails.ServiceType), strcat(x_SkuDetails.ServiceType, x_SkuMeterId), '') | extend x_CommitmentDiscountUtilizationPotential = case( ChargeCategory == 'Purchase', decimal(0), - ProviderName == 'Microsoft' and isnotempty(CommitmentDiscountCategory), EffectiveCost, + // HostProviderName (FOCUS 1.4) = infrastructure provider; replaces the removed ProviderName for "is this Microsoft-billed data" checks + HostProviderName == 'Microsoft' and isnotempty(CommitmentDiscountCategory), EffectiveCost, CommitmentDiscountCategory == 'Usage', ConsumedQuantity, CommitmentDiscountCategory == 'Spend', EffectiveCost, decimal(0) @@ -396,14 +397,13 @@ The following table lists the columns produced in the `All available columns` qu | ContractedCost | decimal | Negotiated cost for the resource or usage. | | ContractedUnitPrice | decimal | Negotiated unit price for the resource. | | EffectiveCost | decimal | Actual cost after all discounts and credits. | +| HostProviderName | string | Infrastructure provider that hosts the resource; always "Microsoft" for Cost Management data. Replaces the removed `ProviderName` (FOCUS 1.4). | | InvoiceIssuerName | string | Name of the invoice issuer. | | ListCost | decimal | List (retail) cost for the resource or usage. | | ListUnitPrice | decimal | List (retail) unit price for the resource. | | PricingCategory | string | Category of pricing (e.g., Standard, Spot). | | PricingQuantity | decimal | Quantity used for pricing. | | PricingUnit | string | Unit of measure for pricing. | -| ProviderName | string | Name of the cloud provider. | -| PublisherName | string | Name of the publisher. | | RegionId | string | Identifier for the region. | | RegionName | string | Name of the region. | | ResourceId | string | Unique identifier for the resource. | @@ -411,6 +411,7 @@ The following table lists the columns produced in the `All available columns` qu | ResourceType | string | Type of resource (e.g., Virtual Machine, SQL Database). | | ServiceCategory | string | High-level service category (e.g., Compute, Storage). | | ServiceName | string | Name of the Azure service. | +| ServiceProviderName | string | Vendor that makes the service available (Marketplace publisher or Microsoft); never null. Replaces the removed `PublisherName` and `ProviderName` (FOCUS 1.4). | | SkuId | string | Unique identifier for the SKU. | | SkuPriceId | string | Unique identifier for the SKU price. | | SubAccountId | string | Identifier for the sub-account or subscription. |