From 7913c70af24ef1fa6b648686343d456f03b3fb00 Mon Sep 17 00:00:00 2001 From: Michael Flanakin Date: Wed, 22 Jan 2025 04:39:42 -0800 Subject: [PATCH] ADX dashboard starter (#1234) --- docs/_resources/changelog.md | 4 + src/templates/finops-hub/dashboard.json | 2923 +++++++++++++++++++++++ 2 files changed, 2927 insertions(+) create mode 100644 src/templates/finops-hub/dashboard.json diff --git a/docs/_resources/changelog.md b/docs/_resources/changelog.md index e3a6ebe5e..ee15db5c1 100644 --- a/docs/_resources/changelog.md +++ b/docs/_resources/changelog.md @@ -100,6 +100,10 @@ Legend: 🏦 FinOps hubs {: .fs-5 .fw-500 .mt-4 mb-0 } +> ➕ Added: +> +> 1. Added Data Explorer dashboard template. +> > ✏️ Changed: > > 1. Update required permissions on hubs page [Required permissions](../docs/_reporting/hubs/README.md). diff --git a/src/templates/finops-hub/dashboard.json b/src/templates/finops-hub/dashboard.json new file mode 100644 index 000000000..acd023613 --- /dev/null +++ b/src/templates/finops-hub/dashboard.json @@ -0,0 +1,2923 @@ +{ + "$schema": "https://dataexplorer.azure.com/static/d/schema/52/dashboard.json", + "id": "a20bfb32-a3e1-4854-bc9f-e93b86e40813", + "eTag": "b33a0cc6-40e5-48d1-8eef-0cfe87d14653", + "schema_version": "52", + "title": "FinOps hub", + "tiles": [ + { + "id": "acf2ca3d-9d8f-477f-b259-f3937bf938d4", + "title": "Cost last month", + "visualType": "multistat", + "pageId": "f416685d-f559-4514-8e45-5e0e09aec286", + "layout": { "x": 0, "y": 3, "width": 4, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "152f2041-bbc1-41e4-b155-271b2e0cf6e9" }, + "visualOptions": { + "multiStat__textSize": "large", + "multiStat__valueColumn": null, + "colorRulesDisabled": true, + "colorStyle": "light", + "multiStat__displayOrientation": "horizontal", + "multiStat__labelColumn": null, + "multiStat__slot": { "width": 1, "height": 2 }, + "colorRules": [] + } + }, + { + "id": "595e39e5-02ff-4ee7-99f9-68694ffd0495", + "title": "Cost over time", + "visualType": "column", + "pageId": "f416685d-f559-4514-8e45-5e0e09aec286", + "layout": { "x": 4, "y": 3, "width": 17, "height": 4 }, + "queryRef": { "kind": "query", "queryId": "bc24e050-f2b9-4b4a-a08d-69fc4a4bb95e" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "left", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "efd2b03d-c80d-4d78-b77a-efa3f932efdb", + "title": "Change over time", + "visualType": "column", + "pageId": "f416685d-f559-4514-8e45-5e0e09aec286", + "layout": { "x": 4, "y": 7, "width": 17, "height": 4 }, + "queryRef": { "kind": "query", "queryId": "0d91ea4a-c81d-4a21-b708-b6af37be1eec" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "left", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "9c5e208a-f0ce-4e2e-9969-35130eef22c1", + "title": "Counts", + "visualType": "multistat", + "pageId": "f416685d-f559-4514-8e45-5e0e09aec286", + "layout": { "x": 0, "y": 11, "width": 12, "height": 4 }, + "queryRef": { "kind": "query", "queryId": "f2cecbb0-13f8-4642-afa4-bbcc0558f777" }, + "visualOptions": { + "multiStat__textSize": "auto", + "multiStat__valueColumn": null, + "colorRulesDisabled": false, + "colorStyle": "light", + "multiStat__displayOrientation": "horizontal", + "multiStat__labelColumn": null, + "multiStat__slot": { "width": 4, "height": 1 }, + "colorRules": [] + } + }, + { + "id": "2a1ee947-f1e3-447e-9388-91e318068608", + "title": "Counts (last n days)", + "visualType": "multistat", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 15, "width": 6, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "5d63e04d-1a11-4307-96f1-ebbf68e09be0" }, + "visualOptions": { + "multiStat__textSize": "auto", + "multiStat__valueColumn": null, + "colorRulesDisabled": true, + "colorStyle": "light", + "multiStat__displayOrientation": "vertical", + "multiStat__labelColumn": null, + "multiStat__slot": { "width": 2, "height": 2 }, + "colorRules": [ + { + "id": "414e8053-b30c-40dd-9f3f-510910d54d83", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "column": null, "operator": ">", "values": [""] }], + "chainingOperator": "and", + "colorStyle": "bold", + "color": null, + "tag": "", + "icon": null, + "ruleName": "", + "visualType": "multistat" + } + ] + } + }, + { + "id": "49534f2e-97ea-4b41-87c2-5e0f4bc26db8", + "title": "Effective cost", + "visualType": "column", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 6, "y": 2, "width": 16, "height": 9 }, + "queryRef": { "kind": "query", "queryId": "290e7eab-8159-4338-8531-85e2718cedb1" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "Effective cost", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [ + { + "id": "e7c54e29-4843-465c-ab63-75e816da8fe0", + "columns": ["Change"], + "label": "% change", + "yAxisMaximumValue": null, + "yAxisMinimumValue": null, + "yAxisScale": "linear", + "horizontalLines": [] + } + ], + "showMultiplePanels": true + }, + "hideLegend": true, + "legendLocation": "left", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "8e17c9f7-c513-4b93-bab8-44d3b0e48e9c", + "title": "", + "visualType": "markdownCard", + "pageId": "969ddf4c-8f2a-4ec4-9588-bb2f39473c9f", + "layout": { "x": 0, "y": 0, "width": 18, "height": 6 }, + "markdownText": "# FinOps hubs 0.8 (January 2025)\nThe FinOps hub dashboard provides several summaries of your cost and usage in aligment with the [FinOps Framework](https://aka.ms/ftk/fx/capabilities). All data formatted based on the [FinOps Open Cost and Usage Specification (FOCUS)](https://aka.ms/finops/focus).\n\nMost of this dashboard is designed to work with effective (amortized) cost rather than billed (actual) cost. Amortization breaks down reservation and savings plan purchases and allocates costs to the resources that received the benefit to facilitate chargeback reporting. Effective costs will not match your invoice. For invoice reconciliation, refer to the **Invoicing** page.\n\n[Learn more](https://aka.ms/finops/hubs)\n", + "visualOptions": {} + }, + { + "id": "f5fc42ae-fb77-4df7-9407-5c9c3588dd84", + "title": "About the FinOps toolkit", + "visualType": "markdownCard", + "pageId": "969ddf4c-8f2a-4ec4-9588-bb2f39473c9f", + "layout": { "x": 18, "y": 0, "width": 4, "height": 6 }, + "markdownText": "FinOps hubs are part of the [FinOps toolkit](https://aka.ms/finops/toolkit), an open-source collection of FinOps solutions that help you manage and optimize your cost, usage, and carbon.\n\nTo contribute to the FinOps toolkit, [join us on GitHub](https://aka.ms/ftk).\n", + "visualOptions": {} + }, + { + "id": "570e40a5-f67a-4c4b-84f6-c207ed021812", + "title": "3-month running total trend", + "visualType": "column", + "pageId": "5838c918-4541-44fe-90d2-77306ef1e241", + "layout": { "x": 0, "y": 13, "width": 16, "height": 7 }, + "queryRef": { "kind": "query", "queryId": "d5ed469a-45ea-49a2-b305-b841050213cf" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "bottom", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "1ac02a9f-3c12-4828-a4dd-60a0d411f60c", + "title": "Running total - This month and last", + "visualType": "area", + "pageId": "5c57f940-6f0f-4e39-930b-b6e89bb758ad", + "layout": { "x": 0, "y": 3, "width": 16, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "10300876-866a-40d7-836d-b3a8783ecece" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "bottom", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "27ff6f92-2e6f-431f-bf3b-f36aad59b5f5", + "title": "3-month daily trend", + "visualType": "column", + "pageId": "5838c918-4541-44fe-90d2-77306ef1e241", + "layout": { "x": 0, "y": 20, "width": 16, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "9e41a624-d5f9-40c6-b47f-fef4b50ec3dd" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "bottom", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "97df5060-929c-4457-a7e9-47005c845f16", + "title": "3-month daily trend by subscription", + "visualType": "stackedcolumn", + "pageId": "5838c918-4541-44fe-90d2-77306ef1e241", + "layout": { "x": 0, "y": 25, "width": 16, "height": 7 }, + "queryRef": { "kind": "query", "queryId": "f26e2204-270e-4219-8f68-5acef1c9393f" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "dad96fbb-750c-47a3-bd2e-e2bee74ebd22", + "title": "Cost + savings running total (this month and last)", + "visualType": "stackedarea", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 6, "y": 11, "width": 16, "height": 7 }, + "queryRef": { "kind": "query", "queryId": "dcc1f533-e5f9-4855-9e4c-21e21fcdf943" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "Cost + savings", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "bottom", + "xColumnTitle": "", + "xColumn": null, + "yColumns": ["EffectiveCostRunningTotal", "NegotiatedDiscountSavingsRunningTotal", "CommitmentDiscountSavingsRunningTotal"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "66dcd731-a141-47b2-b36a-53a138cb75f2", + "title": "Summary", + "visualType": "multistat", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 2, "width": 6, "height": 13 }, + "queryRef": { "kind": "query", "queryId": "e8b343dc-7430-4487-8d44-ef48ac454f2d" }, + "visualOptions": { + "multiStat__textSize": "auto", + "multiStat__valueColumn": null, + "colorRulesDisabled": false, + "colorStyle": "light", + "multiStat__displayOrientation": "vertical", + "multiStat__labelColumn": null, + "multiStat__slot": { "width": 2, "height": 4 }, + "colorRules": [ + { + "id": "a45d5307-a815-4baa-9743-d142253dc699", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "IsThisMonth", "values": ["true"] }], + "chainingOperator": "and", + "colorStyle": "light", + "color": "blue", + "tag": "This month", + "icon": null, + "ruleName": "This month", + "visualType": "multistat" + }, + { + "id": "a1307a22-3b48-48a9-9c1b-ef6b6a228796", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "IsThisMonth", "values": ["false"] }], + "chainingOperator": "and", + "colorStyle": "light", + "color": "green", + "tag": "Last month", + "icon": null, + "ruleName": "Last month", + "visualType": "multistat" + } + ] + } + }, + { + "id": "04cb63d9-0a92-488f-b863-815466d6725c", + "title": "Summary", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 23, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "c077a6d4-719f-42fe-b39b-36f77dc68976" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "4faba5ce-4190-45f9-b41e-5d9c6a9c8098", + "title": "Summary", + "visualType": "table", + "pageId": "5c57f940-6f0f-4e39-930b-b6e89bb758ad", + "layout": { "x": 0, "y": 11, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "3d947a7c-edca-46b5-a862-de77a725c85f" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "890e0366-a9a5-4001-bc6e-f1b7f23fa8a7", + "title": "Effective cost by subscription", + "visualType": "table", + "pageId": "5c57f940-6f0f-4e39-930b-b6e89bb758ad", + "layout": { "x": 0, "y": 16, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "3886b5cd-34a8-42d7-9e16-33ea4d236953" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "e47767ba-1884-4ca7-8458-24025b92464a", + "title": "", + "visualType": "markdownCard", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 58, "width": 22, "height": 4 }, + "markdownText": "# Regions\r\nEffective cost breakdown by region\r\n\r\n⬆️ [Top](?tile=e3ac3bbc-a9ef-44dd-828f-226afbcfda33)", + "visualOptions": {} + }, + { + "id": "d3e265ff-2c5a-4a03-a8b8-e0b4e10cf362", + "title": "Monthly trend by region", + "visualType": "stackedcolumn", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 62, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "d5224d06-c8e7-4dd9-afec-595b39712f5a" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "c54de4ff-e793-49b7-b33d-db22fccd0290", + "title": "Monthly trend by region", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 67, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "0dcf2c54-7f1d-45e9-a53b-d598a24493a4" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "b2916ba0-cb54-433d-89a1-8905b8d8618a", + "title": "Monthly trend by service name", + "visualType": "stackedcolumn", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 45, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "30644718-defd-4c6c-9ffa-a9c2cd1f871f" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "6208961b-6249-4fd4-a2d6-16b5e58b9baa", + "title": "Monthly trend by service name", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 50, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "6259f773-593c-4953-898c-15aa5ff6e53a" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "4956ec68-b338-4926-bd72-ae6ca9e886d6", + "title": "", + "visualType": "markdownCard", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 75, "width": 22, "height": 4 }, + "markdownText": "# Subscriptions\r\nEffective cost breakdown by subscription (subaccount)\r\n\r\n⬆️ [Top](?tile=e3ac3bbc-a9ef-44dd-828f-226afbcfda33)", + "visualOptions": {} + }, + { + "id": "b28897e5-0606-4112-a13a-0cd814055ea7", + "title": "Monthly trend by subscription", + "visualType": "stackedcolumn", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 79, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "21a87abe-19e2-44ec-8298-ba872e66c162" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "7b24b810-3cd3-4b7c-92cc-6b40f071b24d", + "title": "Monthly trend by subscription", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 84, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "90502e9a-2d0d-4ae4-8d9d-cc21f9b72d5d" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "f56a2d38-7d69-4dfd-8cc8-6b7a292758b1", + "title": "Monthly trend by resource group", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 101, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "c2c65ec0-e57d-4834-8a6b-b5975afeb9a0" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "d2672640-0e48-47e5-a253-de927a77a637", + "title": "Monthly trend by resource group", + "visualType": "stackedcolumn", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 96, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "61b26784-6a73-4e80-85b2-9c5cfbd2dd06" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "6750ce15-ec4e-4c60-8079-b00a4b462d63", + "title": "", + "visualType": "markdownCard", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 92, "width": 22, "height": 4 }, + "markdownText": "# Resource groups\r\nEffective cost breakdown by resource group\r\n\r\n⬆️ [Top](?tile=e3ac3bbc-a9ef-44dd-828f-226afbcfda33)", + "visualOptions": {} + }, + { + "id": "52055726-2788-4216-b813-9d91714c5953", + "title": "", + "visualType": "markdownCard", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 109, "width": 22, "height": 4 }, + "markdownText": "# Resources\r\nEffective cost breakdown by resource\r\n\r\n⬆️ [Top](?tile=e3ac3bbc-a9ef-44dd-828f-226afbcfda33)", + "visualOptions": {} + }, + { + "id": "d84a014f-0b68-490b-a522-fba66fee1e0f", + "title": "Monthly trend by resource", + "visualType": "stackedcolumn", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 113, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "3924981c-23e4-464d-a872-045df1752750" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "586ebe0b-ff5c-4794-91a1-a8ec845cad3a", + "title": "Monthly trend by resource", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 123, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "c7be613e-deb4-4779-ad75-4445e8d5e01f" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "c03c1e57-5e66-4eb1-a20b-10c887eb2140", + "title": "Daily trend by resource", + "visualType": "stackedcolumn", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 118, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "49e24ee0-91de-4b1c-973f-036a3c060aca" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "d9960334-1cff-4686-9d4a-e6afc5574aa7", + "title": "", + "visualType": "markdownCard", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 28, "width": 22, "height": 4 }, + "markdownText": "# Services\r\nEffective cost breakdown by service category and service name\r\n\r\n⬆️ [Top](?tile=e3ac3bbc-a9ef-44dd-828f-226afbcfda33)", + "visualOptions": {} + }, + { + "id": "700f736d-56b1-4194-8282-891683f63134", + "title": "Monthly trend by service category", + "visualType": "stackedcolumn", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 32, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "4c7a7614-9b8c-415b-a4e1-d2d53c023d31" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "97872267-01c6-44f9-ad0d-34940d4b58fa", + "title": "Monthly trend by service category", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 37, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "1d273b55-d2ea-427c-8a5f-01f6c240e98a" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "a8edc317-353b-4648-9d32-e73e0d0a2894", + "title": "", + "visualType": "markdownCard", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 131, "width": 22, "height": 4 }, + "markdownText": "# Resource inventory\r\nSummary of resources and their costs\r\n\r\n⬆️ [Top](?tile=e3ac3bbc-a9ef-44dd-828f-226afbcfda33)", + "visualOptions": {} + }, + { + "id": "e26eb29d-8021-406c-a84e-5568ddd234f4", + "title": "Monthly trend by resource type", + "visualType": "stackedcolumn", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 154, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "90e30901-a931-4a1d-b81e-0a1821032c3c" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "8d63f5d3-b1d8-4117-a358-bce7939a13ae", + "title": "Daily trend by resource type (last n days)", + "visualType": "stackedcolumn", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 141, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "ebe41e27-e9f9-478e-ab90-fd1f87906766" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "8caa438b-10a8-418c-ab3b-5c5aee53d3e6", + "title": "Monthly trend by resource", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 159, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "7f7b08a9-ae15-46f8-8b0f-767280375add" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "011c2b2c-a232-4459-acf4-8db4055f4f70", + "title": "Most cost (last n days)", + "visualType": "bar", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 17, "y": 146, "width": 5, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "a35b4c05-8ecb-4c51-9aaf-980af3d7923e" }, + "description": "Uses the Daily trend parameter for the lookback period", + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": ["EffectiveCost", "ResourceCount"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "4495e71e-1005-4224-91f4-8103f06981da", + "title": "Most used (last n days)", + "visualType": "bar", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 12, "y": 146, "width": 5, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "9c5d3cf0-b6cb-45a2-acfd-b19df425bddf" }, + "description": "Uses the Daily trend parameter for the lookback period", + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": ["EffectiveCost", "ResourceCount"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "38ffb57b-4646-4944-a92b-6966a3a6a807", + "title": "Resource type summary (last n days)", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 146, "width": 12, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "2d7b6447-2769-40b8-958a-f252dab68b1e" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "a83872cb-44ef-402a-8512-b9d5ba04744e", + "title": "Resource inventory summary (last n days)", + "visualType": "multistat", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 135, "width": 22, "height": 6 }, + "queryRef": { "kind": "query", "queryId": "f062533b-8c94-412f-bf83-0eb5cd06063d" }, + "hideTitle": true, + "visualOptions": { + "multiStat__textSize": "auto", + "multiStat__valueColumn": "Value", + "colorRulesDisabled": false, + "colorStyle": "light", + "multiStat__displayOrientation": "horizontal", + "multiStat__labelColumn": null, + "multiStat__slot": { "width": 4, "height": 2 }, + "colorRules": [] + } + }, + { + "id": "5bd3258c-034c-4e23-b543-7cdf87bd153d", + "title": "", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 102, "width": 22, "height": 4 }, + "markdownText": "# SKU prices\r\nSummary of the SKUs used and their applicable discounts\r\n\r\n⬆️ [Top](?tile=c0bd4bc4-a910-4a74-89a9-d4ae0f995563)", + "visualOptions": {} + }, + { + "id": "9d9838ca-63b2-4239-b2a7-346273bc2b86", + "title": "", + "visualType": "markdownCard", + "pageId": "ea47329e-0bc9-4c11-b110-534878dbb3ad", + "layout": { "x": 0, "y": 0, "width": 22, "height": 5 }, + "markdownText": "# Understand uage and cost\nThe **Understand usage and cost** domain is focused on data acquisition, reporting, analysis, and alerting on top of your cost, usage, and carbon consumption. This domain focuses on observability and business intelligence. It involves gathering data (ingestion), organizing it for the organization (allocation), generating reports (reporting), and monitoring to proactively identify and address issues (anomalies).\n\n[Learn more](https://learn.microsoft.com/cloud-computing/finops/framework/understand/understand-cloud-usage-cost)\n", + "visualOptions": {} + }, + { + "id": "679acf08-65b5-434c-a0fc-29e178c958c3", + "title": "", + "visualType": "markdownCard", + "pageId": "ea47329e-0bc9-4c11-b110-534878dbb3ad", + "layout": { "x": 0, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Data ingestion\nData ingestion refers to the process of collecting, transforming, and organizing data from various sources into a single, easily accessible repository. With this capability, you identify data sources needed to support your FinOps practice and facilitate FinOps tasks.\n\n \n\n \n\n📊 [View report](#9e099251-9658-48da-b416-80422a2a47c7)\n   \n📗 [Learn more](http://aka.ms/ftk/fx/ingestion)", + "visualOptions": {} + }, + { + "id": "0d15a5a6-6e0e-4825-8cad-77f660b000da", + "title": "", + "visualType": "markdownCard", + "pageId": "ea47329e-0bc9-4c11-b110-534878dbb3ad", + "layout": { "x": 5, "y": 5, "width": 6, "height": 7 }, + "markdownText": "### Allocation\nAllocation is the process of attributing, assigning, and redistributing shared costs and usage by using accounts, tags, and other metadata. It helps establish accountability among teams and projects within an organization. With this capability, you identify the metadata needed to map cost, usage, and carbon data to the teams responsible. This capability is critical to support organizational reporting and driving the right level of accountability.\n\n \n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/allocation)\n", + "visualOptions": {} + }, + { + "id": "c249daec-c935-4669-b6fd-00d1b3fc8818", + "title": "", + "visualType": "markdownCard", + "pageId": "ea47329e-0bc9-4c11-b110-534878dbb3ad", + "layout": { "x": 11, "y": 5, "width": 6, "height": 7 }, + "markdownText": "### Reporting + analytics\nReporting and analytics involve analyzing cloud data and creating reports to understand usage and spending patterns. It helps identify opportunities for improvement and supports informed decision-making about cloud resources. With this capability, you identify and build the reports and reporting infrastructure needed to facilitate other FinOps capabilities. This capability is critical to ensuring proper visibility and transparency and unblocks monitoring and optimization at scale across the organization.\n\n \n\n📊 [View report](#f8ee3008-df7e-442f-825e-2e3b46e4c185)\n   \n📗 [Learn more](http://aka.ms/ftk/fx/reporting)\n", + "visualOptions": {} + }, + { + "id": "652a4347-742c-42d2-aa43-39459b1e71c6", + "title": "", + "visualType": "markdownCard", + "pageId": "ea47329e-0bc9-4c11-b110-534878dbb3ad", + "layout": { "x": 17, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Anomaly management\nAnomaly management refers to the practice of detecting and addressing abnormal or unexpected cost and usage patterns in a timely manner. With this capability, you identify, triage, and address unexpected changes in cost, usage, and carbon. This capability is especially important with usage-based billing and sustainability models, where small fluctuations in usage can result in large fiscal and environmental impact.\n\n📊 [View report](#5838c918-4541-44fe-90d2-77306ef1e241)\n   \n📗 [Learn more](http://aka.ms/ftk/fx/anomalies)\n", + "visualOptions": {} + }, + { + "id": "6ea8b37d-617b-47dd-add0-8e3c0f708540", + "title": "", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 91, "width": 22, "height": 4 }, + "markdownText": "# Purchases\r\nCosts from commitment discount, Marketplace, and other purchases\r\n\r\n⬆️ [Top](?tile=c0bd4bc4-a910-4a74-89a9-d4ae0f995563)", + "visualOptions": {} + }, + { + "id": "e3ac3bbc-a9ef-44dd-828f-226afbcfda33", + "title": "On this page", + "visualType": "markdownCard", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 0, "width": 22, "height": 2 }, + "markdownText": "  [Services](?tile=d9960334-1cff-4686-9d4a-e6afc5574aa7)\r\n• [Regions](?tile=e47767ba-1884-4ca7-8458-24025b92464a)\r\n• [Subscriptions](?tile=4956ec68-b338-4926-bd72-ae6ca9e886d6)\r\n• [Resource groups](?tile=6750ce15-ec4e-4c60-8079-b00a4b462d63)\r\n• [Resources](?tile=52055726-2788-4216-b813-9d91714c5953)\r\n• [Inventory](?tile=a8edc317-353b-4648-9d32-e73e0d0a2894)", + "visualOptions": {} + }, + { + "id": "00b9ea3a-3902-4234-806f-1a7bf87b3992", + "title": "Daily trend", + "visualType": "column", + "pageId": "5838c918-4541-44fe-90d2-77306ef1e241", + "layout": { "x": 0, "y": 3, "width": 16, "height": 10 }, + "queryRef": { "kind": "query", "queryId": "1d9c166d-22b6-48fd-9a90-9f983083ecc7" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "Effective cost", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [ + { + "id": "e7c54e29-4843-465c-ab63-75e816da8fe0", + "columns": ["Change"], + "label": "% change", + "yAxisMaximumValue": null, + "yAxisMinimumValue": null, + "yAxisScale": "linear", + "horizontalLines": [] + } + ], + "showMultiplePanels": true + }, + "hideLegend": true, + "legendLocation": "left", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "c0bd4bc4-a910-4a74-89a9-d4ae0f995563", + "title": "On this page", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 0, "width": 22, "height": 2 }, + "markdownText": "  [Savings](?tile=fa177e0f-9a74-4475-b64d-a399224e96e0)\r\n• [Commitment discounts](?tile=cad5d666-02e8-4319-bbad-1bdf46ca2961)\r\n• [Purchases](?tile=6ea8b37d-617b-47dd-add0-8e3c0f708540)\r\n• [SKU prices](?tile=5bd3258c-034c-4e23-b543-7cdf87bd153d)\r\n", + "visualOptions": {} + }, + { + "id": "72aa5a62-e129-4ffa-be62-82c833282d27", + "title": "SKUs with negotiated discounts (last n days)", + "visualType": "table", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 106, "width": 14, "height": 6 }, + "queryRef": { "kind": "query", "queryId": "af6424d4-8f73-4b81-bfdd-f0287ebcaaca" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "3d7688f7-0a1c-4564-b851-f380a22817bf", + "title": "SKUs with commitment discounts (last n days)", + "visualType": "table", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 112, "width": 14, "height": 6 }, + "queryRef": { "kind": "query", "queryId": "c4f6542d-a9cb-4284-bd4e-b9f94ad02192" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "b2c9dcef-b40d-4dad-a0a3-cb5fe2c77156", + "title": "SKUs with no discounts (last n days)", + "visualType": "table", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 118, "width": 14, "height": 6 }, + "queryRef": { "kind": "query", "queryId": "00ae3917-c783-45f6-a04e-9113e4c5d445" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "a3d814b8-ff20-4919-ae2a-f1caec997edf", + "title": "Most used SKUs (last n days)", + "visualType": "bar", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 14, "y": 106, "width": 8, "height": 18 }, + "queryRef": { "kind": "query", "queryId": "d8a4634e-7ebe-47ce-83b5-ff7f50f6bee6" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "bottom", + "xColumnTitle": "", + "xColumn": "SKU", + "yColumns": ["EffectiveCost"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "18517864-8a43-4f0c-80e3-863554f1b189", + "title": "", + "visualType": "markdownCard", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 167, "width": 22, "height": 4 }, + "markdownText": "# Purchases\r\nCosts from commitment discount, Marketplace, and other purchases\r\n\r\n⬆️ [Top](?tile=c0bd4bc4-a910-4a74-89a9-d4ae0f995563)", + "visualOptions": {} + }, + { + "id": "4383c893-8839-4678-88c6-9a6393595d0a", + "title": "Purchases", + "visualType": "table", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 0, "y": 171, "width": 15, "height": 7 }, + "queryRef": { "kind": "query", "queryId": "98c9b9b5-bebf-41f8-8319-5fa2523f9dd0" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "84da605b-6a0d-4a2a-aac3-a4160f9de10d", + "title": "Purchases", + "visualType": "table", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 95, "width": 22, "height": 7 }, + "queryRef": { "kind": "query", "queryId": "35a3a2b3-4ab0-4449-96f7-c78db789089e" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "ea97e18e-5253-4a9d-9eed-0f2fc45b3c5b", + "title": "Cost summary", + "description": "List cost is based on retail prices without any discounts, contracted cost includes negotiated discounts, and effective cost includes commitment and negotiated discounts.", + "visualType": "bar", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 6, "y": 18, "width": 8, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "5ff29428-de83-4a2c-8f86-d8beebe68750" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "bottom", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "d9959281-dc89-44fc-a2b3-b4f5227e0179", + "title": "Savings summary", + "description": "Negotiated discounts are based on your contractual agreement and represented in the \"contracted cost\". Commitment discounts are based on reservations and savings plans and represented in the \"effective cost\".", + "visualType": "bar", + "pageId": "f8ee3008-df7e-442f-825e-2e3b46e4c185", + "layout": { "x": 14, "y": 18, "width": 8, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "f5f240a8-a818-4f27-bdfb-e96fcfe433bd" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "bottom", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "cad5d666-02e8-4319-bbad-1bdf46ca2961", + "title": "", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 51, "width": 22, "height": 4 }, + "markdownText": "# Commitment discounts\r\nCommitment discount usage and costs\r\n\r\n⬆️ [Top](?tile=c0bd4bc4-a910-4a74-89a9-d4ae0f995563)", + "visualOptions": {} + }, + { + "id": "36c1dede-49c9-4ae3-a19a-a230f87e9197", + "title": "Commitment discount usage (last n days)", + "visualType": "table", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 55, "width": 13, "height": 6 }, + "queryRef": { "kind": "query", "queryId": "d7f31381-ba44-46a1-ad3e-dc6b8826706d" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "9513d9d7-be4a-468c-aed0-f0076c9bf3c4", + "title": "Savings summary (last n months)", + "visualType": "multistat", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 11, "width": 15, "height": 9 }, + "queryRef": { "kind": "query", "queryId": "e17346d1-0227-4aa4-8765-f9b4bf43bed5" }, + "visualOptions": { + "multiStat__textSize": "auto", + "multiStat__valueColumn": "Value", + "colorRulesDisabled": false, + "colorStyle": "light", + "multiStat__displayOrientation": "horizontal", + "multiStat__labelColumn": "Label", + "multiStat__slot": { "width": 5, "height": 3 }, + "colorRules": [ + { + "id": "a45d5307-a815-4baa-9743-d142253dc699", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["List"] }], + "chainingOperator": "and", + "colorStyle": "light", + "color": "red", + "tag": "List cost", + "icon": null, + "ruleName": "List cost", + "visualType": "multistat" + }, + { + "id": "a1307a22-3b48-48a9-9c1b-ef6b6a228796", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["Contracted"] }], + "chainingOperator": "and", + "colorStyle": "light", + "color": "yellow", + "tag": "Contracted cost", + "icon": null, + "ruleName": "Contracted cost", + "visualType": "multistat" + }, + { + "id": "65c6cac8-64f6-4029-bca0-b09dbfef9516", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["Effective"] }], + "chainingOperator": "and", + "colorStyle": "light", + "color": "green", + "tag": "Effective cost", + "icon": null, + "ruleName": "Effective cost", + "visualType": "multistat" + }, + { + "id": "33f99591-c8a6-4aae-be3f-a613bbc85c28", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["PartialSavings"] }], + "chainingOperator": "and", + "colorStyle": "bold", + "color": "blue", + "tag": "Partial savings", + "icon": null, + "ruleName": "Partial savings", + "visualType": "multistat" + }, + { + "id": "55430568-c3ef-4ff7-84b9-f3f82fe1a05a", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["TotalSavings"] }], + "chainingOperator": "and", + "colorStyle": "bold", + "color": "green", + "tag": "Total savings", + "icon": null, + "ruleName": "Total savings", + "visualType": "multistat" + } + ] + } + }, + { + "id": "9aec9f5c-f7cc-48da-8f0d-303137623945", + "title": "Savings summary (last n days)", + "visualType": "multistat", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 36, "width": 15, "height": 9 }, + "queryRef": { "kind": "query", "queryId": "f1ef29df-7a1d-4dd0-8619-0c0164707b31" }, + "visualOptions": { + "multiStat__textSize": "auto", + "multiStat__valueColumn": "Value", + "colorRulesDisabled": false, + "colorStyle": "light", + "multiStat__displayOrientation": "horizontal", + "multiStat__labelColumn": "Label", + "multiStat__slot": { "width": 5, "height": 3 }, + "colorRules": [ + { + "id": "a45d5307-a815-4baa-9743-d142253dc699", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["List"] }], + "chainingOperator": "and", + "colorStyle": "light", + "color": "red", + "tag": "List cost", + "icon": null, + "ruleName": "List cost", + "visualType": "multistat" + }, + { + "id": "a1307a22-3b48-48a9-9c1b-ef6b6a228796", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["Contracted"] }], + "chainingOperator": "and", + "colorStyle": "light", + "color": "yellow", + "tag": "Contracted cost", + "icon": null, + "ruleName": "Contracted cost", + "visualType": "multistat" + }, + { + "id": "65c6cac8-64f6-4029-bca0-b09dbfef9516", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["Effective"] }], + "chainingOperator": "and", + "colorStyle": "light", + "color": "green", + "tag": "Effective cost", + "icon": null, + "ruleName": "Effective cost", + "visualType": "multistat" + }, + { + "id": "33f99591-c8a6-4aae-be3f-a613bbc85c28", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["PartialSavings"] }], + "chainingOperator": "and", + "colorStyle": "bold", + "color": "blue", + "tag": "Partial savings", + "icon": null, + "ruleName": "Partial savings", + "visualType": "multistat" + }, + { + "id": "55430568-c3ef-4ff7-84b9-f3f82fe1a05a", + "ruleType": "colorByCondition", + "applyToColumn": null, + "hideText": false, + "applyTo": "cells", + "conditions": [{ "operator": "==", "column": "Type", "values": ["TotalSavings"] }], + "chainingOperator": "and", + "colorStyle": "bold", + "color": "green", + "tag": "Total savings", + "icon": null, + "ruleName": "Total savings", + "visualType": "multistat" + } + ] + } + }, + { + "id": "e8018da4-7269-4e91-9f32-4bcf390746af", + "title": "Commitment discount breakdown (last n months)", + "visualType": "multistat", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 15, "y": 11, "width": 7, "height": 9 }, + "queryRef": { "kind": "query", "queryId": "7d0c2c1f-338b-4534-b173-36b284779131" }, + "visualOptions": { + "multiStat__textSize": "auto", + "multiStat__valueColumn": "Value", + "colorRulesDisabled": true, + "colorStyle": "light", + "multiStat__displayOrientation": "horizontal", + "multiStat__labelColumn": "Label", + "multiStat__slot": { "width": 2, "height": 2 }, + "colorRules": [] + } + }, + { + "id": "8dd83ee9-6692-4b94-a8c3-68caa7adbb64", + "title": "Commitment discount breakdown (last n days)", + "visualType": "multistat", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 15, "y": 36, "width": 7, "height": 9 }, + "queryRef": { "kind": "query", "queryId": "84ecad69-79ac-45b9-a8af-60be28dcc748" }, + "visualOptions": { + "multiStat__textSize": "auto", + "multiStat__valueColumn": "Value", + "colorRulesDisabled": true, + "colorStyle": "light", + "multiStat__displayOrientation": "horizontal", + "multiStat__labelColumn": "Label", + "multiStat__slot": { "width": 2, "height": 2 }, + "colorRules": [] + } + }, + { + "id": "e69fe03b-606c-4b93-b9b5-6f1048b24deb", + "title": "Monthly trend by service category", + "visualType": "table", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 26, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "85320475-730b-411f-98d5-fbc345bf5e68" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "df06246e-5feb-4fd1-bcb0-c04448ac4c80", + "title": "Monthly savings trend", + "visualType": "stackedcolumn", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 20, "width": 15, "height": 6 }, + "queryRef": { "kind": "query", "queryId": "5bbb5369-ac95-45fc-853c-a6a2ce6a9e7b" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "fa177e0f-9a74-4475-b64d-a399224e96e0", + "title": "", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 5, "width": 22, "height": 4 }, + "markdownText": "# Savings\r\nSummary of negotiated and commitment discount savings\r\n\r\n⬆️ [Top](?tile=c0bd4bc4-a910-4a74-89a9-d4ae0f995563)", + "visualOptions": {} + }, + { + "id": "8f92a18b-9000-48f8-952a-5f21c535105c", + "title": "Total savings (last n months)", + "visualType": "pie", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 15, "y": 20, "width": 7, "height": 6 }, + "queryRef": { "kind": "query", "queryId": "93f0eb9f-fa4d-4c54-96c2-8c1d3387d13a" }, + "visualOptions": { + "hideLegend": false, + "legendLocation": "right", + "xColumn": "Type", + "yColumns": null, + "seriesColumns": null, + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "labelDisabled": false, + "pie__label": ["name", "percentage"], + "tooltipDisabled": false, + "pie__tooltip": ["name", "percentage", "value"], + "pie__orderBy": "size", + "pie__kind": "pie", + "pie__topNSlices": null, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "b28fdb79-8d7a-414a-9da4-75ab9bffe134", + "title": "Daily savings trend", + "visualType": "stackedcolumn", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 45, "width": 15, "height": 6 }, + "queryRef": { "kind": "query", "queryId": "5c442903-65b0-4b53-9e7c-3ea9c1af7be5" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "088944a4-6cc6-4320-a8eb-82d35ee5b5d6", + "title": "Total savings (last n days)", + "visualType": "pie", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 15, "y": 45, "width": 7, "height": 6 }, + "queryRef": { "kind": "query", "queryId": "9a9ee4b0-a37d-475f-bf1d-f51573243491" }, + "visualOptions": { + "hideLegend": false, + "legendLocation": "right", + "xColumn": "Type", + "yColumns": null, + "seriesColumns": null, + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "labelDisabled": false, + "pie__label": ["name", "percentage"], + "tooltipDisabled": false, + "pie__tooltip": ["name", "percentage", "value"], + "pie__orderBy": "size", + "pie__kind": "pie", + "pie__topNSlices": null, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "bd461109-e42e-4329-a4b9-16a83c1ad9b3", + "title": "", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 9, "width": 22, "height": 2 }, + "markdownText": "## Monthly trend (last n months)", + "visualOptions": {} + }, + { + "id": "40a4e89e-e521-4fb1-bdca-95166b7c9267", + "title": "", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 34, "width": 22, "height": 2 }, + "markdownText": "## Daily trend (last n days)", + "visualOptions": {} + }, + { + "id": "cee8e33c-bb08-4f48-9c8e-c785985d16e5", + "title": "", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 61, "width": 22, "height": 2 }, + "markdownText": "## Subscription chargeback (last n months)", + "visualOptions": {} + }, + { + "id": "fad3f76a-1c81-4c4f-8787-99da226100d1", + "title": "", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 71, "width": 22, "height": 2 }, + "markdownText": "## Resource group chargeback (last n months)", + "visualOptions": {} + }, + { + "id": "b2c319c7-0ef0-477b-a80f-9b6e022b7e5e", + "title": "Commitment discount chargeback by resource group", + "visualType": "table", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 73, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "377e3693-0738-45d7-97d9-4b6e71ec5b36" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "e22f49e5-766c-4b35-8b4c-b99bef142d42", + "title": "Commitment discount chargeback by subscription", + "visualType": "table", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 63, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "13cad52d-91e7-4ab4-aad5-4aae21c1019a" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "c7e80308-bbb1-4aa8-a3d7-ce9eb0145f92", + "title": "Commitment discount usage by resource (last n days)", + "visualType": "table", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 83, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "dcf69b47-233e-4bc4-b914-3f6f09f4cb82" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "6e4a3743-e023-4fbc-a34d-43c08f201c6e", + "title": "", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 81, "width": 22, "height": 2 }, + "markdownText": "## Resources usage (last n days)", + "visualOptions": {} + }, + { + "id": "ab300a6a-3bbd-450b-942c-7f30113cba15", + "title": "On this page", + "visualType": "markdownCard", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 0, "width": 22, "height": 2 }, + "markdownText": "  [FinOps hubs](?tile=1e089e2c-d94a-4bfa-95e7-5f8b1249c982)\r\n• [Ingested data](?tile=10d7d4d3-0201-4cdf-977b-4814152fda24)", + "visualOptions": {} + }, + { + "id": "1e089e2c-d94a-4bfa-95e7-5f8b1249c982", + "title": "", + "visualType": "markdownCard", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 5, "width": 22, "height": 4 }, + "markdownText": "# FinOps hubs\r\nSummary of the cost and usage of FinOps hubs infrastructure\r\n\r\n⬆️ [Top](?tile=ab300a6a-3bbd-450b-942c-7f30113cba15)", + "visualOptions": {} + }, + { + "id": "05764729-51e4-4048-8cf8-2ac56eb3e643", + "title": "Monthly trend by hub instance", + "visualType": "stackedcolumn", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 9, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "d7a9ff96-da17-4826-9fb5-b23f4c7b938d" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "37a8bef0-7dfb-42b9-aeab-55f8c9c178b8", + "title": "Daily trend by hub instance", + "visualType": "stackedcolumn", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 14, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "13813a00-e634-4428-9eac-ea255fd1eaca" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": true, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "c48e07c5-f0a5-43e2-8a13-ee43ed1b92f9", + "title": "Monthly trend by hub instance", + "visualType": "table", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 19, "width": 22, "height": 8 }, + "queryRef": { "kind": "query", "queryId": "62bbceee-c089-45db-822c-0b4745358aa4" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": false, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "10d7d4d3-0201-4cdf-977b-4814152fda24", + "title": "", + "visualType": "markdownCard", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 27, "width": 22, "height": 4 }, + "markdownText": "# Ingested data\r\nSummary of the data that's been ingested into FinOps hubs\r\n\r\n⬆️ [Top](?tile=ab300a6a-3bbd-450b-942c-7f30113cba15)", + "visualOptions": {} + }, + { + "id": "0b192258-9639-4bd1-bffb-f0fbdcd14d1f", + "title": "Ingested data by table", + "visualType": "stackedcolumn", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 34, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "b98c9ed7-47b3-41c1-a596-fd9d32725b33" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": ["Rows"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "db78922e-5215-4b93-9762-212eb0e32bf3", + "title": "Ingested cost data by scope", + "visualType": "stackedcolumn", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 39, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "187e22fe-3d78-45a2-a2bf-090ece144fd1" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": ["Rows"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "c636ea6c-8356-4a69-a4d6-61e6596a3c4e", + "title": "Ingested scopes", + "visualType": "card", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 31, "width": 4, "height": 3 }, + "queryRef": { "kind": "query", "queryId": "d2c522dc-ef4b-4714-a473-09350e275557" }, + "visualOptions": { "multiStat__textSize": "auto", "multiStat__valueColumn": null, "colorRulesDisabled": false, "colorStyle": "light", "colorRules": [] } + }, + { + "id": "379b25b8-7188-4657-b82f-dee14b344bec", + "title": "Ingested months", + "visualType": "card", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 4, "y": 31, "width": 4, "height": 3 }, + "queryRef": { "kind": "query", "queryId": "6fe11b78-82ef-4e9a-8411-a65e5b0d8bba" }, + "visualOptions": { "multiStat__textSize": "auto", "multiStat__valueColumn": null, "colorRulesDisabled": false, "colorStyle": "light", "colorRules": [] } + }, + { + "id": "71b29fd4-2999-45dc-9e4b-14152c48a4f4", + "title": "Ingested price data by scope", + "visualType": "stackedcolumn", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 44, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "b3621977-59be-4f98-a034-a94479612115" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": ["Rows"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "29f1c705-131d-44b9-9bd6-368c93aedcdf", + "title": "Ingested recommendation data by scope", + "visualType": "stackedcolumn", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 49, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "4a2a77fe-e819-4059-b027-dab0a1770a0a" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": ["Rows"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "47471816-9569-4ff3-816b-98fbc47b5c17", + "title": "Ingested transaction data by scope", + "visualType": "stackedcolumn", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 54, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "8f1ad1ef-6f5e-4f20-a1c4-3941e871d0cd" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": ["Rows"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "fcedcd3b-cd11-42ab-8363-de9619fc2018", + "title": "Ingested commitment discount usage data by scope", + "visualType": "stackedcolumn", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 59, "width": 22, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "e9a9a135-6a74-4463-b69f-eac6930ff1f2" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "right", + "xColumnTitle": "", + "xColumn": null, + "yColumns": ["Rows"], + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "9", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + }, + { + "id": "e29123b0-320a-4d36-a5bd-14c1757af8b8", + "title": "About this domain", + "visualType": "markdownCard", + "pageId": "9e099251-9658-48da-b416-80422a2a47c7", + "layout": { "x": 0, "y": 2, "width": 22, "height": 3 }, + "markdownText": "Data ingestion refers to the process of collecting, transforming, and organizing data from various sources into a single, easily accessible repository. With this capability, you identify data sources needed to support your FinOps practice and facilitate FinOps tasks. [Learn more](http://aka.ms/ftk/fx/ingestion)", + "visualOptions": {} + }, + { + "id": "fe3644dd-bb95-4fee-b212-5e75374b3100", + "title": "", + "visualType": "markdownCard", + "pageId": "8beab65c-f5ec-4661-bc67-37b10baffb16", + "layout": { "x": 0, "y": 0, "width": 22, "height": 5 }, + "markdownText": "# Quantify business value\nThe **Quantify business value** domain focuses on analyzing cost, usage, and sustainability to align with organizational plans and measure the return on investment from cloud computing efforts. This domain is all about measuring and maximizing the business value each team and workload gets from the cloud to maximize future potential.\n\n[Learn more](https://learn.microsoft.com/cloud-computing/finops/framework/quantify/quantify-business-value)\n", + "visualOptions": {} + }, + { + "id": "353712a3-e590-4d4e-a041-54c4b3105c99", + "title": "", + "visualType": "markdownCard", + "pageId": "8beab65c-f5ec-4661-bc67-37b10baffb16", + "layout": { "x": 0, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Planning and estimating\nPlanning and estimating involve predicting the cost and usage of new and existing workloads based on potential architectural changes and shifting business priorities. With this capability, you establish baseline expectations for new cloud workloads and prepare for changes to existing workloads. This capability is an important part of establishing and maintaining organizational budgets.\n\n \n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/planning)", + "visualOptions": {} + }, + { + "id": "cbc699f4-0197-420a-a439-3c869bf48227", + "title": "", + "visualType": "markdownCard", + "pageId": "8beab65c-f5ec-4661-bc67-37b10baffb16", + "layout": { "x": 5, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Forecasting\nForecasting involves analyzing historical trends and future plans to predict costs, understand the impact on current budgets, and influence future budgets. With this capability, you'll project future cost, usage, and carbon emissions based on historical trends. This capability is a major part of establishing accurate budgets for each team.\n\n \n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/forecasting)", + "visualOptions": {} + }, + { + "id": "5206bf80-0c56-4d07-bedb-ab0dc15bffb5", + "title": "", + "visualType": "markdownCard", + "pageId": "8beab65c-f5ec-4661-bc67-37b10baffb16", + "layout": { "x": 10, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Budgeting\nBudgeting is the process of monitoring and managing financial plans and limits over a specific period to control spending effectively. This capability allows you to use established estimates and forecasts to allocate funds to each team for fiscal year planning and set up alerts to ensure budget accountability. This capability plays a key role in staying within established fiscal constraints on an ongoing basis.\n\n \n\n📊 [View report](#5c57f940-6f0f-4e39-930b-b6e89bb758ad)\n   \n📗 [Learn more](http://aka.ms/ftk/fx/budgeting)", + "visualOptions": {} + }, + { + "id": "566ad60b-4c09-45e4-aa2f-e6817c181a61", + "title": "", + "visualType": "markdownCard", + "pageId": "8beab65c-f5ec-4661-bc67-37b10baffb16", + "layout": { "x": 15, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Benchmarking\nBenchmarking is a systematic process of evaluating the performance and value of cloud services using efficiency metrics, either within an organization or against industry peers. This capability allows you to measure and track key performance indicators to identify and accelerate the adoption of successful initiatives, maximizing cloud return on investment (ROI) across teams and external organizations when applicable.\n\n \n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/benchmarking)", + "visualOptions": {} + }, + { + "id": "6282be37-d78a-4555-91e4-9c71dee8fcb7", + "title": "", + "visualType": "markdownCard", + "pageId": "8beab65c-f5ec-4661-bc67-37b10baffb16", + "layout": { "x": 0, "y": 12, "width": 5, "height": 7 }, + "markdownText": "### Unit economics\nUnit economics refers to the process of calculating the cost and carbon emissions of a single unit of a business that can show the business value of the cloud. With this capability, you break down cost, usage, and carbon emissions and compare that with the business value per unit to identify high- and low-value workloads. This capability helps you identify areas that can be scaled out to accelerate business value through specific technology decisions.\n\n \n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/uniteconomics)", + "visualOptions": {} + }, + { + "id": "c19ca143-e39b-4407-9592-cbaf87a37529", + "title": "", + "visualType": "markdownCard", + "pageId": "d01a8154-8a60-4d22-96ea-54b45b1417fe", + "layout": { "x": 0, "y": 0, "width": 22, "height": 5 }, + "markdownText": "# Optimize usage and cost\nThe **Optimize usage and cost** domain focused on designing and optimizing solutions for efficiency to ensure you get the most out of your cloud investments.\n\n[Learn more](https://learn.microsoft.com/cloud-computing/finops/framework/optimize/optimize-cloud-usage-cost)\n", + "visualOptions": {} + }, + { + "id": "4ce93188-d865-432f-8488-c5d5758d0f14", + "title": "", + "visualType": "markdownCard", + "pageId": "d01a8154-8a60-4d22-96ea-54b45b1417fe", + "layout": { "x": 0, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Architecting for the cloud\nArchitecting for the cloud involves designing and implementing cloud infrastructure and applications to optimize cost, performance, scalability, and reliability. Simultaneously, you align with business objectives.\n\nWith this capability, you ensure solutions are designed for efficiency in early development and migration stages to ensure they follow proven practices to maximize value and reduce waste. This capability is an important step towards reducing post-deployment optimization efforts, which often require much time and effort.\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/architecting)", + "visualOptions": {} + }, + { + "id": "87e197cb-12de-4eca-86e6-ee1d469c8990", + "title": "", + "visualType": "markdownCard", + "pageId": "d01a8154-8a60-4d22-96ea-54b45b1417fe", + "layout": { "x": 5, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Workload optimization\nWorkload optimization refers to the process of ensuring cloud services are utilized and tuned to maximize business value and minimize wasteful usage and spending. With this capability, you analyze cost, usage, and carbon emissions for cloud workloads to identify opportunities to maximize efficiency. This capability usually starts with recommendations and expands into more nuanced optimization efforts based on detailed resource utilization analysis. This capability can be time and effort intensive as each cloud service has its different optimization opportunities.\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/workloads)", + "visualOptions": {} + }, + { + "id": "a60dda7f-8f14-429d-b7ff-a2db94feb809", + "title": "", + "visualType": "markdownCard", + "pageId": "d01a8154-8a60-4d22-96ea-54b45b1417fe", + "layout": { "x": 10, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Rate optimization\nRate optimization is the practice of obtaining reduced rates on cloud services, often by committing to a certain level of usage or spend over a specific period. With this capability, you analyze SKU usage patterns to inform rate negotiation efforts and commitment discount planning. This capability can lead to impressive discounts based on consistent usage patterns.\n\n📊 [View report](#306fef9a-c760-4559-a326-7c25d196b616)\n   \n📗 [Learn more](http://aka.ms/ftk/fx/rates)", + "visualOptions": {} + }, + { + "id": "aa339c66-412d-4619-9737-06d5e4c282fe", + "title": "", + "visualType": "markdownCard", + "pageId": "d01a8154-8a60-4d22-96ea-54b45b1417fe", + "layout": { "x": 15, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Licensing and SaaS\nLicensing & SaaS involves managing and optimizing the financial aspects of software licensing agreements and Software as a Service (SaaS) investments within an organization. With this capability, you track and manage software licenses and prepaid SaaS products to ensure they're being fully utilized. This capability also covers bring your own license offers, like Azure Hybrid Benefit.\n\n📊 [View report](#a4ec1d55-5b6e-49af-bb9e-4f3d136cdf05)\n   \n📗 [Learn more](http://aka.ms/ftk/fx/licensing)", + "visualOptions": {} + }, + { + "id": "2ba70b12-ac64-41b9-b13f-d3c91dab6df4", + "title": "On this page", + "visualType": "markdownCard", + "pageId": "a4ec1d55-5b6e-49af-bb9e-4f3d136cdf05", + "layout": { "x": 0, "y": 0, "width": 22, "height": 2 }, + "markdownText": "  [Hybrid Benefit](?tile=805cac8c-a189-45cb-8ba3-fbb1a06dfba0)", + "visualOptions": {} + }, + { + "id": "805cac8c-a189-45cb-8ba3-fbb1a06dfba0", + "title": "", + "visualType": "markdownCard", + "pageId": "a4ec1d55-5b6e-49af-bb9e-4f3d136cdf05", + "layout": { "x": 0, "y": 5, "width": 22, "height": 4 }, + "markdownText": "# Azure Hybrid Benefit\r\nSummary of the Hybrid Benefit coverage and utilization\r\n\r\n⬆️ [Top](?tile=2ba70b12-ac64-41b9-b13f-d3c91dab6df4)", + "visualOptions": {} + }, + { + "id": "d2e4a321-9c2c-411b-8a20-19fd86dab3fe", + "title": "Hybrid Benefit summary (last n days)", + "visualType": "multistat", + "pageId": "a4ec1d55-5b6e-49af-bb9e-4f3d136cdf05", + "layout": { "x": 0, "y": 9, "width": 6, "height": 15 }, + "queryRef": { "kind": "query", "queryId": "1a400b6c-9204-434d-88ff-2dc5260a95bf" }, + "visualOptions": { + "multiStat__textSize": "auto", + "multiStat__valueColumn": "Value", + "colorRulesDisabled": true, + "colorStyle": "light", + "multiStat__displayOrientation": "vertical", + "multiStat__labelColumn": "Label", + "multiStat__slot": { "width": 2, "height": 3 }, + "colorRules": [] + } + }, + { + "id": "80e1ecb4-69f6-451d-9e1c-f90d17b7f865", + "title": "Underutilized vCPU capacity (last n days)", + "visualType": "table", + "pageId": "a4ec1d55-5b6e-49af-bb9e-4f3d136cdf05", + "layout": { "x": 6, "y": 9, "width": 16, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "c2ad5370-f4df-4a13-ac31-2c095f88754d" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": true, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "59a1756c-7586-4364-8047-604aa7d6f09a", + "title": "Fully utilized vCPU capacity (last n days)", + "visualType": "table", + "pageId": "a4ec1d55-5b6e-49af-bb9e-4f3d136cdf05", + "layout": { "x": 6, "y": 14, "width": 16, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "4614acfb-2288-4a71-97f7-32845a9ddcb2" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": true, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "9197f822-bdf3-42af-8b43-5609c9b91f00", + "title": "Eligible resources (last n days)", + "visualType": "table", + "pageId": "a4ec1d55-5b6e-49af-bb9e-4f3d136cdf05", + "layout": { "x": 6, "y": 19, "width": 16, "height": 5 }, + "queryRef": { "kind": "query", "queryId": "99d44f1f-c53a-40ee-b749-8e5557ec58c7" }, + "visualOptions": { + "table__enableRenderLinks": true, + "colorRulesDisabled": true, + "colorStyle": "light", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [], + "table__renderLinks": [], + "colorRules": [] + } + }, + { + "id": "d9d6d2e0-6403-418f-8aa0-1e2eb4ce2822", + "title": "", + "visualType": "markdownCard", + "pageId": "d01a8154-8a60-4d22-96ea-54b45b1417fe", + "layout": { "x": 0, "y": 12, "width": 5, "height": 7 }, + "markdownText": "### Cloud sustainability\nCloud sustainability balances environmental and financial efficiency in cloud optimization, ensuring alignment with strategic objectives. With this capability, you focus explicitly on optimizing carbon emissions through usage and workload analysis. This capability relies heavily on understanding the carbon impact of different services across different regions to identify the right cost/carbon balance for your organizational goals.\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/sustainability)", + "visualOptions": {} + }, + { + "id": "43e7bf02-fa40-4a35-9b41-e45496d0404b", + "title": "", + "visualType": "markdownCard", + "pageId": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10", + "layout": { "x": 0, "y": 0, "width": 22, "height": 5 }, + "markdownText": "# Manage the FinOps practice\nThe **Manage the FinOps practice** domain focuses on establishing a clear and consistent vision of FinOps and driving cultural adoption across your organization. Other domains are focused on the FinOps tasks you perform to drive efficiency and maximize value. This domain is focused more on how you run your FinOps practice and supporting those efforts.\n\n[Learn more](https://learn.microsoft.com/cloud-computing/finops/framework/manage/manage-finops)\n", + "visualOptions": {} + }, + { + "id": "9c05ec17-5d60-4ed3-bc8c-6214e8955312", + "title": "", + "visualType": "markdownCard", + "pageId": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10", + "layout": { "x": 0, "y": 5, "width": 6, "height": 7 }, + "markdownText": "### FinOps education and enablement\nFinOps education and enablement involve refers to the process of providing training, resources, and support to help individuals and teams within an organization adopt FinOps practices. This capability ensures that stakeholders across the organization have the resources they need to:\n\n- Understand FinOps\n- Understand how it can help them achieve their goals\n- Understand how to perform FinOps tasks using the available tools and services.\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/education)", + "visualOptions": {} + }, + { + "id": "abf6cf66-48b8-4d86-826d-64ebc9ddcc90", + "title": "", + "visualType": "markdownCard", + "pageId": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10", + "layout": { "x": 6, "y": 5, "width": 6, "height": 7 }, + "markdownText": "### FinOps practice operations\nFinOps practice operations refer to the process of:\n\n- Building and managing a robust FinOps team\n- Defining clear cross-functional responsibilities\n- Integrating FinOps practices into organizational processes to manage cloud cost and usage effectively.\n\nWith this capability, you establish and manage your FinOps practice, focusing on supporting the needs of stakeholders across the organization. This capability is pivotal to driving organizational adoption.\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/operations)", + "visualOptions": {} + }, + { + "id": "20c47c65-228a-4c70-9d7c-418ad1c8c5cf", + "title": "", + "visualType": "markdownCard", + "pageId": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10", + "layout": { "x": 12, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Onboarding workloads\nOnboarding workloads refers to the process of bringing new and existing applications into the cloud based on their financial and technical feasibility. With this capability, you:\n\n- Understand requirements for new workloads\n- Identify if there are any architectural requirements or changes that should be considered\n- Validate that the budget is available to support their needs\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/onboarding)", + "visualOptions": {} + }, + { + "id": "31c7508b-6298-4257-9c35-a7d9cd7c84e2", + "title": "", + "visualType": "markdownCard", + "pageId": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10", + "layout": { "x": 17, "y": 5, "width": 5, "height": 7 }, + "markdownText": "### Cloud policy and governance\nCloud policy and governance refer to the process of defining, implementing, and monitoring a framework of rules that guide an organization's FinOps efforts. With this capability, you identify and implement policies to support organizational goals by promoting or limiting the use of:\n\n- Specific SKUs\n- Resource configurations\n- Other practices that might affect cost, usage, and carbon growth\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/policy)", + "visualOptions": {} + }, + { + "id": "a000abed-3a39-4675-806c-9423ff344d2e", + "title": "", + "visualType": "markdownCard", + "pageId": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10", + "layout": { "x": 0, "y": 12, "width": 5, "height": 6 }, + "markdownText": "### Invoicing and chargeback\nInvoicing and chargeback refer to the process of receiving, reconciling, and paying provider invoices, and then billing internal teams for their respective cloud costs using existing internal finance tools and processes. With this capability, you break down invoices and cross-charge portions of these invoices to the teams responsible for the charges.\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/chargeback)", + "visualOptions": {} + }, + { + "id": "fc3beac9-e524-4262-bdc5-39f7168e11ff", + "title": "", + "visualType": "markdownCard", + "pageId": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10", + "layout": { "x": 5, "y": 12, "width": 7, "height": 6 }, + "markdownText": "### FinOps assessment\nFinOps assessment refers to the process of measuring the effectiveness of a FinOps practice, aligning activities with organizational goals, and identifying areas for improvement to drive FinOps maturity. With this capability, you assess and benchmark the maturity of different teams to identify focus areas for key milestones. This capability is important to set clear, quantitative expectations with teams that are backed up with recommendations to drive targeted improvements and prioritize organizational goals.\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/assessment)", + "visualOptions": {} + }, + { + "id": "d525fe75-1afb-43f3-89c3-b8ccfbc8f570", + "title": "", + "visualType": "markdownCard", + "pageId": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10", + "layout": { "x": 12, "y": 12, "width": 5, "height": 6 }, + "markdownText": "### FinOps tools and services\nFinOps tools and services encapsulate identifying, configuring, and integrating tools and services that meet the needs of FinOps capabilities. They also enable the FinOps practice at scale throughout the organization. With this capability, you identify the tools and services needed to accelerate FinOps tasks and support your FinOps practice.\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/tools)", + "visualOptions": {} + }, + { + "id": "c2452fca-3ba3-40f6-9ccb-94ea6d075a12", + "title": "", + "visualType": "markdownCard", + "pageId": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10", + "layout": { "x": 17, "y": 12, "width": 5, "height": 6 }, + "markdownText": "### Intersecting frameworks\nFinOps and intersecting frameworks refers to integrating FinOps practices with other frameworks and methodologies used by an organization. With this capability, you'll partner with stakeholders in other disciplines to understand each other's others priorities to achieve an acceptable balance compared to cost, usage, and carbon efficiency goals.\n\n📊 Coming soon\n   \n📗 [Learn more](http://aka.ms/ftk/fx/frameworks)", + "visualOptions": {} + }, + { + "id": "876b81e5-4f71-4c69-bd62-8d470f50bf31", + "title": "About this domain", + "visualType": "markdownCard", + "pageId": "f416685d-f559-4514-8e45-5e0e09aec286", + "layout": { "x": 0, "y": 0, "width": 21, "height": 3 }, + "markdownText": "Invoicing and chargeback refer to the process of receiving, reconciling, and paying provider invoices, and then billing internal teams for their respective cloud costs using existing internal finance tools and processes. With this capability, you break down invoices and cross-charge portions of these invoices to the teams responsible for the charges. [Learn more](http://aka.ms/ftk/fx/chargeback)", + "visualOptions": {} + }, + { + "id": "a66f0b2b-6bce-4bfb-ad3e-13f7eabcb586", + "title": "About this domain", + "visualType": "markdownCard", + "pageId": "5c57f940-6f0f-4e39-930b-b6e89bb758ad", + "layout": { "x": 0, "y": 0, "width": 22, "height": 3 }, + "markdownText": "Budgeting is the process of monitoring and managing financial plans and limits over a specific period to control spending effectively. This capability allows you to use established estimates and forecasts to allocate funds to each team for fiscal year planning and set up alerts to ensure budget accountability. This capability plays a key role in staying within established fiscal constraints on an ongoing basis. [Learn more](http://aka.ms/ftk/fx/budgeting)", + "visualOptions": {} + }, + { + "id": "8f02d466-36fc-464b-adb2-bfa4ff888891", + "title": "About this domain", + "visualType": "markdownCard", + "pageId": "306fef9a-c760-4559-a326-7c25d196b616", + "layout": { "x": 0, "y": 2, "width": 22, "height": 3 }, + "markdownText": "Rate optimization is the practice of obtaining reduced rates on cloud services, often by committing to a certain level of usage or spend over a specific period. With this capability, you analyze SKU usage patterns to inform rate negotiation efforts and commitment discount planning. This capability can lead to impressive discounts based on consistent usage patterns. [Learn more](http://aka.ms/ftk/fx/rates)", + "visualOptions": {} + }, + { + "id": "3b6b230c-4bc1-40f7-917a-aa7c02ba22c5", + "title": "About this domain", + "visualType": "markdownCard", + "pageId": "a4ec1d55-5b6e-49af-bb9e-4f3d136cdf05", + "layout": { "x": 0, "y": 2, "width": 22, "height": 3 }, + "markdownText": "Licensing & SaaS involves managing and optimizing the financial aspects of software licensing agreements and Software as a Service (SaaS) investments within an organization. With this capability, you track and manage software licenses and prepaid SaaS products to ensure they're being fully utilized. This capability also covers bring your own license offers, like Azure Hybrid Benefit. [Learn more](http://aka.ms/ftk/fx/licensing)", + "visualOptions": {} + }, + { + "id": "08c92e20-6563-464b-893f-81d80dd3caa1", + "title": "About this domain", + "visualType": "markdownCard", + "pageId": "5838c918-4541-44fe-90d2-77306ef1e241", + "layout": { "x": 0, "y": 0, "width": 16, "height": 3 }, + "markdownText": "Anomaly management refers to the practice of detecting and addressing abnormal or unexpected cost and usage patterns in a timely manner. With this capability, you identify, triage, and address unexpected changes in cost, usage, and carbon. This capability is especially important with usage-based billing and sustainability models, where small fluctuations in usage can result in large fiscal and environmental impact. [Learn more](http://aka.ms/ftk/fx/anomalies)\n", + "visualOptions": {} + }, + { + "id": "6fb4c25e-ae84-495b-88ae-6dd2035500d1", + "title": "Forecast (next n days)", + "visualType": "timechart", + "pageId": "5838c918-4541-44fe-90d2-77306ef1e241", + "layout": { "x": 0, "y": 32, "width": 9, "height": 7 }, + "queryRef": { "kind": "query", "queryId": "5fd3ea2a-8882-4438-9103-fa3945240604" }, + "visualOptions": { + "multipleYAxes": { + "base": { "id": "-1", "label": "", "columns": [], "yAxisMaximumValue": null, "yAxisMinimumValue": null, "yAxisScale": "linear", "horizontalLines": [] }, + "additional": [], + "showMultiplePanels": false + }, + "hideLegend": false, + "legendLocation": "bottom", + "xColumnTitle": "", + "xColumn": null, + "yColumns": null, + "seriesColumns": null, + "xAxisScale": "linear", + "verticalLine": "", + "crossFilterDisabled": false, + "drillthroughDisabled": false, + "crossFilter": [], + "drillthrough": [] + } + } + ], + "baseQueries": [ + { "id": "58764bcb-2ba0-4c7f-b018-e5d7f6cff688", "queryId": "43612ae4-c475-4f22-bb50-ce9d995abb8f", "variableName": "CostsThisMonth" }, + { "id": "21512220-154c-4646-a188-72e8c437d8ed", "queryId": "cb1f5404-c0b1-42fd-99fb-3cff7b08daaa", "variableName": "CostsLastMonth" }, + { "id": "5fa73857-4e92-4a16-8179-f94563e5f605", "queryId": "4ce0f587-2d45-436c-8f79-102c6b382439", "variableName": "CostsByMonth" }, + { "id": "4880346a-0a24-48f9-bf25-b7427df29d69", "queryId": "6b598467-8c31-4693-b1eb-7ed683fcfc3a", "variableName": "CostsByDay" }, + { "id": "8ca40660-3fbc-4a08-b12e-92e7382d9449", "queryId": "4a1973bf-08e9-4e82-b8e6-6edff81cf0a5", "variableName": "CostsByDayAHB" } + ], + "parameters": [ + { + "kind": "int", + "id": "50e8acdc-5d90-4937-96cb-53a9b0ad047f", + "displayName": "Monthly trend", + "description": "How many months should be shown in monthly trend charts and tables?", + "variableName": "numberOfMonths", + "selectionType": "scalar", + "includeAllOption": false, + "defaultValue": { "kind": "query-result" }, + "dataSource": { "kind": "query", "columns": { "value": "Value", "label": "Label" }, "queryRef": { "kind": "query", "queryId": "c9039243-968d-4e75-9899-8d4ab51a9896" } }, + "showOnPages": { "kind": "all" } + }, + { + "kind": "int", + "selectionType": "freetext", + "id": "c016c954-1d37-41fb-8c4e-7607a9be2e96", + "displayName": "Daily trend", + "variableName": "numberOfDays", + "description": "How many days should be shown in daily trend charts and tables? Does not apply to \"this month and last\" queries.", + "defaultValue": { "kind": "value", "value": 28 }, + "showOnPages": { "kind": "all" } + }, + { + "kind": "int", + "selectionType": "freetext", + "id": "55463317-2576-4d98-875e-85a1fa032c12", + "displayName": "Max group count", + "variableName": "maxGroupCount", + "description": "How many groups should be shown in charts? Remaining will be in an \"others\" group.", + "defaultValue": { "kind": "value", "value": 9 }, + "showOnPages": { "kind": "all" } + } + ], + "dataSources": [ + { "id": "23540be2-ffc9-4b61-8c4c-05e493e682a6", "kind": "manual-kusto", "scopeId": "kusto", "name": "Hub", "clusterUri": "https://ftk-mf.westcentralus.kusto.windows.net/", "database": "Hub" } + ], + "pages": [ + { "name": "About", "id": "969ddf4c-8f2a-4ec4-9588-bb2f39473c9f" }, + { "name": "UNDERSTAND", "id": "ea47329e-0bc9-4c11-b110-534878dbb3ad" }, + { "id": "f8ee3008-df7e-442f-825e-2e3b46e4c185", "name": "- Summary" }, + { "name": "- Anomaly management", "id": "5838c918-4541-44fe-90d2-77306ef1e241" }, + { "name": "- Data ingestion", "id": "9e099251-9658-48da-b416-80422a2a47c7" }, + { "name": "OPTIMIZE", "id": "d01a8154-8a60-4d22-96ea-54b45b1417fe" }, + { "name": "- Rate optimization", "id": "306fef9a-c760-4559-a326-7c25d196b616" }, + { "id": "a4ec1d55-5b6e-49af-bb9e-4f3d136cdf05", "name": "- Licensing + SaaS" }, + { "name": "QUANTIFY", "id": "8beab65c-f5ec-4661-bc67-37b10baffb16" }, + { "name": "- Budgeting", "id": "5c57f940-6f0f-4e39-930b-b6e89bb758ad" }, + { "name": "MANAGE", "id": "11f019cd-e0cc-4aa7-a125-4dc852eb3f10" }, + { "name": "- Invoicing + chargeback", "id": "f416685d-f559-4514-8e45-5e0e09aec286" } + ], + "queries": [ + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['(ignore)', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']);\nlet costs = materialize(\n CostsLastMonth\n | summarize BilledCost = round(sum(BilledCost), 2), EffectiveCost = round(sum(EffectiveCost), 2) by BillingPeriodStart = startofmonth(BillingPeriodStart)\n | extend json = todynamic(strcat('[{\"type\":\"Billed cost\", \"Cost\":', BilledCost, '}, {\"type\":\"Effective cost\", \"Cost\":', EffectiveCost, '}]'))\n | mv-expand json\n | project Type = strcat(json.type, ' (', monthname[monthofyear(BillingPeriodStart)], ' ', format_datetime(BillingPeriodStart, 'yyyy'), ')'), Cost = todouble(json.Cost)\n);\ncosts", + "id": "152f2041-bbc1-41e4-b155-271b2e0cf6e9", + "usedVariables": ["CostsLastMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\n| summarize BilledCost = round(sum(BilledCost), 2), EffectiveCost = round(sum(EffectiveCost), 2) by BillingPeriodStart = startofmonth(BillingPeriodStart)\n| render timechart", + "id": "bc24e050-f2b9-4b4a-a08d-69fc4a4bb95e", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\n// | summarize BilledCost = round(sum(BilledCost), 2), EffectiveCost = round(sum(EffectiveCost), 2) by BillingPeriodStart = startofmonth(BillingPeriodStart)\n// | render timechart\n| summarize BilledCost = sum(BilledCost), EffectiveCost = sum(EffectiveCost) by BillingPeriodStart = startofmonth(BillingPeriodStart)\n| order by BillingPeriodStart asc\n| extend PreviousBilledCost = prev(BilledCost)\n| extend PreviousEffectiveCost = prev(EffectiveCost)\n| project BillingPeriodStart\n , BilledCost = iif(isempty(PreviousBilledCost), todouble(0), todouble((BilledCost - PreviousBilledCost) * 100.0 / PreviousBilledCost))\n , EffectiveCost = iif(isempty(PreviousEffectiveCost), todouble(0), todouble((EffectiveCost - PreviousEffectiveCost) * 100.0 / PreviousEffectiveCost))\n", + "id": "0d91ea4a-c81d-4a21-b708-b6af37be1eec", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let data = materialize(\n CostsLastMonth\n | summarize\n Subscriptions = dcount(SubAccountId),\n ResourceGroups = dcount(strcat(SubAccountId, x_ResourceGroupName)),\n Resources = dcount(ResourceId),\n Services = dcount(ServiceName)\n | project json = todynamic(strcat('[{ \"Type\":\"Subscriptions\", \"Count\":', Subscriptions, ' }, { \"Type\":\"Resource groups\", \"Count\":', ResourceGroups, ' }, { \"Type\":\"Resources\", \"Count\":', Resources, ' }, { \"Type\":\"Services\", \"Count\":', Services, ' }]'))\n | mv-expand json\n | project Label = tostring(json.Type), Count = tolong(json.Count)\n);\ndata", + "id": "f2cecbb0-13f8-4642-afa4-bbcc0558f777", + "usedVariables": ["CostsLastMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let data = materialize(\n CostsByDay\n | summarize\n Subscriptions = dcount(SubAccountId),\n ResourceGroups = dcount(strcat(SubAccountId, x_ResourceGroupName)),\n Resources = dcount(ResourceId),\n Services = dcount(ServiceName)\n | project json = todynamic(strcat('[{ \"Type\":\"Subscriptions\", \"Count\":', Subscriptions, ' }, { \"Type\":\"Resource groups\", \"Count\":', ResourceGroups, ' }, { \"Type\":\"Resources\", \"Count\":', Resources, ' }, { \"Type\":\"Services\", \"Count\":', Services, ' }]'))\n | mv-expand json\n | project Label = tostring(json.Type), Count = tolong(json.Count)\n);\ndata", + "id": "5d63e04d-1a11-4307-96f1-ebbf68e09be0", + "usedVariables": ["CostsByDay"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "CostsByMonth\n| summarize EffectiveCost = sum(EffectiveCost) by BillingPeriodStart\n| order by BillingPeriodStart asc\n| extend PreviousEffectiveCost = prev(EffectiveCost)\n| project BillingPeriodStart, EffectiveCost, Change = iif(isempty(PreviousEffectiveCost), todouble(0), todouble((EffectiveCost - PreviousEffectiveCost) / PreviousEffectiveCost)) * 100\n", + "id": "290e7eab-8159-4338-8531-85e2718cedb1", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nCosts_v1_0\n| where ChargePeriodStart >= startofmonth(ago(90d))\n| summarize EffectiveCost = sum(EffectiveCost) by ChargePeriodStart, Day = dayofmonth(ChargePeriodStart), Month = strcat(format_datetime(ChargePeriodStart, 'MM '), monthname[monthofyear(ChargePeriodStart)])\n| order by ChargePeriodStart asc\n| extend EffectiveCostRunningTotal = row_cumsum(EffectiveCost, prev(Month) != Month)\n| project Day, EffectiveCostRunningTotal, Month\n| render areachart ", + "id": "d5ed469a-45ea-49a2-b305-b841050213cf", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nCosts_v1_0\n| where ChargePeriodStart >= startofmonth(startofmonth(now()) - 1d)\n| summarize EffectiveCost = sum(EffectiveCost) by ChargePeriodStart, Month = strcat(format_datetime(ChargePeriodStart, 'MM '), monthname[monthofyear(ChargePeriodStart)])\n| order by ChargePeriodStart asc\n| extend EffectiveCostRunningTotal = row_cumsum(EffectiveCost, prev(Month) != Month)\n| project ChargePeriodStart, EffectiveCostRunningTotal, Month\n| render areachart ", + "id": "10300876-866a-40d7-836d-b3a8783ecece", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nCosts_v1_0\n| where ChargePeriodStart >= startofmonth(ago(90d))\n| summarize EffectiveCost = sum(EffectiveCost) by ChargePeriodStart, Day = dayofmonth(ChargePeriodStart), Month = strcat(format_datetime(ChargePeriodStart, 'MM '), monthname[monthofyear(ChargePeriodStart)])\n| order by ChargePeriodStart asc\n| project Day, EffectiveCost, Month\n| render columnchart", + "id": "9e41a624-d5f9-40c6-b47f-fef4b50ec3dd", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = Costs_v1_0 | where ChargePeriodStart >= startofmonth(ago(90d));\nlet all = costs | summarize sum(EffectiveCost) by SubAccountId;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = SubAccountId in (topX)\n| extend SubAccountId = iff(inTopX, SubAccountId, otherId)\n| extend SubAccountName = iff(inTopX, SubAccountName, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2),\n SubAccountName = take_any(SubAccountName)\n by\n ChargePeriodStart,\n SubAccountId\n| project ChargePeriodStart, EffectiveCost, Sub = iff(SubAccountId == otherId, SubAccountName, strcat(SubAccountName, ' (', split(SubAccountId, '/')[2], ')'))\n| order by EffectiveCost desc\n| render columnchart", + "id": "f26e2204-270e-4219-8f68-5acef1c9393f", + "usedVariables": ["maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nCosts_v1_0\n| where ChargePeriodStart >= startofmonth(startofmonth(now()) - 1d)\n| summarize \n EffectiveCost = sum(EffectiveCost),\n ContractedCost = sum(ContractedCost),\n ListCost = sum(ListCost)\n by\n ChargePeriodStart,\n Month = strcat(format_datetime(ChargePeriodStart, 'MM '), monthname[monthofyear(ChargePeriodStart)])\n| extend CommitmentDiscountSavings = ContractedCost - EffectiveCost\n| extend NegotiatedDiscountSavings = ListCost - ContractedCost\n| order by ChargePeriodStart asc\n| extend EffectiveCostRunningTotal = row_cumsum(EffectiveCost, prev(Month) != Month)\n| extend CommitmentDiscountSavingsRunningTotal = row_cumsum(CommitmentDiscountSavings, prev(Month) != Month)\n| extend NegotiatedDiscountSavingsRunningTotal = row_cumsum(NegotiatedDiscountSavings, prev(Month) != Month)\n| project ChargePeriodStart, CommitmentDiscountSavingsRunningTotal, NegotiatedDiscountSavingsRunningTotal, EffectiveCostRunningTotal, Month\n| render areachart ", + "id": "dcc1f533-e5f9-4855-9e4c-21e21fcdf943", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = materialize(\n CostsByMonth\n | summarize \n BilledCost = sum(BilledCost),\n EffectiveCost = sum(EffectiveCost),\n ContractedCost = sum(ContractedCost),\n ListCost = sum(ListCost)\n by\n ChargePeriodStart\n | order by ChargePeriodStart asc\n | extend CommitmentDiscountSavings = ContractedCost - EffectiveCost\n | extend NegotiatedDiscountSavings = ListCost - ContractedCost\n | extend Month = monthname[monthofyear(ChargePeriodStart)]\n | project json = todynamic(strcat('[{ \"Type\":\"Billed cost\", \"Count\":', BilledCost, ' }, { \"Type\":\"Effective cost\", \"Count\":', EffectiveCost, ' }, { \"Type\":\"Commitment savings\", \"Count\":', CommitmentDiscountSavings, ' }, { \"Type\":\"Negotiated savings\", \"Count\":', NegotiatedDiscountSavings, ' }]')), Month, IsThisMonth = ChargePeriodStart >= startofmonth(now())\n | mv-expand json\n | project Label = strcat(json.Type, ' (', Month, ')'), Count = tolong(json.Count), IsThisMonth\n);\ndata", + "id": "e8b343dc-7430-4487-8d44-ef48ac454f2d", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | summarize \n BilledCost = todouble(round(sum(BilledCost), 2)),\n EffectiveCost = todouble(round(sum(EffectiveCost), 2)),\n ContractedCost = todouble(round(sum(ContractedCost), 2)),\n ListCost = todouble(round(sum(ListCost), 2))\n by\n ChargePeriodStart\n | order by ChargePeriodStart asc\n | extend CommitmentDiscountSavings = todouble(round(ContractedCost - EffectiveCost, 2))\n | extend NegotiatedDiscountSavings = todouble(round(ListCost - ContractedCost, 2))\n | extend ChargePeriod = strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)])\n);\ndata | extend Data = 'Billed cost' | evaluate pivot(ChargePeriod, sum(BilledCost), Data)\n| union (data | extend Data = 'Effective cost' | evaluate pivot(ChargePeriod, sum(EffectiveCost), Data))\n| union (data | extend Data = 'Negotiated savings' | evaluate pivot(ChargePeriod, sum(NegotiatedDiscountSavings), Data))\n| union (data | extend Data = 'Commitment savings' | evaluate pivot(ChargePeriod, sum(CommitmentDiscountSavings), Data))\n", + "id": "c077a6d4-719f-42fe-b39b-36f77dc68976", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n Costs_v1_0\n | summarize \n BilledCost = todouble(round(sum(BilledCost), 2)),\n EffectiveCost = todouble(round(sum(EffectiveCost), 2)),\n ContractedCost = todouble(round(sum(ContractedCost), 2)),\n ListCost = todouble(round(sum(ListCost), 2))\n by\n ChargePeriodStart = startofmonth(ChargePeriodStart)\n | order by ChargePeriodStart asc\n | extend CommitmentDiscountSavings = todouble(round(ContractedCost - EffectiveCost, 2))\n | extend NegotiatedDiscountSavings = todouble(round(ListCost - ContractedCost, 2))\n | extend ChargePeriod = strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)])\n);\ndata | extend Data = 'Billed cost' | evaluate pivot(ChargePeriod, sum(BilledCost), Data)\n| union (data | extend Data = 'Effective cost' | evaluate pivot(ChargePeriod, sum(EffectiveCost), Data))\n| union (data | extend Data = 'Negotiated savings' | evaluate pivot(ChargePeriod, sum(NegotiatedDiscountSavings), Data))\n| union (data | extend Data = 'Commitment savings' | evaluate pivot(ChargePeriod, sum(CommitmentDiscountSavings), Data))\n//, BilledCost, NegotiatedDiscountSavings, CommitmentDiscountSavings)\n//| project ChargePeriod, BilledCost = round(BilledCost, 2), EffectiveCost = round(EffectiveCost, 2), NegotiatedDiscountSavings, CommitmentDiscountSavings\n", + "id": "3d947a7c-edca-46b5-a862-de77a725c85f", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n Costs_v1_0\n | summarize \n BilledCost = sum(BilledCost),\n EffectiveCost = sum(EffectiveCost),\n ContractedCost = sum(ContractedCost),\n ListCost = sum(ListCost),\n SubAccountName = take_any(SubAccountName)\n by\n ChargePeriodStart = startofmonth(ChargePeriodStart),\n SubAccountId\n | as per\n | union (\n per\n | summarize \n BilledCost = sum(BilledCost),\n EffectiveCost = sum(EffectiveCost),\n ContractedCost = sum(ContractedCost),\n ListCost = sum(ListCost),\n SubAccountName = take_any(SubAccountName)\n by\n SubAccountId\n )\n | order by ChargePeriodStart asc\n | extend BilledCost = todouble(round(BilledCost, 2))\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ContractedCost = todouble(round(ContractedCost, 2))\n | extend ListCost = todouble(round(ListCost, 2))\n | extend CommitmentDiscountSavings = todouble(round(ContractedCost - EffectiveCost, 2))\n | extend NegotiatedDiscountSavings = todouble(round(ListCost - ContractedCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), SubAccountName)\n| order by Total desc", + "id": "3886b5cd-34a8-42d7-9e16-33ea4d236953", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByMonth;\nlet all = costs | where isnotempty(RegionName) | summarize sum(EffectiveCost) by RegionName;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit iff(count - maxGroupCount > 1, maxGroupCount, count);\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = RegionName in (topX)\n| extend RegionName = iff(inTopX, RegionName, strcat('(', count - maxGroupCount, ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2)\n by\n ChargePeriodStart = startofmonth(ChargePeriodStart),\n RegionName\n| project ChargePeriodStart, EffectiveCost, Region = RegionName\n| order by EffectiveCost desc", + "id": "d5224d06-c8e7-4dd9-afec-595b39712f5a", + "usedVariables": ["CostsByMonth", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n ChargePeriodStart = startofmonth(ChargePeriodStart),\n RegionName\n | as per\n | union (\n per\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n RegionName\n )\n | order by ChargePeriodStart asc\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), RegionName)\n| order by Total desc", + "id": "0dcf2c54-7f1d-45e9-a53b-d598a24493a4", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByMonth;\nlet all = costs | where isnotempty(ServiceName) | summarize sum(EffectiveCost) by ServiceName;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = ServiceName in (topX)\n| extend ServiceName = iff(inTopX, ServiceName, otherId)\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2)\n by\n ChargePeriodStart,\n ServiceName\n| project ChargePeriodStart, EffectiveCost, Category = ServiceName\n| order by EffectiveCost desc\n| render columnchart", + "id": "30644718-defd-4c6c-9ffa-a9c2cd1f871f", + "usedVariables": ["CostsByMonth", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n ChargePeriodStart,\n ServiceCategory,\n ServiceName\n | as per\n | union (\n per\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n ServiceCategory,\n ServiceName\n )\n | order by ChargePeriodStart asc\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), ServiceName, ServiceCategory)\n| order by Total desc", + "id": "6259f773-593c-4953-898c-15aa5ff6e53a", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByMonth;\nlet all = costs | where isnotempty(SubAccountId) | summarize sum(EffectiveCost) by SubAccountId;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = SubAccountId in (topX)\n| extend SubAccountId = iff(inTopX, SubAccountId, otherId)\n| extend SubAccountName = iff(inTopX, SubAccountName, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2),\n SubAccountName = take_any(SubAccountName)\n by\n ChargePeriodStart = startofmonth(ChargePeriodStart),\n SubAccountId\n| project ChargePeriodStart, EffectiveCost, Sub = iff(SubAccountId == otherId, SubAccountName, strcat(SubAccountName, ' (', split(SubAccountId, '/')[2], ')'))\n| order by EffectiveCost desc\n| render columnchart", + "id": "21a87abe-19e2-44ec-8298-ba872e66c162", + "usedVariables": ["CostsByMonth", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | summarize \n BilledCost = sum(BilledCost),\n EffectiveCost = sum(EffectiveCost),\n ContractedCost = sum(ContractedCost),\n ListCost = sum(ListCost),\n SubAccountName = take_any(SubAccountName)\n by\n ChargePeriodStart,\n SubAccountId\n | as per\n | union (\n per\n | summarize \n BilledCost = sum(BilledCost),\n EffectiveCost = sum(EffectiveCost),\n ContractedCost = sum(ContractedCost),\n ListCost = sum(ListCost),\n SubAccountName = take_any(SubAccountName)\n by\n SubAccountId\n )\n | order by ChargePeriodStart asc\n | extend BilledCost = todouble(round(BilledCost, 2))\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ContractedCost = todouble(round(ContractedCost, 2))\n | extend ListCost = todouble(round(ListCost, 2))\n | extend CommitmentDiscountSavings = todouble(round(ContractedCost - EffectiveCost, 2))\n | extend NegotiatedDiscountSavings = todouble(round(ListCost - ContractedCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), SubAccountName)\n| order by Total desc", + "id": "90502e9a-2d0d-4ae4-8d9d-cc21f9b72d5d", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | extend x_ResourceGroupId = strcat(SubAccountId, '/resourcegroups/', x_ResourceGroupName)\n | summarize \n EffectiveCost = sum(EffectiveCost),\n SubAccountName = take_any(SubAccountName),\n x_ResourceGroupName = take_any(x_ResourceGroupName)\n by\n ChargePeriodStart,\n x_ResourceGroupId\n | as per\n | union (\n per\n | summarize \n EffectiveCost = sum(EffectiveCost),\n SubAccountName = take_any(SubAccountName),\n x_ResourceGroupName = take_any(x_ResourceGroupName)\n by\n x_ResourceGroupId\n )\n | order by ChargePeriodStart asc\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), x_ResourceGroupName, SubAccountName)\n| order by Total desc", + "id": "c2c65ec0-e57d-4834-8a6b-b5975afeb9a0", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByMonth | extend x_ResourceGroupId = strcat(SubAccountId, '/resourcegroups/', x_ResourceGroupName);\nlet all = costs | where isnotempty(x_ResourceGroupId) | summarize sum(EffectiveCost) by x_ResourceGroupId;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = x_ResourceGroupId in (topX)\n| extend x_ResourceGroupId = iff(inTopX, x_ResourceGroupId, otherId)\n| extend x_ResourceGroupName = iff(inTopX, x_ResourceGroupName, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2),\n SubAccountName = take_any(SubAccountName),\n x_ResourceGroupName = take_any(x_ResourceGroupName)\n by\n ChargePeriodStart,\n x_ResourceGroupId\n| project ChargePeriodStart, EffectiveCost, RG = iff(x_ResourceGroupId == otherId, x_ResourceGroupName, strcat(x_ResourceGroupName, ' (', SubAccountName, ')'))\n| order by EffectiveCost desc\n| render columnchart", + "id": "61b26784-6a73-4e80-85b2-9c5cfbd2dd06", + "usedVariables": ["CostsByMonth", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByMonth;\nlet all = costs | where isnotempty(ResourceId) | summarize sum(EffectiveCost) by ResourceId;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = ResourceId in (topX)\n| extend ResourceId = iff(inTopX, ResourceId, otherId)\n| extend ResourceName = iff(inTopX, ResourceName, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2),\n ResourceType = take_any(ResourceType),\n ResourceName = take_any(ResourceName)\n by\n ChargePeriodStart,\n ResourceId\n| project ChargePeriodStart, EffectiveCost, RG = iff(ResourceId == otherId, ResourceName, strcat(ResourceName, ' (', ResourceType, ')'))\n| order by EffectiveCost desc\n| render columnchart", + "id": "3924981c-23e4-464d-a872-045df1752750", + "usedVariables": ["CostsByMonth", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | summarize \n EffectiveCost = sum(EffectiveCost),\n ResourceName = take_any(ResourceName),\n ResourceType = take_any(ResourceType),\n RegionName = take_any(RegionName),\n x_ResourceGroupName = take_any(x_ResourceGroupName),\n SubAccountName = take_any(SubAccountName)\n by\n ChargePeriodStart,\n ResourceId\n | as per\n | union (\n per\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n ResourceId,\n ResourceName,\n ResourceType,\n RegionName,\n x_ResourceGroupName,\n SubAccountName\n )\n | order by ChargePeriodStart asc\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), ResourceName, ResourceType, RegionName, x_ResourceGroupName, SubAccountName)\n| order by Total desc", + "id": "c7be613e-deb4-4779-ad75-4445e8d5e01f", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByDay;\nlet all = costs | summarize sum(EffectiveCost) by ResourceId;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = ResourceId in (topX)\n| extend ResourceId = iff(inTopX, ResourceId, otherId)\n| extend ResourceName = iff(inTopX, ResourceName, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2),\n ResourceType = take_any(ResourceType),\n ResourceName = take_any(ResourceName)\n by\n ChargePeriodStart,\n ResourceId\n| project ChargePeriodStart, EffectiveCost, RG = iff(ResourceId == otherId, ResourceName, strcat(ResourceName, ' (', ResourceType, ')'))\n| order by EffectiveCost desc\n| render columnchart", + "id": "49e24ee0-91de-4b1c-973f-036a3c060aca", + "usedVariables": ["CostsByDay", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByMonth;\nlet all = costs | where isnotempty(ServiceCategory) | summarize sum(EffectiveCost) by ServiceCategory;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = ServiceCategory in (topX)\n| extend ServiceCategory = iff(inTopX, ServiceCategory, otherId)\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2)\n by\n ChargePeriodStart,\n ServiceCategory\n| project ChargePeriodStart, EffectiveCost, Category = ServiceCategory\n| order by EffectiveCost desc\n| render columnchart", + "id": "4c7a7614-9b8c-415b-a4e1-d2d53c023d31", + "usedVariables": ["CostsByMonth", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n ChargePeriodStart,\n ServiceCategory,\n ServiceName\n | as per\n | union (\n per\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n ServiceCategory,\n ServiceName\n )\n | order by ChargePeriodStart asc\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), ServiceCategory)\n| order by Total desc", + "id": "1d273b55-d2ea-427c-8a5f-01f6c240e98a", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByMonth;\nlet all = costs | where isnotempty(ResourceType) | summarize sum(EffectiveCost) by ResourceType;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = ResourceType in (topX)\n| extend ResourceType = iff(inTopX, ResourceType, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2)\n by\n ChargePeriodStart,\n ResourceType\n| project ChargePeriodStart, EffectiveCost, Type = ResourceType\n| order by EffectiveCost desc\n| render columnchart", + "id": "90e30901-a931-4a1d-b81e-0a1821032c3c", + "usedVariables": ["CostsByMonth", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByDay;\nlet all = costs | where isnotempty(ResourceType) | summarize sum(EffectiveCost) by ResourceType;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n| where isnotempty(ResourceType)\n//\n// Group rows after max count\n| extend inTopX = ResourceType in (topX)\n| extend ResourceType = iff(inTopX, ResourceType, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2)\n by\n ChargePeriodStart = startofday(ChargePeriodStart),\n ResourceType\n| project ChargePeriodStart, EffectiveCost, Type = ResourceType\n| order by EffectiveCost desc\n| render columnchart", + "id": "ebe41e27-e9f9-478e-ab90-fd1f87906766", + "usedVariables": ["CostsByDay", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | summarize \n EffectiveCost = sum(EffectiveCost),\n ResourceName = take_any(ResourceName),\n ResourceType = take_any(ResourceType),\n RegionName = take_any(RegionName),\n x_ResourceGroupName = take_any(x_ResourceGroupName),\n SubAccountName = take_any(SubAccountName)\n by\n ChargePeriodStart,\n ResourceId\n | as per\n | union (\n per\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n ResourceId,\n ResourceName,\n ResourceType,\n RegionName,\n x_ResourceGroupName,\n SubAccountName\n )\n | order by ChargePeriodStart asc\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), ResourceName, ResourceType, RegionName, x_ResourceGroupName, SubAccountName)\n| order by Total desc", + "id": "7f7b08a9-ae15-46f8-8b0f-767280375add", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByDay | where isnotempty(ResourceType);\nlet all = costs | summarize sum(EffectiveCost) by ResourceType;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n| where isnotempty(ResourceType)\n//\n// Group rows after max count\n| extend inTopX = ResourceType in (topX)\n| extend ResourceType = iff(inTopX, ResourceType, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2)\n by\n ResourceType\n| order by EffectiveCost desc\n| render columnchart", + "id": "a35b4c05-8ecb-4c51-9aaf-980af3d7923e", + "usedVariables": ["CostsByDay", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByDay | where isnotempty(ResourceType);\nlet all = costs | summarize ResourceCount = dcount(ResourceId) by ResourceType;\nlet count = toscalar(all | order by ResourceCount desc | count);\nlet topX = all | order by ResourceCount desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n| where isnotempty(ResourceType)\n//\n// Group rows after max count\n| extend inTopX = ResourceType in (topX)\n| extend ResourceType = iff(inTopX, ResourceType, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n ResourceCount = dcount(ResourceId)\n by\n ResourceType\n| order by ResourceCount desc\n| render columnchart", + "id": "9c5d3cf0-b6cb-45a2-acfd-b19df425bddf", + "usedVariables": ["CostsByDay", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nCostsByDay\n| where isnotempty(ResourceType)\n| summarize \n Count = dcount(ResourceId),\n EffectiveCost = sum(EffectiveCost),\n ListCost = sum(ListCost),\n ContractedCost = sum(ContractedCost)\n by\n ResourceType\n| order by Count desc\n| project \n Type = ResourceType,\n Count,\n Cost = round(EffectiveCost, 2),\n // NegotiatedSavings = round(ListCost - ContractedCost, 2),\n // CommitmentSavings = round(ContractedCost - EffectiveCost, 2),\n Savings = round(ListCost - EffectiveCost, 2),\n [\"Cost / Resource\"] = round(EffectiveCost / Count, 2)\n", + "id": "2d7b6447-2769-40b8-958a-f252dab68b1e", + "usedVariables": ["CostsByDay"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByDay\n| where isnotempty(ResourceType);\ncosts | summarize Value = tostring(dcount(ResourceId)) by Label = \"Resources\", Order = 10\n| union (costs | summarize Value = tostring(dcount(ResourceType)) by Label = \"Resource types\", Order = 11)\n| union (costs | summarize Count = dcount(ResourceId) by Value = ResourceType | order by Count desc | limit 1 | extend Label = \"Most used\", Order = 21)\n| union (costs | summarize sum(EffectiveCost) by Value = ResourceType | order by sum_EffectiveCost desc | limit 1 | extend Label = \"Most cost\", Order = 22)\n| union (costs | summarize AllTypes = dcount(ResourceType), CommittedTypes = dcountif(ResourceType, isnotempty(CommitmentDiscountType)) by Label = \"Covered by commitment discounts\", Order = 31 | extend Value = strcat(round(1.0 * CommittedTypes / AllTypes * 100, 1), '%'))\n| union (costs | summarize Savings = sum(ListCost - EffectiveCost) by Value = ResourceType | order by Savings desc | limit 1 | extend Label = \"Most savings\", Order = 32)\n| union (costs | summarize CostPerResource = sum(EffectiveCost) / dcount(ResourceId) by Value = ResourceType | order by CostPerResource desc | limit 1 | extend Label = \"Most expensive (cost / resource)\", Order = 41)\n| union (costs | where ResourceType !in (Costs_v1_0 | where ChargePeriodStart < ago(numberOfDays * 1d) - 1d | distinct ResourceType) | summarize Count = dcount(ResourceId) by ResourceType | order by Count desc | as d | count | extend Label = \"New in last n days\", Value = case(Count == 0, '(none)', Count == 1, toscalar(d | project ResourceType), strcat(toscalar(d | limit 1 | project ResourceType), ' and ', (Count - 1), ' more')), Order = 42)\n| order by Order asc\n", + "id": "f062533b-8c94-412f-bf83-0eb5cd06063d", + "usedVariables": ["CostsByDay", "numberOfDays"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\n| where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n| summarize EffectiveCost = sum(EffectiveCost) by ChargePeriodStart = startofday(ChargePeriodStart)\n| order by ChargePeriodStart asc\n| extend PreviousEffectiveCost = prev(EffectiveCost)\n| project ChargePeriodStart, EffectiveCost, Change = iif(isempty(PreviousEffectiveCost), todouble(0), todouble((EffectiveCost - PreviousEffectiveCost) / PreviousEffectiveCost)) * 100\n", + "id": "1d9c166d-22b6-48fd-9a90-9f983083ecc7", + "usedVariables": ["numberOfDays"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\n| where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n| where isnotempty(x_SkuDescription)\n//\n// Only include SKUs with effective prices\n| where x_EffectiveUnitPrice != 0 and isnotempty(x_EffectiveUnitPrice)\n//\n// Only include SKUs with negotiated discounts and not commitment discounts\n| where ListUnitPrice > x_EffectiveUnitPrice\n| where isempty(CommitmentDiscountStatus)\n//\n| summarize \n x_ResourceCount = dcount(ResourceId),\n EffectiveCost = round(sum(EffectiveCost), 2),\n BilledCost = round(sum(BilledCost), 2),\n ListUnitPrice = round(take_any(ListUnitPrice), 4),\n ContractedUnitPrice = round(take_any(ContractedUnitPrice), 4),\n x_EffectiveUnitPrice = round(take_any(x_EffectiveUnitPrice), 4),\n PricingQuantity = sum(PricingQuantity)\n by\n x_SkuDescription,\n PricingUnit,\n CommitmentDiscountType,\n x_SkuTerm\n| order by EffectiveCost desc\n| project \n x_SkuDescription,\n // CommitmentDiscountType,\n // x_SkuTerm,\n Quantity = round(PricingQuantity, 4),\n Unit = PricingUnit,\n // Resources = x_ResourceCount,\n List = ListUnitPrice,\n // ContractedUnitPrice,\n // x_EffectiveUnitPrice,\n Discount = round(ListUnitPrice - x_EffectiveUnitPrice, 4),\n // BilledCost,\n Cost = EffectiveCost\n| where Discount > 0\n", + "id": "af6424d4-8f73-4b81-bfdd-f0287ebcaaca", + "usedVariables": ["numberOfDays"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\n| where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n| where isnotempty(x_SkuDescription)\n//\n// Only include SKUs with effective prices\n| where x_EffectiveUnitPrice != 0 and isnotempty(x_EffectiveUnitPrice)\n//\n// Only include SKUs with commitment discounts\n| where isnotempty(CommitmentDiscountStatus)\n//\n| summarize \n x_ResourceCount = dcount(ResourceId),\n EffectiveCost = round(sum(EffectiveCost), 2),\n BilledCost = round(sum(BilledCost), 2),\n ListUnitPrice = round(take_any(ListUnitPrice), 4),\n ContractedUnitPrice = round(take_any(ContractedUnitPrice), 4),\n x_EffectiveUnitPrice = round(take_any(x_EffectiveUnitPrice), 4),\n PricingQuantity = sum(PricingQuantity)\n by\n x_SkuDescription,\n PricingUnit,\n CommitmentDiscountType,\n x_SkuTerm\n| order by EffectiveCost desc\n| project \n x_SkuDescription,\n CommitmentDiscountType,\n Term = case(\n isempty(x_SkuTerm) or x_SkuTerm <= 0, '',\n x_SkuTerm < 12, strcat(x_SkuTerm, ' month', iff(x_SkuTerm != 1, 's', '')),\n strcat(x_SkuTerm / 12, ' year', iff(x_SkuTerm != 12, 's', ''))\n ),\n Quantity = round(PricingQuantity, 4),\n Unit = PricingUnit,\n // Resources = x_ResourceCount,\n List = ListUnitPrice,\n // ContractedUnitPrice,\n // x_EffectiveUnitPrice,\n Discount = round(ListUnitPrice - x_EffectiveUnitPrice, 4),\n // BilledCost,\n Cost = EffectiveCost\n//| where Discount > 0\n", + "id": "c4f6542d-a9cb-4284-bd4e-b9f94ad02192", + "usedVariables": ["numberOfDays"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\n| where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n| where isnotempty(x_SkuDescription)\n//\n// Only include SKUs with effective prices\n| where x_EffectiveUnitPrice != 0 and isnotempty(x_EffectiveUnitPrice)\n//\n// Only include SKUs without any discounts\n| where ListUnitPrice == x_EffectiveUnitPrice\n| where isempty(CommitmentDiscountStatus)\n//\n| summarize \n x_ResourceCount = dcount(ResourceId),\n EffectiveCost = round(sum(EffectiveCost), 2),\n BilledCost = round(sum(BilledCost), 2),\n ListUnitPrice = round(take_any(ListUnitPrice), 4),\n ContractedUnitPrice = round(take_any(ContractedUnitPrice), 4),\n x_EffectiveUnitPrice = round(take_any(x_EffectiveUnitPrice), 4),\n PricingQuantity = sum(PricingQuantity)\n by\n x_SkuDescription,\n PricingUnit,\n CommitmentDiscountType,\n x_SkuTerm\n| order by EffectiveCost desc\n| project \n x_SkuDescription,\n // CommitmentDiscountType,\n // x_SkuTerm,\n Quantity = round(PricingQuantity, 4),\n Unit = PricingUnit,\n // Resources = x_ResourceCount,\n List = ListUnitPrice,\n // ContractedUnitPrice,\n // x_EffectiveUnitPrice,\n Discount = round(ListUnitPrice - x_EffectiveUnitPrice, 4),\n // BilledCost,\n Cost = EffectiveCost\n| where Discount == 0\n", + "id": "00ae3917-c783-45f6-a04e-9113e4c5d445", + "usedVariables": ["numberOfDays"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let doubleGroupCount = maxGroupCount * 2;\nlet costs = Costs_v1_0\n| where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n| where isnotempty(x_SkuDescription)\n;\nlet all = costs | summarize EffectiveCost = round(sum(EffectiveCost), 2) by x_SkuDescription;\nlet count = toscalar(all | count);\nlet topX = all | order by EffectiveCost desc | limit doubleGroupCount;\ncosts\n//\n// Group rows after max count\n| extend inTopX = x_SkuDescription in (topX)\n| extend x_SkuDescription = iff(inTopX, x_SkuDescription, strcat('(', (count - doubleGroupCount), ' others)'))\n//\n| summarize EffectiveCost = round(sum(EffectiveCost), 2) by SKU = x_SkuDescription\n| order by EffectiveCost desc\n", + "id": "d8a4634e-7ebe-47ce-83b5-ff7f50f6bee6", + "usedVariables": ["maxGroupCount", "numberOfDays"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nCostsByMonth\n| where ChargeCategory == 'Purchase'\n| project\n ChargePeriodStart = substring(ChargePeriodStart, 0, 10),\n x_SkuDescription,\n CommitmentDiscountType,\n Term = case(isempty(x_SkuTerm) or x_SkuTerm <= 0, '', x_SkuTerm < 12, strcat(x_SkuTerm, ' month', iff(x_SkuTerm != 1, 's', '')), strcat(x_SkuTerm / 12, ' year', iff(x_SkuTerm != 12, 's', ''))),\n PricingQuantity,\n BilledCost,\n BillingCurrency\n| order by ChargePeriodStart desc\n", + "id": "98c9b9b5-bebf-41f8-8319-5fa2523f9dd0", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nCostsByMonth\n| as costs\n| where ChargeCategory == 'Purchase'\n| where isnotempty(CommitmentDiscountType)\n| project\n ChargePeriodStart = substring(ChargePeriodStart, 0, 10),\n x_SkuDescription,\n CommitmentDiscountType,\n Term = case(isempty(x_SkuTerm) or x_SkuTerm <= 0, '', x_SkuTerm < 12, strcat(x_SkuTerm, ' month', iff(x_SkuTerm != 1, 's', '')), strcat(x_SkuTerm / 12, ' year', iff(x_SkuTerm != 12, 's', ''))),\n ChargeFrequency,\n ChargeClass,\n PricingQuantity,\n Utilization = double(0),\n BilledCost,\n x_SkuOrderId\n| join kind=leftouter (\n costs\n | where ChargeCategory == 'Usage'\n | where isnotempty(CommitmentDiscountId)\n //\n | extend x_CommitmentDiscountUtilizationPotential = case(\n ProviderName == 'Microsoft', EffectiveCost,\n CommitmentDiscountCategory == 'Usage', ConsumedQuantity,\n CommitmentDiscountCategory == 'Spend', EffectiveCost,\n decimal(0)\n )\n | extend x_CommitmentDiscountUtilizationAmount = iff(CommitmentDiscountStatus == 'Used', x_CommitmentDiscountUtilizationPotential, decimal(0))\n //\n | summarize\n x_CommitmentDiscountUtilizationAmount = sum(x_CommitmentDiscountUtilizationAmount),\n x_CommitmentDiscountUtilizationPotential = sum(x_CommitmentDiscountUtilizationPotential)\n by\n x_SkuOrderId\n | project\n x_SkuOrderId,\n Utilization = round(x_CommitmentDiscountUtilizationAmount / x_CommitmentDiscountUtilizationPotential * 100, 1)\n) on x_SkuOrderId\n| extend Utilization = coalesce(Utilization1, double(0))\n| project-away x_SkuOrderId, x_SkuOrderId1, Utilization1\n| order by ChargePeriodStart desc\n\n\n", + "id": "35a3a2b3-4ab0-4449-96f7-c78db789089e", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let data = materialize(\n CostsByMonth | extend Period = 'Last n months'\n | union (CostsByDay | extend Period = 'Last n days')\n | summarize \n ListCost = round(sum(ListCost), 2),\n ContractedCost = round(sum(ContractedCost), 2),\n EffectiveCost = round(sum(EffectiveCost), 2)\n by\n Period\n | project Period, json = todynamic(strcat('[{ \"Label\":\"List\", \"Value\":', ListCost, ' }, { \"Label\":\"Contracted\", \"Value\":', ContractedCost, ' }, { \"Label\":\"Effective\", \"Value\":', EffectiveCost, ' }]'))\n | mv-expand json\n | project Label = tostring(json.Label), Value = tolong(json.Value), Period\n);\ndata", + "id": "5ff29428-de83-4a2c-8f86-d8beebe68750", + "usedVariables": ["CostsByDay", "CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let data = materialize(\n CostsByMonth | extend Period = 'Last n months'\n | union (CostsByDay | extend Period = 'Last n days')\n | summarize\n ListCost = round(sum(ListCost), 2),\n ContractedCost = round(sum(ContractedCost), 2),\n EffectiveCost = round(sum(EffectiveCost), 2)\n by\n Period\n | project Period, json = todynamic(strcat('[{ \"Label\":\"Total\", \"Value\":', ListCost - EffectiveCost, ' }, { \"Label\":\"Negotiated\", \"Value\":', ListCost - ContractedCost, ' }, { \"Label\":\"Commitment\", \"Value\":', ContractedCost - EffectiveCost, ' }]'))\n | mv-expand json\n | project Label = tostring(json.Label), Value = tolong(json.Value), Period\n);\ndata\n", + "id": "f5f240a8-a818-4f27-bdfb-e96fcfe433bd", + "usedVariables": ["CostsByDay", "CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nCosts_v1_0\n| where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n| where ChargeCategory == 'Usage'\n| where isnotempty(CommitmentDiscountId)\n//\n| extend x_CommitmentDiscountUtilizationPotential = case(\n ProviderName == 'Microsoft', EffectiveCost,\n CommitmentDiscountCategory == 'Usage', ConsumedQuantity,\n CommitmentDiscountCategory == 'Spend', EffectiveCost,\n decimal(0)\n)\n| extend x_CommitmentDiscountUtilizationAmount = iff(CommitmentDiscountStatus == 'Used', x_CommitmentDiscountUtilizationPotential, decimal(0))\n//\n| summarize\n CommitmentDiscountName = take_any(CommitmentDiscountName),\n CommitmentDiscountType = take_any(CommitmentDiscountType),\n x_SkuTerm = take_any(x_SkuTerm),\n ListCost = sum(ListCost),\n ContractedCost = sum(ContractedCost),\n EffectiveCost = sum(EffectiveCost),\n x_CommitmentDiscountUtilizationAmount = sum(x_CommitmentDiscountUtilizationAmount),\n x_CommitmentDiscountUtilizationPotential = sum(x_CommitmentDiscountUtilizationPotential)\n by\n CommitmentDiscountId\n| order by EffectiveCost desc\n| project\n CommitmentDiscountName,\n CommitmentDiscountType,\n Term = case(isempty(x_SkuTerm) or x_SkuTerm <= 0, '', x_SkuTerm < 12, strcat(x_SkuTerm, ' month', iff(x_SkuTerm != 1, 's', '')), strcat(x_SkuTerm / 12, ' year', iff(x_SkuTerm != 12, 's', ''))),\n Utilization = round(x_CommitmentDiscountUtilizationAmount / x_CommitmentDiscountUtilizationPotential * 100, 1),\n Cost = round(EffectiveCost, 2),\n Savings = round(ListCost - EffectiveCost, 2)\n", + "id": "d7f31381-ba44-46a1-ad3e-dc6b8826706d", + "usedVariables": ["numberOfDays"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let data = materialize(\n Costs_v1_0\n | where ChargePeriodStart >= startofmonth(startofmonth(now()) - 1d)\n // | where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n //\n // Don't double-count commitment discount purchases\n | where ChargeCategory == 'Usage' or isempty(CommitmentDiscountId)\n //\n | summarize \n ListCost = sum(ListCost),\n ContractedCost = sum(ContractedCost),\n EffectiveCost = sum(EffectiveCost)\n | extend CommitmentDiscountSavings = ContractedCost - EffectiveCost\n | extend NegotiatedDiscountSavings = ListCost - ContractedCost\n | extend TotalSavings = ListCost - EffectiveCost\n | project json = todynamic(strcat('[',\n '{ \"order\":11, \"type\":\"List\", \"label\":\"Cost without discounts\", \"value\":\"', numberstring(round(ListCost, 2)), '\" },',\n '{ \"order\":12, \"type\":\"\", \"label\":\"\", \"value\":\"➖\" },',\n '{ \"order\":13, \"type\":\"Contracted\", \"label\":\"After negotiated discounts\", \"value\":\"', numberstring(round(ContractedCost, 2)), '\" },',\n '{ \"order\":14, \"type\":\"\", \"label\":\"\", \"value\":\"🟰\" },',\n '{ \"order\":15, \"type\":\"PartialSavings\", \"label\":\"Negotiated savings\", \"value\":\"', numberstring(round(NegotiatedDiscountSavings, 2)), '\" },',\n //\n '{ \"order\":21, \"type\":\"Contracted\", \"label\":\"After negotiated discounts\", \"value\":\"', numberstring(round(ContractedCost, 2)), '\" },',\n '{ \"order\":22, \"type\":\"\", \"label\":\"\", \"value\":\"➖\" },',\n '{ \"order\":23, \"type\":\"Effective\", \"label\":\"After commitment discounts\", \"value\":\"', numberstring(round(EffectiveCost, 2)), '\" },',\n '{ \"order\":24, \"type\":\"\", \"label\":\"\", \"value\":\"🟰\" },',\n '{ \"order\":25, \"type\":\"PartialSavings\", \"label\":\"Commitment savings\", \"value\":\"', numberstring(round(CommitmentDiscountSavings, 2)), '\" },',\n //\n '{ \"order\":31, \"type\":\"List\", \"label\":\"Cost without discounts\", \"value\":\"', numberstring(round(ListCost, 2)), '\" },',\n '{ \"order\":32, \"type\":\"\", \"label\":\"\", \"value\":\"➖\" },',\n '{ \"order\":33, \"type\":\"Effective\", \"label\":\"After commitment discounts\", \"value\":\"', numberstring(round(EffectiveCost, 2)), '\" },',\n '{ \"order\":34, \"type\":\"\", \"label\":\"\", \"value\":\"🟰\" },',\n '{ \"order\":35, \"type\":\"TotalSavings\", \"label\":\"Total savings\", \"value\":\"', numberstring(round(TotalSavings, 2)), '\" }',\n ']'))\n | mv-expand json\n | order by toint(json.order) asc\n | project Label = tostring(json.label), Value = tostring(json.value), Type = tostring(json.type)\n);\ndata", + "id": "e17346d1-0227-4aa4-8765-f9b4bf43bed5", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let data = materialize(\n Costs_v1_0\n | where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n //\n // Don't double-count commitment discount purchases\n | where ChargeCategory == 'Usage' or isempty(CommitmentDiscountId)\n //\n | summarize \n ListCost = sum(ListCost),\n ContractedCost = sum(ContractedCost),\n EffectiveCost = sum(EffectiveCost)\n | extend CommitmentDiscountSavings = ContractedCost - EffectiveCost\n | extend NegotiatedDiscountSavings = ListCost - ContractedCost\n | extend TotalSavings = ListCost - EffectiveCost\n | project json = todynamic(strcat('[',\n '{ \"order\":11, \"type\":\"List\", \"label\":\"Cost without discounts\", \"value\":\"', numberstring(round(ListCost, 2)), '\" },',\n '{ \"order\":12, \"type\":\"\", \"label\":\"\", \"value\":\"➖\" },',\n '{ \"order\":13, \"type\":\"Contracted\", \"label\":\"After negotiated discounts\", \"value\":\"', numberstring(round(ContractedCost, 2)), '\" },',\n '{ \"order\":14, \"type\":\"\", \"label\":\"\", \"value\":\"🟰\" },',\n '{ \"order\":15, \"type\":\"PartialSavings\", \"label\":\"Negotiated savings\", \"value\":\"', numberstring(round(NegotiatedDiscountSavings, 2)), '\" },',\n //\n '{ \"order\":21, \"type\":\"Contracted\", \"label\":\"After negotiated discounts\", \"value\":\"', numberstring(round(ContractedCost, 2)), '\" },',\n '{ \"order\":22, \"type\":\"\", \"label\":\"\", \"value\":\"➖\" },',\n '{ \"order\":23, \"type\":\"Effective\", \"label\":\"After commitment discounts\", \"value\":\"', numberstring(round(EffectiveCost, 2)), '\" },',\n '{ \"order\":24, \"type\":\"\", \"label\":\"\", \"value\":\"🟰\" },',\n '{ \"order\":25, \"type\":\"PartialSavings\", \"label\":\"Commitment savings\", \"value\":\"', numberstring(round(CommitmentDiscountSavings, 2)), '\" },',\n //\n '{ \"order\":31, \"type\":\"List\", \"label\":\"Cost without discounts\", \"value\":\"', numberstring(round(ListCost, 2)), '\" },',\n '{ \"order\":32, \"type\":\"\", \"label\":\"\", \"value\":\"➖\" },',\n '{ \"order\":33, \"type\":\"Effective\", \"label\":\"After commitment discounts\", \"value\":\"', numberstring(round(EffectiveCost, 2)), '\" },',\n '{ \"order\":34, \"type\":\"\", \"label\":\"\", \"value\":\"🟰\" },',\n '{ \"order\":35, \"type\":\"TotalSavings\", \"label\":\"Total savings\", \"value\":\"', numberstring(round(TotalSavings, 2)), '\" }',\n ']'))\n | mv-expand json\n | order by toint(json.order) asc\n | project Label = tostring(json.label), Value = tostring(json.value), Type = tostring(json.type)\n);\ndata", + "id": "f1ef29df-7a1d-4dd0-8619-0c0164707b31", + "usedVariables": ["numberOfDays"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let data = materialize(\n Costs_v1_0\n | where ChargePeriodStart >= startofmonth(startofmonth(now()) - 1d)\n // | where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n //\n // Don't double-count commitment discount purchases\n | where isnotempty(CommitmentDiscountStatus)\n //\n // Guarantee there's a row for every combination\n | union (\n print json = dynamic([\n {\"order\": 11, \"CommitmentDiscountType\": \"Reservation\", \"CommitmentDiscountStatus\": \"Used\"},\n {\"order\": 12, \"CommitmentDiscountType\": \"Reservation\", \"CommitmentDiscountStatus\": \"Unused\"},\n {\"order\": 21, \"CommitmentDiscountType\": \"Savings Plan\", \"CommitmentDiscountStatus\": \"Used\"},\n {\"order\": 22, \"CommitmentDiscountType\": \"Savings Plan\", \"CommitmentDiscountStatus\": \"Unused\"}\n ])\n | mv-expand json\n | evaluate bag_unpack(json)\n | extend EffectiveCost = todecimal(0)\n )\n //\n | summarize Value = sum(EffectiveCost), order = sum(order) by CommitmentDiscountStatus, CommitmentDiscountType\n | order by order asc\n | project Label = strcat(CommitmentDiscountStatus, ' ', tolower(CommitmentDiscountType), 's'), Value\n);\ndata", + "id": "7d0c2c1f-338b-4534-b173-36b284779131", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let data = materialize(\n Costs_v1_0\n | where ChargePeriodStart >= ago(numberOfDays * 1d) - 1d and ChargePeriodStart < ago(1d)\n //\n // Don't double-count commitment discount purchases\n | where isnotempty(CommitmentDiscountStatus)\n //\n // Guarantee there's a row for every combination\n | union (\n print json = dynamic([\n {\"order\": 11, \"CommitmentDiscountType\": \"Reservation\", \"CommitmentDiscountStatus\": \"Used\"},\n {\"order\": 12, \"CommitmentDiscountType\": \"Reservation\", \"CommitmentDiscountStatus\": \"Unused\"},\n {\"order\": 21, \"CommitmentDiscountType\": \"Savings Plan\", \"CommitmentDiscountStatus\": \"Used\"},\n {\"order\": 22, \"CommitmentDiscountType\": \"Savings Plan\", \"CommitmentDiscountStatus\": \"Unused\"}\n ])\n | mv-expand json\n | evaluate bag_unpack(json)\n | extend EffectiveCost = todecimal(0)\n )\n //\n | summarize Value = sum(EffectiveCost), order = sum(order) by CommitmentDiscountStatus, CommitmentDiscountType\n | order by order asc\n | project Label = strcat(CommitmentDiscountStatus, ' ', tolower(CommitmentDiscountType), 's'), Value\n);\ndata", + "id": "84ecad69-79ac-45b9-a8af-60be28dcc748", + "usedVariables": ["numberOfDays"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n Costs_v1_0\n | where ChargePeriodStart >= monthsago(numberOfMonths)\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n ChargePeriodStart = startofmonth(ChargePeriodStart),\n ServiceCategory,\n ServiceName\n | as per\n | union (\n per\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n ServiceCategory,\n ServiceName\n )\n | order by ChargePeriodStart asc\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), ServiceCategory)\n| order by Total desc", + "id": "85320475-730b-411f-98d5-fbc345bf5e68", + "usedVariables": ["numberOfMonths"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "CostsByMonth\n//\n// Filter out commitment discount purchases\n| where ChargeCategory == 'Usage' or isempty(CommitmentDiscountId)\n//\n| summarize \n ListCost = sum(ListCost),\n ContractedCost = sum(ContractedCost),\n EffectiveCost = sum(EffectiveCost)\n by\n ChargePeriodStart = startofmonth(ChargePeriodStart),\n CommitmentDiscountType\n| project\n ChargePeriodStart,\n Savings = round(ListCost - EffectiveCost, 2),\n Type = case(\n isnotempty(CommitmentDiscountType), CommitmentDiscountType,\n 'Negotiated'\n )", + "id": "5bbb5369-ac95-45fc-853c-a6a2ce6a9e7b", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "CostsByMonth\n//\n// Filter out commitment discount purchases\n| where ChargeCategory == 'Usage' or isempty(CommitmentDiscountId)\n//\n| summarize \n Savings = round(sum(ListCost - EffectiveCost), 2)\n by\n Type = case(\n isnotempty(CommitmentDiscountType), CommitmentDiscountType,\n 'Negotiated'\n )", + "id": "93f0eb9f-fa4d-4c54-96c2-8c1d3387d13a", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "CostsByDay\n//\n// Filter out commitment discount purchases\n| where ChargeCategory == 'Usage' or isempty(CommitmentDiscountId)\n//\n| summarize \n ListCost = sum(ListCost),\n ContractedCost = sum(ContractedCost),\n EffectiveCost = sum(EffectiveCost)\n by\n ChargePeriodStart = startofday(ChargePeriodStart),\n CommitmentDiscountType\n| project\n ChargePeriodStart,\n Savings = round(ListCost - EffectiveCost, 2),\n Type = case(\n isnotempty(CommitmentDiscountType), CommitmentDiscountType,\n 'Negotiated'\n )", + "id": "5c442903-65b0-4b53-9e7c-3ea9c1af7be5", + "usedVariables": ["CostsByDay"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "CostsByDay\n//\n// Filter out commitment discount purchases\n| where ChargeCategory == 'Usage' or isempty(CommitmentDiscountId)\n//\n| summarize \n Savings = round(sum(ListCost - EffectiveCost), 2)\n by\n Type = case(\n isnotempty(CommitmentDiscountType), CommitmentDiscountType,\n 'Negotiated'\n )", + "id": "9a9ee4b0-a37d-475f-bf1d-f51573243491", + "usedVariables": ["CostsByDay"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | where ChargeCategory == 'Usage'\n | where isnotempty(CommitmentDiscountId)\n | where EffectiveCost != 0\n | extend x_ResourceGroupId = strcat(SubAccountId, '/resourcegroups/', x_ResourceGroupName)\n | summarize \n EffectiveCost = sum(EffectiveCost),\n SubAccountName = take_any(SubAccountName),\n x_ResourceGroupName = take_any(x_ResourceGroupName),\n CommitmentDiscountName = take_any(CommitmentDiscountName),\n CommitmentDiscountType = take_any(CommitmentDiscountType)\n by\n ChargePeriodStart,\n SubAccountId,\n x_ResourceGroupId,\n CommitmentDiscountId\n | as per\n | union (\n per\n | summarize \n EffectiveCost = sum(EffectiveCost),\n SubAccountName = take_any(SubAccountName),\n x_ResourceGroupName = take_any(x_ResourceGroupName),\n CommitmentDiscountName = take_any(CommitmentDiscountName),\n CommitmentDiscountType = take_any(CommitmentDiscountType)\n by\n x_ResourceGroupId,\n CommitmentDiscountId\n )\n | order by ChargePeriodStart asc\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), x_ResourceGroupName, SubAccountName, CommitmentDiscountName, CommitmentDiscountType)\n| order by x_ResourceGroupName asc, SubAccountName asc, Total desc", + "id": "377e3693-0738-45d7-97d9-4b6e71ec5b36", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet data = (\n CostsByMonth\n | where ChargeCategory == 'Usage'\n | where isnotempty(CommitmentDiscountId)\n | where EffectiveCost != 0\n | summarize \n BilledCost = sum(BilledCost),\n EffectiveCost = sum(EffectiveCost),\n ContractedCost = sum(ContractedCost),\n ListCost = sum(ListCost),\n SubAccountName = take_any(SubAccountName),\n CommitmentDiscountName = take_any(CommitmentDiscountName),\n CommitmentDiscountType = take_any(CommitmentDiscountType)\n by\n ChargePeriodStart,\n SubAccountId,\n CommitmentDiscountId\n | as per\n | union (\n per\n | summarize \n BilledCost = sum(BilledCost),\n EffectiveCost = sum(EffectiveCost),\n ContractedCost = sum(ContractedCost),\n ListCost = sum(ListCost),\n SubAccountName = take_any(SubAccountName),\n CommitmentDiscountName = take_any(CommitmentDiscountName),\n CommitmentDiscountType = take_any(CommitmentDiscountType)\n by\n SubAccountId,\n CommitmentDiscountId\n )\n | order by ChargePeriodStart asc\n | extend BilledCost = todouble(round(BilledCost, 2))\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ContractedCost = todouble(round(ContractedCost, 2))\n | extend ListCost = todouble(round(ListCost, 2))\n | extend CommitmentDiscountSavings = todouble(round(ContractedCost - EffectiveCost, 2))\n | extend NegotiatedDiscountSavings = todouble(round(ListCost - ContractedCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), SubAccountName, CommitmentDiscountName, CommitmentDiscountType)\n| order by SubAccountName asc, Total desc", + "id": "13cad52d-91e7-4ab4-aad5-4aae21c1019a", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "CostsByDay\n| where ChargeCategory == 'Usage'\n| where isnotempty(CommitmentDiscountId)\n| where EffectiveCost != 0\n| summarize \n EffectiveCost = sum(EffectiveCost),\n ResourceName = take_any(ResourceName),\n ResourceType = take_any(ResourceType),\n RegionName = take_any(RegionName),\n x_ResourceGroupName = take_any(x_ResourceGroupName),\n SubAccountName = take_any(SubAccountName),\n CommitmentDiscountName = take_any(CommitmentDiscountName),\n CommitmentDiscountType = take_any(CommitmentDiscountType)\n by\n ResourceId,\n CommitmentDiscountId\n| project \n CommitmentDiscountType,\n CommitmentDiscountName,\n ResourceName,\n ResourceType,\n RegionName,\n x_ResourceGroupName,\n SubAccountName,\n EffectiveCost = round(EffectiveCost, 2)\n| order by CommitmentDiscountType asc, CommitmentDiscountName asc, ResourceName asc, ResourceType asc, x_ResourceGroupName asc, SubAccountName asc, EffectiveCost desc", + "id": "dcf69b47-233e-4bc4-b914-3f6f09f4cb82", + "usedVariables": ["CostsByDay"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByMonth\n| extend x_ToolkitTool = tostring(Tags['ftk-tool'])\n| where x_ToolkitTool == 'FinOps hubs'\n| extend x_ToolkitVersion = tostring(Tags['ftk-version'])\n| extend x_ResourceParentId = tostring(Tags['cm-resource-parent'])\n| extend x_ResourceParentName = database('Ingestion').parse_resourceid(x_ResourceParentId).ResourceName\n;\nlet all = costs | summarize sum(EffectiveCost) by x_ResourceParentId;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = x_ResourceParentId in (topX)\n| extend x_ResourceParentId = iff(inTopX, x_ResourceParentId, otherId)\n| extend x_ResourceParentName = iff(inTopX, x_ResourceParentName, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2),\n ResourceType = take_any(ResourceType),\n x_ResourceParentName = take_any(x_ResourceParentName),\n x_ResourceGroupName = take_any(x_ResourceGroupName),\n SubAccountName = take_any(SubAccountName)\n by\n ChargePeriodStart,\n x_ResourceParentId\n| project ChargePeriodStart, EffectiveCost, Hub = iff(x_ResourceParentId == otherId, x_ResourceParentName, strcat(x_ResourceParentName, ' (', x_ResourceGroupName, ' / ', SubAccountName, ')'))\n| order by EffectiveCost desc\n", + "id": "d7a9ff96-da17-4826-9fb5-b23f4c7b938d", + "usedVariables": ["CostsByMonth", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByDay\n| extend x_ToolkitTool = tostring(Tags['ftk-tool'])\n| where x_ToolkitTool == 'FinOps hubs'\n| extend x_ToolkitVersion = tostring(Tags['ftk-version'])\n| extend x_ResourceParentId = tostring(Tags['cm-resource-parent'])\n| extend x_ResourceParentName = database('Ingestion').parse_resourceid(x_ResourceParentId).ResourceName\n;\nlet all = costs | summarize sum(EffectiveCost) by x_ResourceParentId;\nlet count = toscalar(all | order by sum_EffectiveCost desc | count);\nlet topX = all | order by sum_EffectiveCost desc | limit maxGroupCount;\nlet otherId = '(others)';\ncosts\n//\n// Group rows after max count\n| extend inTopX = x_ResourceParentId in (topX)\n| extend x_ResourceParentId = iff(inTopX, x_ResourceParentId, otherId)\n| extend x_ResourceParentName = iff(inTopX, x_ResourceParentName, strcat('(', (count - maxGroupCount), ' others)'))\n//\n| summarize \n EffectiveCost = round(sum(EffectiveCost), 2),\n ResourceType = take_any(ResourceType),\n x_ResourceParentName = take_any(x_ResourceParentName),\n x_ResourceGroupName = take_any(x_ResourceGroupName),\n SubAccountName = take_any(SubAccountName)\n by\n ChargePeriodStart,\n x_ResourceParentId\n| project ChargePeriodStart, EffectiveCost, Hub = iff(x_ResourceParentId == otherId, x_ResourceParentName, strcat(x_ResourceParentName, ' (', x_ResourceGroupName, ' / ', SubAccountName, ')'))\n| order by EffectiveCost desc\n", + "id": "13813a00-e634-4428-9eac-ea255fd1eaca", + "usedVariables": ["CostsByDay", "maxGroupCount"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let monthname = dynamic(['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\nlet costs = CostsByMonth\n| extend x_ToolkitTool = tostring(Tags['ftk-tool'])\n| where x_ToolkitTool == 'FinOps hubs'\n| extend x_ToolkitVersion = tostring(Tags['ftk-version'])\n| extend x_ResourceParentId = tostring(Tags['cm-resource-parent'])\n| extend x_ResourceParentName = tostring(database('Ingestion').parse_resourceid(x_ResourceParentId).ResourceName)\n;\nlet data = (\n costs\n | summarize \n EffectiveCost = sum(EffectiveCost),\n x_ResourceParentName = take_any(x_ResourceParentName),\n RegionName = take_any(RegionName),\n x_ResourceGroupName = take_any(x_ResourceGroupName),\n SubAccountName = take_any(SubAccountName),\n x_ToolkitVersion = take_any(x_ToolkitVersion)\n by\n ChargePeriodStart,\n x_ResourceParentId\n | as per\n //\n // Append total\n | union (\n per\n | summarize \n EffectiveCost = sum(EffectiveCost)\n by\n x_ResourceParentId,\n x_ResourceParentName,\n x_ToolkitVersion,\n RegionName,\n x_ResourceGroupName,\n SubAccountName\n )\n | order by ChargePeriodStart asc\n | extend EffectiveCost = todouble(round(EffectiveCost, 2))\n | extend ChargePeriod = iff(isempty(ChargePeriodStart), strcat('Total'), strcat(format_datetime(ChargePeriodStart, 'yyyy-MM - '), monthname[monthofyear(ChargePeriodStart)]))\n);\ndata | evaluate pivot(ChargePeriod, sum(EffectiveCost), x_ResourceParentName, x_ToolkitVersion, RegionName, x_ResourceGroupName, SubAccountName)\n| project-rename Name = x_ResourceParentName, Version = x_ToolkitVersion\n| order by Total desc\n", + "id": "62bbceee-c089-45db-822c-0b4745358aa4", + "usedVariables": ["CostsByMonth"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": ".show cluster extents\n| where TableName contains '_final_v'\n| extend Dataset = tostring(split(TableName, '_final_v')[0])\n| extend FocusVersion = replace_string(tostring(split(TableName, '_final_v')[1]), '_', '.')\n| extend ToolkitVersion = tostring(extract(@'drop-by:ftk-version-([^\\s]+)', 1, Tags))\n// | extend Table = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 1, Tags))\n| extend Date = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 2, Tags))\n| extend Scope = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 5, Tags))\n| extend Date = todatetime(strcat(replace_string(trim(@'/', Date), '/', '-'), '-01'))\n| extend Scope = replace_regex(Scope, @'/[^/]+$', '')\n| project Dataset, FocusVersion, ToolkitVersion, Date, Scope, LastUpdate = MaxCreatedOn, OriginalSize, RowCount\n| extend ScopeId = database('Ingestion').parse_resourceid(Scope).ResourceName\n// TODO: Look up the name from cost data\n| extend ScopeResourceType = database('Ingestion').parse_resourceid(Scope).x_ResourceType\n// TODO: Clean up scope resource type display names -- | extend ScopeType = resource_type(ScopeResourceType).SingularDisplayName\n| summarize Rows = sum(RowCount) by Date, Dataset", + "id": "b98c9ed7-47b3-41c1-a596-fd9d32725b33", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": ".show cluster extents\n| where TableName contains '_final_v'\n| extend Dataset = tostring(split(TableName, '_final_v')[0])\n| where Dataset == 'Costs'\n| extend FocusVersion = replace_string(tostring(split(TableName, '_final_v')[1]), '_', '.')\n| extend ToolkitVersion = tostring(extract(@'drop-by:ftk-version-([^\\s]+)', 1, Tags))\n// | extend Table = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 1, Tags))\n| extend Date = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 2, Tags))\n| extend Scope = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 5, Tags))\n| extend Date = todatetime(strcat(replace_string(trim(@'/', Date), '/', '-'), '-01'))\n| extend Scope = replace_regex(Scope, @'/[^/]+$', '')\n| project Dataset, FocusVersion, ToolkitVersion, Date, Scope, LastUpdate = MaxCreatedOn, OriginalSize, RowCount\n| extend ScopeId = tostring(database('Ingestion').parse_resourceid(Scope).ResourceName)\n| extend ScopeResourceType = database('Ingestion').parse_resourceid(Scope).x_ResourceType\n// TODO: Clean up scope resource type display names -- | extend ScopeType = resource_type(ScopeResourceType).SingularDisplayName\n| summarize Rows = sum(RowCount) by Date, ScopeId", + "id": "187e22fe-3d78-45a2-a2bf-090ece144fd1", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": ".show cluster extents\n| where TableName contains '_final_v'\n| extend Dataset = tostring(split(TableName, '_final_v')[0])\n| where Dataset == 'Costs'\n| extend FocusVersion = replace_string(tostring(split(TableName, '_final_v')[1]), '_', '.')\n| extend ToolkitVersion = tostring(extract(@'drop-by:ftk-version-([^\\s]+)', 1, Tags))\n// | extend Table = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 1, Tags))\n| extend Date = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 2, Tags))\n| extend Scope = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 5, Tags))\n| extend Date = todatetime(strcat(replace_string(trim(@'/', Date), '/', '-'), '-01'))\n| extend Scope = replace_regex(Scope, @'/[^/]+$', '')\n| project Dataset, FocusVersion, ToolkitVersion, Date, Scope, LastUpdate = MaxCreatedOn, OriginalSize, RowCount\n| extend ScopeId = tostring(database('Ingestion').parse_resourceid(Scope).ResourceName)\n// TODO: Look up the name from cost data\n| extend ScopeResourceType = database('Ingestion').parse_resourceid(Scope).x_ResourceType\n// TODO: Clean up scope resource type display names -- | extend ScopeType = resource_type(ScopeResourceType).SingularDisplayName\n| summarize dcount(Scope)", + "id": "d2c522dc-ef4b-4714-a473-09350e275557", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": ".show cluster extents\n| where TableName contains '_final_v'\n| extend Dataset = tostring(split(TableName, '_final_v')[0])\n| where Dataset == 'Costs'\n| extend FocusVersion = replace_string(tostring(split(TableName, '_final_v')[1]), '_', '.')\n| extend ToolkitVersion = tostring(extract(@'drop-by:ftk-version-([^\\s]+)', 1, Tags))\n// | extend Table = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 1, Tags))\n| extend Date = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 2, Tags))\n| extend Scope = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 5, Tags))\n| extend Date = todatetime(strcat(replace_string(trim(@'/', Date), '/', '-'), '-01'))\n| extend Scope = replace_regex(Scope, @'/[^/]+$', '')\n| project Dataset, FocusVersion, ToolkitVersion, Date, Scope, LastUpdate = MaxCreatedOn, OriginalSize, RowCount\n| extend ScopeId = tostring(database('Ingestion').parse_resourceid(Scope).ResourceName)\n// TODO: Look up the name from cost data\n| extend ScopeResourceType = database('Ingestion').parse_resourceid(Scope).x_ResourceType\n// TODO: Clean up scope resource type display names -- | extend ScopeType = resource_type(ScopeResourceType).SingularDisplayName\n| summarize dcount(startofmonth(Date))", + "id": "6fe11b78-82ef-4e9a-8411-a65e5b0d8bba", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": ".show cluster extents\n| where TableName contains '_final_v'\n| extend Dataset = tostring(split(TableName, '_final_v')[0])\n| where Dataset == 'Prices'\n| extend FocusVersion = replace_string(tostring(split(TableName, '_final_v')[1]), '_', '.')\n| extend ToolkitVersion = tostring(extract(@'drop-by:ftk-version-([^\\s]+)', 1, Tags))\n// | extend Table = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 1, Tags))\n| extend Date = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 2, Tags))\n| extend Scope = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 5, Tags))\n| extend Date = todatetime(strcat(replace_string(trim(@'/', Date), '/', '-'), '-01'))\n| extend Scope = replace_regex(Scope, @'/[^/]+$', '')\n| project Dataset, FocusVersion, ToolkitVersion, Date, Scope, LastUpdate = MaxCreatedOn, OriginalSize, RowCount\n| extend ScopeId = tostring(database('Ingestion').parse_resourceid(Scope).ResourceName)\n// TODO: Look up the name from cost data\n| extend ScopeResourceType = database('Ingestion').parse_resourceid(Scope).x_ResourceType\n// TODO: Clean up scope resource type display names -- | extend ScopeType = resource_type(ScopeResourceType).SingularDisplayName\n| summarize Rows = sum(RowCount) by Date, ScopeId", + "id": "b3621977-59be-4f98-a034-a94479612115", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": ".show cluster extents\n| where TableName contains '_final_v'\n| extend Dataset = tostring(split(TableName, '_final_v')[0])\n| where Dataset == 'Recommendations'\n| extend FocusVersion = replace_string(tostring(split(TableName, '_final_v')[1]), '_', '.')\n| extend ToolkitVersion = tostring(extract(@'drop-by:ftk-version-([^\\s]+)', 1, Tags))\n// | extend Table = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 1, Tags))\n| extend Date = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 2, Tags))\n| extend Scope = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 5, Tags))\n| extend Date = todatetime(strcat(replace_string(trim(@'/', Date), '/', '-'), '-01'))\n| extend Scope = replace_regex(Scope, @'/[^/]+$', '')\n| project Dataset, FocusVersion, ToolkitVersion, Date, Scope, LastUpdate = MaxCreatedOn, OriginalSize, RowCount\n| extend ScopeId = tostring(database('Ingestion').parse_resourceid(Scope).ResourceName)\n// TODO: Look up the name from cost data\n| extend ScopeResourceType = database('Ingestion').parse_resourceid(Scope).x_ResourceType\n// TODO: Clean up scope resource type display names -- | extend ScopeType = resource_type(ScopeResourceType).SingularDisplayName\n| summarize Rows = sum(RowCount) by Date, ScopeId", + "id": "4a2a77fe-e819-4059-b027-dab0a1770a0a", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": ".show cluster extents\n| where TableName contains '_final_v'\n| extend Dataset = tostring(split(TableName, '_final_v')[0])\n| where Dataset == 'Transactions'\n| extend FocusVersion = replace_string(tostring(split(TableName, '_final_v')[1]), '_', '.')\n| extend ToolkitVersion = tostring(extract(@'drop-by:ftk-version-([^\\s]+)', 1, Tags))\n// | extend Table = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 1, Tags))\n| extend Date = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 2, Tags))\n| extend Scope = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 5, Tags))\n| extend Date = todatetime(strcat(replace_string(trim(@'/', Date), '/', '-'), '-01'))\n| extend Scope = replace_regex(Scope, @'/[^/]+$', '')\n| project Dataset, FocusVersion, ToolkitVersion, Date, Scope, LastUpdate = MaxCreatedOn, OriginalSize, RowCount\n| extend ScopeId = tostring(database('Ingestion').parse_resourceid(Scope).ResourceName)\n// TODO: Look up the name from cost data\n| extend ScopeResourceType = database('Ingestion').parse_resourceid(Scope).x_ResourceType\n// TODO: Clean up scope resource type display names -- | extend ScopeType = resource_type(ScopeResourceType).SingularDisplayName\n| summarize Rows = sum(RowCount) by Date, ScopeId", + "id": "8f1ad1ef-6f5e-4f20-a1c4-3941e871d0cd", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": ".show cluster extents\n| where TableName contains '_final_v'\n| extend Dataset = tostring(split(TableName, '_final_v')[0])\n| where Dataset == 'CommitmentDiscountUsage'\n| extend FocusVersion = replace_string(tostring(split(TableName, '_final_v')[1]), '_', '.')\n| extend ToolkitVersion = tostring(extract(@'drop-by:ftk-version-([^\\s]+)', 1, Tags))\n// | extend Table = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 1, Tags))\n| extend Date = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 2, Tags))\n| extend Scope = tostring(extract(@'drop-by:([^/\\s]+)(/[0-9]{4}(/[0-9]{2}(/[0-9]{2})?)?)?(/[^\\s]+)', 5, Tags))\n| extend Date = todatetime(strcat(replace_string(trim(@'/', Date), '/', '-'), '-01'))\n| extend Scope = replace_regex(Scope, @'/[^/]+$', '')\n| project Dataset, FocusVersion, ToolkitVersion, Date, Scope, LastUpdate = MaxCreatedOn, OriginalSize, RowCount\n| extend ScopeId = tostring(database('Ingestion').parse_resourceid(Scope).ResourceName)\n// TODO: Look up the name from cost data\n| extend ScopeResourceType = database('Ingestion').parse_resourceid(Scope).x_ResourceType\n// TODO: Clean up scope resource type display names -- | extend ScopeType = resource_type(ScopeResourceType).SingularDisplayName\n| summarize Rows = sum(RowCount) by Date, ScopeId", + "id": "e9a9a135-6a74-4463-b69f-eac6930ff1f2", + "usedVariables": [] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = CostsByDayAHB\n| where isnotempty(x_SkuLicenseStatus)\n//\n// Get the latest resource record first to guarrantee we have the latest status\n| summarize arg_max(ChargePeriodStart, *) by ResourceId\n| summarize\n x_ResourceCount = dcount(ResourceId),\n x_SkuLicenseUnusedQuantity = sum(x_SkuLicenseUnusedQuantity)\n by\n x_SkuLicenseStatus,\n x_SkuLicenseQuantity,\n x_SkuCoreCount\n| union (\n print json = dynamic([\n { \"x_SkuLicenseStatus\": \"Enabled\" },\n { \"x_SkuLicenseStatus\": \"Not Enabled\" }\n ])\n | mv-expand json\n | evaluate bag_unpack(json)\n);\n//\n// Coverage first\ncosts\n| summarize covered = sumif(x_ResourceCount, x_SkuLicenseStatus == 'Enabled'), all = sum(x_ResourceCount)\n| project Order = 1, Label = 'Coverage %', Value = percentstring(covered, all, 1)\n//\n// First column\n| union (costs | where x_SkuLicenseStatus == 'Enabled' | summarize Value = numberstring(sum(x_ResourceCount)) by Order = 3, Label = 'Covered resources')\n| union (costs | where x_SkuLicenseStatus == 'Not Enabled' | summarize Value = numberstring(sum(x_ResourceCount)) by Order = 5, Label = 'Eligible resources')\n//\n// Second column\n| union (costs | where x_SkuLicenseStatus == 'Enabled' | summarize Value = numberstring(sum(x_SkuLicenseUnusedQuantity)) by Order = 2, Label = 'Underutilized vCPU capacity')\n| union (costs | where x_SkuLicenseStatus == 'Enabled' | summarize Value = numberstring(sum(x_SkuLicenseQuantity)) by Order = 4, Label = 'Covered vCPU capacity')\n| union (costs | where x_SkuLicenseStatus == 'Not Enabled' | summarize Value = numberstring(sum(x_SkuLicenseQuantity)) by Order = 6, Label = 'Eligible vCPU capacity')\n| order by Order asc\n", + "id": "1a400b6c-9204-434d-88ff-2dc5260a95bf", + "usedVariables": ["CostsByDayAHB"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "// Underutilized capacity\n// Fully utilized capacity\n// Eligible resources\nCostsByDayAHB\n| where x_SkuLicenseStatus == 'Enabled'\n//\n// Get the latest resource record first to guarrantee we have the latest status\n| summarize\n arg_max(ChargePeriodStart, *),\n TotalConsumedQuantity = sum(ConsumedQuantity),\n TotalEffectiveCost = sum(EffectiveCost)\n by\n ResourceId\n| project \n [\"License type\"] = x_SkuLicenseType,\n ResourceName,\n ResourceType,\n SKU = x_SkuType,\n [\"SKU cores\"] = x_SkuCoreCount,\n [\"Required capacity\"] = x_SkuLicenseQuantity,\n [\"Unused capacity\"] = x_SkuLicenseUnusedQuantity,\n [\"Unused vCore hours\"] = x_SkuLicenseUnusedQuantity * ConsumedQuantity,\n EffectiveCost = TotalEffectiveCost,\n x_ResourceGroupName,\n SubAccountName\n| order by [\"Unused vCore hours\"] desc\n", + "id": "c2ad5370-f4df-4a13-ac31-2c095f88754d", + "usedVariables": ["CostsByDayAHB"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "CostsByDayAHB\n| where x_SkuLicenseStatus == 'Enabled'\n| where x_SkuLicenseUnusedQuantity == 0\n//\n// Get the latest resource record first to guarrantee we have the latest status\n| summarize\n arg_max(ChargePeriodStart, *),\n TotalConsumedQuantity = sum(ConsumedQuantity),\n TotalEffectiveCost = sum(EffectiveCost)\n by\n ResourceId\n| project \n [\"License type\"] = x_SkuLicenseType,\n ResourceName,\n ResourceType,\n SKU = x_SkuType,\n [\"SKU cores\"] = x_SkuCoreCount,\n [\"vCore hours\"] = x_SkuLicenseQuantity * ConsumedQuantity,\n EffectiveCost = TotalEffectiveCost,\n x_ResourceGroupName,\n SubAccountName\n| order by [\"vCore hours\"] desc\n", + "id": "4614acfb-2288-4a71-97f7-32845a9ddcb2", + "usedVariables": ["CostsByDayAHB"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "CostsByDayAHB\n| where x_SkuLicenseStatus == 'Not Enabled'\n//\n// Get the latest resource record first to guarrantee we have the latest status\n| summarize\n arg_max(ChargePeriodStart, *),\n TotalConsumedQuantity = sum(ConsumedQuantity),\n TotalEffectiveCost = sum(EffectiveCost)\n by\n ResourceId\n| project \n [\"License type\"] = x_SkuLicenseType,\n ResourceName,\n ResourceType,\n SKU = x_SkuType,\n [\"SKU cores\"] = x_SkuCoreCount,\n [\"Required capacity\"] = x_SkuLicenseQuantity,\n [\"Eligible vCore hours\"] = x_SkuLicenseQuantity * ConsumedQuantity,\n EffectiveCost = TotalEffectiveCost,\n x_ResourceGroupName,\n SubAccountName\n| order by [\"Eligible vCore hours\"] desc\n", + "id": "99d44f1f-c53a-40ee-b749-8e5557ec58c7", + "usedVariables": ["CostsByDayAHB"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let costs = Costs_v1_0 | where ChargePeriodStart >= startofmonth(now(), -3) and ChargePeriodStart < startofday(ago(-1d));\nlet startOfPeriod = toscalar(costs | summarize min(startofday(ChargePeriodStart)));\nlet endOfPeriod = toscalar(costs | summarize max(startofday(ChargePeriodStart)));\nlet forecastHorizon = numberOfDays * 1d;\ncosts\n| make-series\n EffectiveCost = sum(EffectiveCost)\n on ChargePeriodStart\n from startOfPeriod to endOfPeriod + forecastHorizon step 1d\n // by SubAccountId\n| extend Forecast = series_decompose_forecast(EffectiveCost, numberOfDays)\n", + "id": "5fd3ea2a-8882-4438-9103-fa3945240604", + "usedVariables": ["numberOfDays"] + }, + { + "id": "43612ae4-c475-4f22-bb50-ce9d995abb8f", + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\n| where startofmonth(BillingPeriodStart) == startofmonth(now())", + "usedVariables": [] + }, + { + "id": "cb1f5404-c0b1-42fd-99fb-3cff7b08daaa", + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\n| where startofmonth(BillingPeriodStart) == startofmonth(startofmonth(now()) - 1d)", + "usedVariables": [] + }, + { + "id": "4ce0f587-2d45-436c-8f79-102c6b382439", + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\r\n| where ChargePeriodStart >= monthsago(numberOfMonths) and ChargePeriodStart < startofday(ago(1d))\r\n| extend ChargePeriodStart = startofmonth(ChargePeriodStart)\r\n| extend BillingPeriodStart = startofmonth(BillingPeriodStart)", + "usedVariables": ["numberOfMonths"] + }, + { + "id": "6b598467-8c31-4693-b1eb-7ed683fcfc3a", + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "Costs_v1_0\r\n| where ChargePeriodStart >= startofday(ago(numberOfDays * 1d) - 1d) and ChargePeriodStart < startofday(ago(1d))\r\n| extend ChargePeriodStart = startofday(ChargePeriodStart)", + "usedVariables": ["numberOfDays"] + }, + { + "id": "4a1973bf-08e9-4e82-b8e6-6edff81cf0a5", + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "CostsByDay\n| extend tmp_SQLAHB = tolower(x_SkuDetails.AHB)\n| extend x_SkuType = tostring(x_SkuDetails.ServiceType)\n| extend x_SkuCoreCount = toint(coalesce(x_SkuDetails.VCPUs, x_SkuDetails.vCores, ''))\n| extend x_ConsumedCoreHours = iff(isnotempty(x_SkuCoreCount), x_SkuCoreCount * ConsumedQuantity, todecimal(''))\n| extend x_SkuLicenseStatus = case(\n ChargeCategory != 'Usage', '',\n (x_SkuMeterCategory in ('Virtual Machines', 'Virtual Machine Licenses') and x_SkuMeterSubcategory contains 'Windows') or tmp_SQLAHB == 'false', 'Not Enabled',\n x_SkuDetails.ImageType contains 'Windows Server BYOL' or tmp_SQLAHB == 'true' or x_SkuMeterSubcategory == 'SQL Server Azure Hybrid Benefit', 'Enabled',\n ''\n)\n| extend x_SkuLicenseType = case(\n ChargeCategory != 'Usage', '',\n x_SkuMeterCategory in ('Virtual Machines', 'Virtual Machine Licenses') and (x_SkuMeterSubcategory contains 'Windows' or x_SkuDetails.ImageType contains 'Windows Server BYOL'), 'Windows Server',\n isnotempty(tmp_SQLAHB) or x_SkuMeterSubcategory == 'SQL Server Azure Hybrid Benefit', 'SQL Server',\n ''\n)\n| extend x_SkuLicenseQuantity = case(\n isempty(x_SkuCoreCount), toint(''),\n x_SkuCoreCount <= 8, 8,\n x_SkuCoreCount <= 16, 16,\n x_SkuCoreCount == 20, 24,\n x_SkuCoreCount > 20, x_SkuCoreCount,\n toint('')\n)\n| extend x_SkuLicenseUnusedQuantity = x_SkuLicenseQuantity - x_SkuCoreCount", + "usedVariables": ["CostsByDay"] + }, + { + "dataSource": { "kind": "inline", "dataSourceId": "23540be2-ffc9-4b61-8c4c-05e493e682a6" }, + "text": "let months = toscalar(database('Ingestion').HubSettings | project toint(retention.final.months));\nlet monthname = dynamic(['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']);\nrange Value from toint(1) to iff(isempty(months), 24, months) step 1\n| order by Value desc\n| extend MonthsAgo = monthsago(Value)\n| extend Label = strcat(Value, ' mo (', monthname[monthofyear(MonthsAgo)], format_datetime(MonthsAgo, ' yyyy'), ')')\n| project-away MonthsAgo\n", + "id": "c9039243-968d-4e75-9899-8d4ab51a9896", + "usedVariables": [] + } + ] +}