diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/README.md b/quickstarts/microsoft.costmanagement/finops-workbooks/README.md new file mode 100644 index 000000000000..1d6ca8044c08 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/README.md @@ -0,0 +1,74 @@ +--- +description: This template deploys Azure Monitor workbooks from the FinOps toolkit that can help engineers perform key tasks defined by the FinOps Framework. +page_type: sample +products: + - azure +urlFragment: finops-workbooks +languages: + - bicep + - json +--- + +# FinOps workbooks template + +![Azure Public Test Date](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.costmanagement/finops-workbooks/PublicLastTestDate.svg) +![Azure Public Test Result](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.costmanagement/finops-workbooks/PublicDeployment.svg) + +![Azure US Gov Last Test Date](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.costmanagement/finops-workbooks/FairfaxLastTestDate.svg) +![Azure US Gov Last Test Result](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.costmanagement/finops-workbooks/FairfaxDeployment.svg) + +![Best Practice Check](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.costmanagement/finops-workbooks/BestPracticeResult.svg) +![Cred Scan Check](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.costmanagement/finops-workbooks/CredScanResult.svg) +![Bicep Version](https://azurequickstartsservice.blob.core.windows.net/badges/quickstarts/microsoft.costmanagement/finops-workbooks/BicepVersion.svg) + +[![Deploy To Azure](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazure.svg?sanitize=true)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2Fquickstarts%2Fmicrosoft.costmanagement%2Ffinops-workbooks%2Fazuredeploy.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2Fquickstarts%2Fmicrosoft.costmanagement%2Ffinops-workbooks%2FcreateUiDefinition.json) +[![Deploy To Azure US Gov](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazuregov.svg?sanitize=true)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2Fquickstarts%2Fmicrosoft.costmanagement%2Ffinops-workbooks%2Fazuredeploy.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2Fquickstarts%2Fmicrosoft.costmanagement%2Ffinops-workbooks%2FcreateUiDefinition.json) +[![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.svg?sanitize=true)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Fmaster%2Fquickstarts%2Fmicrosoft.costmanagement%2Ffinops-workbooks%2Fazuredeploy.json) + +This template deploys a set of workbooks that help you implement FinOps capabilities. FinOps workbooks are tools designed for engineers with direct access to resources to manage and optimize cloud resources. + +FinOps workbooks include: + +- **Optimization** - Supports workload and rate optimization, sustainability, and security, and more as defined by the Well Architected Framework. +- **Governance** - Supports policy compliance and cloud governance scenarios as defined by the Well Architected Framework. + +To learn more about FinOps workbooks, the roadmap, or how to contribute , see [FinOps workbooks documentation](https://aka.ms/finops/workbooks). + +
+ +## 📋 Prerequisites + +Azure Monitor workbooks provide direct access to Azure resource details. To deploy workbooks, you must have the **Workbook Contributor** role. To use workbooks, you need read access to the resources being monitored. The exact permissions vary by resource and service. + +If you run into any issues, see [Troubleshooting FinOps toolkit solutions](https://aka.ms/ftk/tsg). + +
+ +## 📗 How to use this template + +Once your workbooks are deployed, you can use them by navigating to one of the following destinations: + +1. From Azure Monitor: + 1. Select [**Workbooks**](https://portal.azure.com/#view/Microsoft_Azure_Monitoring/AzureMonitoringBrowseBlade/~/workbooks) in the menu. + 2. Verify your subscription is selected in the **Subscription** filter. + 3. Select the applicable workbook. +2. From the resource group: + 1. Select the desired workbook resource. + 2. Select **Workbook** in the menu. +3. From [Azure workbooks](https://portal.azure.com/#browse/microsoft.insights%2Fworkbooks): + 1. Select the desired workbook. + 2. Select **Workbook** in the menu. + +> ℹī¸ _**Pro tip:** If you navigate to the workbook resource (2 or 3 above), consider adding the workbook as a favorite using the star icon to the right of the resource name to make it easier to find in the future. Favorite resources can be opened directly from the Resources > Favorite section of the Azure portal default home page._ + +
+ +## 🧰 About the FinOps toolkit + +FinOps workbooks 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. + +To contribute to the FinOps toolkit, [join us on GitHub](https://aka.ms/ftk). + +
+ +`Tags: finops, cost, usage, carbon, optimization, policy, governance, Microsoft.Insights/workbooks` diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/azuredeploy.parameters.json b/quickstarts/microsoft.costmanagement/finops-workbooks/azuredeploy.parameters.json new file mode 100644 index 000000000000..bf74208938e3 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/azuredeploy.parameters.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0" +} diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/bicepconfig.json b/quickstarts/microsoft.costmanagement/finops-workbooks/bicepconfig.json new file mode 100644 index 000000000000..30673ee6104a --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/bicepconfig.json @@ -0,0 +1,13 @@ +{ + // See https://aka.ms/bicep/config for more information on Bicep configuration options + // Press CTRL+SPACE/CMD+SPACE at any location to see Intellisense suggestions + "analyzers": { + "core": { + "rules": { + "no-deployments-resources": { + "level": "off" + } + } + } + } +} diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/createUiDefinition.json b/quickstarts/microsoft.costmanagement/finops-workbooks/createUiDefinition.json new file mode 100644 index 000000000000..0c6148af6958 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/createUiDefinition.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "config": { + "basics": { + "description": "FinOps workbooks facilitate FinOps tasks that help you build, manage, and optimize cloud resources. [Learn more](https://aka.ms/finops/workbooks)", + "location": { + "label": "Location", + "resourceTypes": ["Microsoft.Insights/workbooks"] + } + } + }, + "resourceTypes": ["Microsoft.Insights/workbooks"], + "basics": [ + { + "name": "displayNamePrefix", + "type": "Microsoft.Common.TextBox", + "label": "Name prefix", + "defaultValue": "FinOps", + "toolTip": "Prefix to use for each of the workbook names (e.g., 'FinOps-Optimization', 'FinOps-Governance').", + "constraints": { + "required": true, + "regex": "^.{1,220}$", + "validationMessage": "Name prefix cannot be longer than 220 characters." + }, + "visible": true + } + ], + "steps": [ + { + "name": "workbooks", + "label": "Workbooks", + "elements": [ + { + "name": "workbookSelectionIntro", + "options": { "text": "Select the FinOps workbooks you would like to include in this deployment. You can select more later." }, + "type": "Microsoft.Common.TextBlock" + }, + { + "name": "includeOptimization", + "label": "Optimization", + "toolTip": "Select to include the optimization workbook for workload and rate optimization as well as sustainability, security, and more.", + "type": "Microsoft.Common.CheckBox", + "defaultValue": true + }, + { + "name": "includeGovernance", + "label": "Governance", + "toolTip": "Select to include the governance workbook for queries to support the Well-Architected Framework governance pillar.", + "type": "Microsoft.Common.CheckBox", + "defaultValue": true + } + ] + } + ], + "outputs": { + "displayNamePrefix": "[basics('displayNamePrefix')]", + "includeOptimization": "[steps('workbooks').includeOptimization]", + "includeGovernance": "[steps('workbooks').includeGovernance]", + "location": "[location()]" + } + } +} diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/ftkver.txt b/quickstarts/microsoft.costmanagement/finops-workbooks/ftkver.txt new file mode 100644 index 000000000000..0e2c93950bb6 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/ftkver.txt @@ -0,0 +1 @@ +0.7 \ No newline at end of file diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/main.bicep b/quickstarts/microsoft.costmanagement/finops-workbooks/main.bicep new file mode 100644 index 000000000000..ebd9bb532032 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/main.bicep @@ -0,0 +1,116 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +targetScope = 'resourceGroup' + +//============================================================================== +// Parameters +//============================================================================== + +@sys.description('Optional. Display name prefix to use for all workbooks. Default: "FinOps".') +param displayNamePrefix string = 'FinOps' + +@sys.description('Optional. Indicates whether to deploy the optimization workbook. Default: true.') +param includeOptimization bool = true + +@sys.description('Optional. Indicates whether to deploy the governance workbook. Default: true.') +param includeGovernance bool = true + +@sys.description('Optional. Location of the resources. Default: Same as deployment. See https://aka.ms/azureregions.') +param location string = resourceGroup().location + +@sys.description('Optional. Tags for all resources.') +param tags object = {} + +@description('Optional. Tags to apply to resources based on their resource type. Resource type specific tags will be merged with tags for all resources.') +param tagsByResource object = {} + +@sys.description('Optional. Enable telemetry to track anonymous module usage trends, monitor for bugs, and improve future releases.') +param enableDefaultTelemetry bool = true + +//------------------------------------------------------------------------------ +// Variables +//------------------------------------------------------------------------------ + +// The last segment of the telemetryId is used to identify this module +var telemetryId = '00f120b5-2007-6120-0000-a7730126b006' +var finOpsToolkitVersion = loadTextContent('ftkver.txt') + +// Add tags to all resources +var resourceTags = union( + tags, + tagsByResource[?'Microsoft.Insights/workbooks'] ?? {}, + { + 'ftk-version': finOpsToolkitVersion + 'ftk-tool': 'FinOps workbooks' + } +) + +//============================================================================== +// Resources +//============================================================================== + +//------------------------------------------------------------------------------ +// Telemetry +// Used to anonymously count the number of times the template has been deployed +// and to track and fix deployment bugs to ensure the highest quality. +// No information about you or your cost data is collected. +//------------------------------------------------------------------------------ + +resource defaultTelemetry 'Microsoft.Resources/deployments@2022-09-01' = if (enableDefaultTelemetry) { + name: 'pid-${telemetryId}-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + metadata: { + _generator: { + name: 'FinOps toolkit' + version: finOpsToolkitVersion + } + } + resources: [] + } + } +} + +//------------------------------------------------------------------------------ +// Workbooks +//------------------------------------------------------------------------------ + +module optimization 'workbooks/optimization/main.bicep' = if (includeOptimization) { + name: '${displayNamePrefix}-Optimization' + params: { + displayName: '${displayNamePrefix} - Optimization' + location: location + tags: resourceTags + enableDefaultTelemetry: false + } +} + +module governance 'workbooks/governance/main.bicep' = if (includeGovernance) { + name: '${displayNamePrefix}-Governance' + params: { + displayName: '${displayNamePrefix} - Governance' + location: location + tags: resourceTags + enableDefaultTelemetry: false + } +} + +//============================================================================== +// Outputs +//============================================================================== + +@sys.description('Optimization workbook resource ID.') +output optimizationId string = optimization.outputs.workbookId + +@sys.description('Optimization workbook Azure portal link.') +output optimizationUrl string = optimization.outputs.workbookUrl + +@sys.description('Governance workbook resource ID.') +output governanceId string = governance.outputs.workbookId + +@sys.description('Governance workbook Azure portal link.') +output governanceUrl string = governance.outputs.workbookUrl diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/metadata.json b/quickstarts/microsoft.costmanagement/finops-workbooks/metadata.json new file mode 100644 index 000000000000..461cc357b176 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/metadata.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://aka.ms/azure-quickstart-templates-metadata-schema#", + "type": "QuickStart", + "itemDisplayName": "FinOps workbooks", + "summary": "Deploy a set of workbooks that help you implement FinOps capabilities", + "description": "This template deploys Azure Monitor workbooks from the FinOps toolkit that can help engineers perform key tasks defined by the FinOps Framework.", + "githubUsername": "flanakin", + "dateUpdated": "2024-08-25" +} diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/governance/ftkver.txt b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/governance/ftkver.txt new file mode 100644 index 000000000000..0e2c93950bb6 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/governance/ftkver.txt @@ -0,0 +1 @@ +0.7 \ No newline at end of file diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/governance/main.bicep b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/governance/main.bicep new file mode 100644 index 000000000000..4295db6cde6b --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/governance/main.bicep @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +targetScope = 'resourceGroup' + +//============================================================================== +// Parameters +//============================================================================== + +@sys.description('Optional. Display name for the workbook used in the Gallery. Must be unique in the resource group.') +param displayName string = 'Governance' + +@sys.description('Optional. Location of the resources. Default: Same as deployment. See https://aka.ms/azureregions.') +param location string = resourceGroup().location + +@sys.description('Optional. Workbook description.') +param description string = 'Reports to help you optimize your cost.' + +@sys.description('Optional. Tags for all resources.') +param tags object = {} + +@sys.description('Optional. Enable telemetry to track anonymous module usage trends, monitor for bugs, and improve future releases.') +param enableDefaultTelemetry bool = true + +//------------------------------------------------------------------------------ +// Variables +//------------------------------------------------------------------------------ + +var version = '' +var workbookJson = string(loadJsonContent('workbook.json')) + +// The last segment of the telemetryId is used to identify this module +var workbookId = '907' +var telemetryId = '00f120b5-2007-6120-0000-${workbookId}30126b006' +var finOpsToolkitVersion = loadTextContent('ftkver.txt') + +// Add tags to all resources +var resourceTags = contains(tags, 'ftk-tool') ? tags : union(tags, { + 'ftk-version': finOpsToolkitVersion + 'ftk-tool': '${displayName} workbook' + }) + +//============================================================================== +// Resources +//============================================================================== + +//------------------------------------------------------------------------------ +// Telemetry +// Used to anonymously count the number of times the template has been deployed +// and to track and fix deployment bugs to ensure the highest quality. +// No information about you or your cost data is collected. +//------------------------------------------------------------------------------ + +resource defaultTelemetry 'Microsoft.Resources/deployments@2022-09-01' = if (enableDefaultTelemetry) { + name: 'pid-${telemetryId}-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + metadata: { + _generator: { + name: 'FinOps toolkit' + version: finOpsToolkitVersion + } + } + resources: [] + } + } +} + +//------------------------------------------------------------------------------ +// Workbook +//------------------------------------------------------------------------------ + +resource workbook 'Microsoft.Insights/workbooks@2022-04-01' = { + name: guid(resourceGroup().id, 'Microsoft.Insights/workbooks', displayName) + location: location + tags: resourceTags + kind: 'shared' + properties: { + category: 'workbook' + description: description + displayName: displayName + serializedData: workbookJson + sourceId: 'Azure Monitor' + version: version + } +} + +//============================================================================== +// Outputs +//============================================================================== + +@sys.description('The resource ID of the workbook.') +output workbookId string = workbook.id + +@sys.description('Link to the workbook in the Azure portal.') +output workbookUrl string = '${environment().portal}/#view/AppInsightsExtension/UsageNotebookBlade/ComponentId/Azure%20Monitor/ConfigurationId/${uriComponent(workbook.id)}/Type/${workbook.properties.category}/WorkbookTemplateName/${uriComponent(workbook.properties.displayName)}' diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/governance/workbook.json b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/governance/workbook.json new file mode 100644 index 000000000000..1405b0364651 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/governance/workbook.json @@ -0,0 +1,8128 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "19b06e9e-eec2-4a7e-935d-92d77b2f87a3", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Overview", + "subTarget": "RC_Overview", + "preText": "", + "style": "link" + }, + { + "id": "528e35b9-aca4-423f-9267-50f62011a3cb", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Virtual machine", + "subTarget": "RC_VM", + "style": "link" + }, + { + "id": "7faacfc6-663e-4ff5-bb64-f86d995f9563", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Storage + backup", + "subTarget": "RC_Storage", + "style": "link" + }, + { + "id": "c17ce2c0-83e6-4e5c-9c3e-f34cbf887e73", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Network", + "subTarget": "RC_Network", + "style": "link" + }, + { + "id": "2f4e49d7-3198-4173-af1c-4cf4c5178000", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "PaaS", + "subTarget": "RC_PaaS", + "style": "link" + }, + { + "id": "f8f7e1fc-8f5d-442a-9788-3eabbf8ab275", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Security", + "subTarget": "RC_Security", + "style": "link" + }, + { + "id": "80ad2db8-a21e-43e9-bd28-75d8d606eaf5", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Monitoring", + "subTarget": "RC_Monitoring", + "style": "link" + }, + { + "id": "6fc0fef0-a016-4923-9239-b641eb5bdc4f", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Services retirement", + "subTarget": "RC_ServicesRetirement", + "style": "link" + }, + { + "id": "e40dbf66-2abe-4bcf-acd7-1ee6d8fc950b", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Resource age", + "subTarget": "RC_Age", + "style": "link" + }, + { + "id": "e112c6e1-db5e-4b0e-99e9-2edac0eba177", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Tag explorer", + "subTarget": "RC_Tag", + "style": "link" + }, + { + "id": "840cd5ea-6b74-484b-846f-01d424b295cd", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Cost management", + "subTarget": "RC_Cost", + "style": "link" + }, + { + "id": "5436a8c9-73c4-4121-a814-dd6fbb0c0d0c", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Usage + limits", + "subTarget": "RC_Quota", + "style": "link" + }, + { + "id": "fa81b57a-8f3c-4502-beb0-128a7fc35f7c", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Compliance", + "subTarget": "RC_Compliance", + "style": "link" + }, + { + "id": "e3acf38e-2dc4-423e-b91d-a173280b5808", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Governance", + "subTarget": "RC_Governance", + "style": "link" + } + ] + }, + "name": "RC_Menu" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "value::tenant" + ], + "parameters": [ + { + "id": "30297a43-7d69-4daf-93c9-8170d5a995b0", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "label": "Subscriptions", + "type": 6, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all" + } + ], + "style": "above", + "queryType": 1, + "resourceType": "microsoft.resources/tenants" + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "RC_Age" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "RC_Cost" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "RC_Quota" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "RC_Compliance" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "RC_ServicesRetirement" + } + ], + "name": "parameters - Subscriptions" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Welcome the Azure governance workbook" + }, + "name": "Welcome" + }, + { + "type": 1, + "content": { + "json": "### Reference: [Governance in the Microsoft Cloud Adoption Framework for Azure](https://learn.microsoft.com/azure/cloud-adoption-framework/govern/)", + "style": "upsell" + }, + "name": "Reference" + }, + { + "type": 1, + "content": { + "json": "The objective of this workbook is to provide a comprehensive overview of the governance posture of your Azure environment. It offers the standard metrics aligned with the Cloud Adoption Framework and has the capability to identify and apply recommendations to identify non compliance. This workbook is part of the [FinOps toolkit](https://aka.ms/finops/toolkit).\r\n\r\n## Overview of the Cloud Adoption Framework\r\n\r\n* The CAF Govern methodology provides a structured approach for establishing and optimizing cloud governance in Azure. The guidance is relevant for organizations across any industry. It covers essential categories of cloud governance, such as regulatory compliance, security, operations, cost, data, resource management, and artificial intelligence (AI).\r\n\r\n* Cloud governance is how you control cloud use across your organization. Cloud governance sets up guardrails that regulate cloud interactions. These guardrails are a framework of policies, procedures, and tools you use to establish control. Policies define acceptable and unacceptable cloud activity, and the procedures and tools you use ensure all cloud usage aligns with those policies. Successful cloud governance prevents all unauthorized or unmanaged cloud usage.\r\n\r\n* To assess your transformation journey, try the [governance benchmark tool](https://learn.microsoft.com/assessments/b1891add-7646-4d60-a875-32a4ab26327e/).\r\n\r\n\r\n\r\n\r\n" + }, + "name": "text - Overview" + }, + { + "type": 1, + "content": { + "json": "## Prerequisites\r\n\r\nThis workbook will present various cost-related details in the form of governance, networking, storage, VMs, web apps, SQL, and cost information to educate the business about cost related to various resources.\r\n\r\nThis workbook requires the following least-privileged (minimum) roles:\r\n\r\n * **Reader** : allows you to import the workbook without saving it and view all of the workbook tabs except the *Cost management* tab.\r\n * **Cost Management Reader**: allows you to view the costs in the *Cost management* tab \r\n * **Workbook Contributor** : allows you to import and save the workbook\r\n\r\n\r\n" + }, + "name": "text - 7" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\n| summarize count()", + "size": 3, + "title": "Count of all resources", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": false, + "size": "auto" + } + }, + "name": "Count of all resources" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| summarize Count=count(id) by subscriptionId\r\n| order by Count desc", + "size": 3, + "title": "Resource count per subscription (Top 10)", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "type", + "formatter": 1 + } + ], + "rowLimit": 10, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "subscriptionId", + "label": "Subscription name" + } + ] + }, + "sortBy": [], + "tileSettings": { + "titleContent": { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + "leftContent": { + "columnMatch": "Count", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal", + "maximumFractionDigits": 2, + "maximumSignificantDigits": 3 + } + } + }, + "showBorder": false, + "rowLimit": 10, + "sortCriteriaField": "count_type", + "sortOrderField": 2 + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "subscriptionId", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "Count", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "chartSettings": { + "xAxis": "subscriptionId", + "yAxis": [ + "Count" + ], + "showLegend": true, + "seriesLabelSettings": [ + { + "seriesName": "subscriptionId", + "color": "greenDark" + } + ] + }, + "mapSettings": { + "locInfo": "LatLong", + "sizeSettings": "Count", + "sizeAggregation": "Sum", + "legendMetric": "Count", + "legendAggregation": "Sum", + "itemColorSettings": { + "type": "heatmap", + "colorAggregation": "Sum", + "nodeColorField": "Count", + "heatmapPalette": "greenRed" + } + } + }, + "name": "Resource count per subscription (Top 10)" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources \r\n| extend type = case(\r\ntype contains 'microsoft.netapp/netappaccounts', 'NetApp Accounts',\r\ntype contains \"microsoft.compute\", \"Azure Compute\",\r\ntype contains \"microsoft.logic\", \"LogicApps\",\r\ntype contains 'microsoft.keyvault/vaults', \"Key Vaults\",\r\ntype contains 'microsoft.storage/storageaccounts', \"Storage Accounts\",\r\ntype contains 'microsoft.compute/availabilitysets', 'Availability Sets',\r\ntype contains 'microsoft.operationalinsights/workspaces', 'Azure Monitor Resources',\r\ntype contains 'microsoft.operationsmanagement', 'Operations Management Resources',\r\ntype contains 'microsoft.insights', 'Azure Monitor Resources',\r\ntype contains 'microsoft.desktopvirtualization/applicationgroups', 'WVD Application Groups',\r\ntype contains 'microsoft.desktopvirtualization/workspaces', 'WVD Workspaces',\r\ntype contains 'microsoft.desktopvirtualization/hostpools', 'WVD Hostpools',\r\ntype contains 'microsoft.recoveryservices/vaults', 'Backup Vaults',\r\ntype contains 'microsoft.web', 'App Services',\r\ntype contains 'microsoft.managedidentity/userassignedidentities','Managed Identities',\r\ntype contains 'microsoft.storagesync/storagesyncservices', 'Azure File Sync',\r\ntype contains 'microsoft.hybridcompute/machines', 'ARC Machines',\r\ntype contains 'Microsoft.EventHub', 'Event Hub',\r\ntype contains 'Microsoft.EventGrid', 'Event Grid',\r\ntype contains 'Microsoft.Sql', 'SQL Resources',\r\ntype contains 'Microsoft.HDInsight/clusters', 'HDInsight Clusters',\r\ntype contains 'microsoft.devtestlab', 'DevTest Labs Resources',\r\ntype contains 'microsoft.containerinstance', 'Container Instances Resources',\r\ntype contains 'microsoft.portal/dashboards', 'Azure Dashboards',\r\ntype contains 'microsoft.containerregistry/registries', 'Container Registry',\r\ntype contains 'microsoft.automation', 'Automation Resources',\r\ntype contains 'sendgrid.email/accounts', 'SendGrid Accounts',\r\ntype contains 'microsoft.datafactory/factories', 'Data Factory',\r\ntype contains 'microsoft.databricks/workspaces', 'Databricks Workspaces',\r\ntype contains 'microsoft.machinelearningservices/workspaces', 'Machine Learnings Workspaces',\r\ntype contains 'microsoft.alertsmanagement/smartdetectoralertrules', 'Azure Monitor Resources',\r\ntype contains 'microsoft.apimanagement/service', 'API Management Services',\r\ntype contains 'microsoft.dbforpostgresql', 'PostgreSQL Resources',\r\ntype contains 'microsoft.scheduler/jobcollections', 'Scheduler Job Collections',\r\ntype contains 'microsoft.visualstudio/account', 'Azure DevOps Organization',\r\ntype contains 'microsoft.network/', 'Network Resources',\r\ntype contains 'microsoft.migrate/' or type contains 'microsoft.offazure', 'Azure Migrate Resources',\r\ntype contains 'microsoft.servicebus/namespaces', 'Service Bus Namespaces',\r\ntype contains 'microsoft.classic', 'ASM Obsolete Resources',\r\ntype contains 'microsoft.resources/templatespecs', 'Template Spec Resources',\r\ntype contains 'microsoft.virtualmachineimages', 'VM Image Templates',\r\ntype contains 'microsoft.documentdb', 'CosmosDB DB Resources',\r\ntype contains 'microsoft.alertsmanagement/actionrules', 'Azure Monitor Resources',\r\ntype contains 'microsoft.kubernetes/connectedclusters', 'ARC Kubernetes Clusters',\r\ntype contains 'microsoft.purview', 'Purview Resources',\r\ntype contains 'microsoft.security', 'Security Resources',\r\ntype contains 'microsoft.cdn', 'CDN Resources',\r\ntype contains 'microsoft.devices','IoT Resources',\r\ntype contains 'microsoft.datamigration', 'Data Migraiton Services',\r\ntype contains 'microsoft.cognitiveservices', 'Congitive Services',\r\ntype contains 'microsoft.customproviders', 'Custom Providers',\r\ntype contains 'microsoft.appconfiguration', 'App Services',\r\ntype contains 'microsoft.search', 'Search Services',\r\ntype contains 'microsoft.maps', 'Maps',\r\ntype contains 'microsoft.containerservice/managedclusters', 'AKS',\r\ntype contains 'microsoft.signalrservice', 'SignalR',\r\ntype contains 'microsoft.resourcegraph/queries', 'Resource Graph Queries',\r\ntype contains 'microsoft.batch', 'MS Batch',\r\ntype contains 'microsoft.analysisservices', 'Analysis Services',\r\ntype contains 'microsoft.synapse/workspaces', 'Synapse Workspaces',\r\ntype contains 'microsoft.synapse/workspaces/sqlpools', 'Synapse SQL Pools',\r\ntype contains 'microsoft.kusto/clusters', 'ADX Clusters',\r\ntype contains 'microsoft.resources/deploymentscripts', 'Deployment Scripts',\r\ntype contains 'microsoft.aad/domainservices', 'AD Domain Services',\r\ntype contains 'microsoft.labservices/labaccounts', 'Lab Accounts',\r\ntype contains 'microsoft.automanage/accounts', 'Automanage Accounts',\r\ntype contains 'microsoft.relay/namespaces', 'Azure Relay',\r\ntype contains 'microsoft.notificationhubs/namespaces', 'Notification Hubs',\r\ntype contains 'microsoft.digitaltwins/digitaltwinsinstances', 'Digital Twins',\r\nstrcat(\"Not Translated: \", type))\r\n| summarize count() by type\r\n| order by count_ desc", + "size": 3, + "title": "Resource number by type (Top 10)", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "type", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "rowLimit": 10 + } + }, + "name": "Resource number by type" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| summarize count() by location", + "size": 3, + "title": "Resource number by location", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "map", + "mapSettings": { + "locInfo": "AzureLoc", + "sizeSettings": "count_", + "sizeAggregation": "Sum", + "legendMetric": "count_", + "legendAggregation": "Sum", + "itemColorSettings": { + "type": "heatmap", + "colorAggregation": "Sum", + "nodeColorField": "count_", + "heatmapPalette": "greenRed" + }, + "labelSettings": "location", + "locInfoColumn": "location" + } + }, + "name": "Resource number by location" + } + ] + }, + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "group - Overview metrics" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Overview" + }, + "name": "RC_Overview" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Things to know before creating a virtual machine\r\nThere's always a multitude of design considerations when you build out an application infrastructure in Azure. These aspects of a virtual machine are important to think about to manage virtual machine properly:\r\n- The names of your application resources\r\n- The location where the resources are stored\r\n- The size of the virtual machine\r\n- The maximum number of virtual machines that can be created\r\n- The operating system that the virtual machine runs\r\n- The configuration of the virtual machine after it starts\r\n- The related resources that the virtual machine needs\r\n" + }, + "name": "text - 13" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources | where type =~ 'Microsoft.Compute/virtualMachines'\n| summarize count() by tostring(properties.storageProfile.osDisk.osType)", + "size": 3, + "title": "Virtual machine count per OS type", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "properties_storageProfile_osDisk_osType", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "name": "Virtual machine count per OS type" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n| where type =~ 'Microsoft.Compute/virtualMachines'\r\n| project SKU = tostring(properties.hardwareProfile.vmSize)\r\n| summarize count() by SKU\r\n| order by count_ desc", + "size": 1, + "title": "VM by VM type/size", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "barchart", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "SKU", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "rowLimit": 10 + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "SKU", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "count_", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "name": "VM by VM type/size" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type=~ 'microsoft.compute/virtualmachinescalesets'\r\n| project subscriptionId, name, location, resourceGroup, Capacity = toint(sku.capacity), Tier = sku.name\r\n| order by Capacity desc", + "size": 0, + "title": "Virtual machine scale set capacity and size", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "name": "query - virtual machine scale set capacity and size" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources | where type == \"microsoft.compute/virtualmachines\"\r\n| extend osDiskId= tostring(properties.storageProfile.osDisk.managedDisk.id)\r\n | join kind=leftouter(resources\r\n | where type =~ 'microsoft.compute/disks'\r\n | where properties !has 'Unattached'\r\n | where properties has 'osType'\r\n | project OS = tostring(properties.osType), osSku = tostring(sku.name), osDiskSizeGB = toint(properties.diskSizeGB), osDiskId=tostring(id)) on osDiskId\r\n | join kind=leftouter(Resources\r\n | where type =~ 'microsoft.compute/disks'\r\n | where properties !has \"osType\"\r\n | where properties !has 'Unattached'\r\n | project sku = tostring(sku.name), diskSizeGB = toint(properties.diskSizeGB), id = managedBy\r\n | summarize sum(diskSizeGB), count(sku) by id, sku) on id\r\n| project vmId=id, subscriptionId, resourceGroup, OS, location, osDiskId, osSku, osDiskSizeGB, DataDisksGB=sum_diskSizeGB, diskSkuCount=count_sku\r\n| sort by diskSkuCount desc", + "size": 0, + "title": "Compute disks", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "location", + "formatter": 17 + } + ], + "filter": true, + "labelSettings": [ + { + "columnId": "vmId", + "label": "Resource Name" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "location", + "label": "Region" + }, + { + "columnId": "osDiskId", + "label": "OS Disk" + }, + { + "columnId": "osSku", + "label": "OS Disk SKU" + }, + { + "columnId": "osDiskSizeGB", + "label": "OS Disk Size" + } + ] + } + }, + "name": "Compute disks" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n| where type =~ 'microsoft.compute/virtualmachines'\r\n| extend nics=array_length(properties.networkProfile.networkInterfaces)\r\n| mv-expand nic=properties.networkProfile.networkInterfaces\r\n| where nics == 1 or nic.properties.primary =~ 'true' or isempty(nic)\r\n| project vmId = id, vmName = name, vmSize=tostring(properties.hardwareProfile.vmSize), nicId = tostring(nic.id)\r\n\t| join kind=leftouter (\r\n \t\tResources\r\n \t\t| where type =~ 'microsoft.network/networkinterfaces'\r\n \t\t| extend ipConfigsCount=array_length(properties.ipConfigurations)\r\n \t\t| mv-expand ipconfig=properties.ipConfigurations\r\n \t\t| where ipConfigsCount == 1 or ipconfig.properties.primary =~ 'true'\r\n \t\t| project nicId = id, privateIP= tostring(ipconfig.properties.privateIPAddress), publicIpId = tostring(ipconfig.properties.publicIPAddress.id), subscriptionId) on nicId\r\n| project-away nicId1\r\n| summarize by vmId, subscriptionId, vmSize, nicId, privateIP, publicIpId\r\n\t| join kind=leftouter (\r\n \t\tResources\r\n \t\t| where type =~ 'microsoft.network/publicipaddresses'\r\n \t\t| project publicIpId = id, publicIpAddress = tostring(properties.ipAddress)) on publicIpId\r\n| project-away publicIpId1\r\n| sort by publicIpAddress desc", + "size": 0, + "title": "Compute networking", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "filter": true, + "labelSettings": [ + { + "columnId": "vmId", + "label": "Resource name" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + }, + { + "columnId": "vmSize", + "label": "VM size" + }, + { + "columnId": "nicId", + "label": "Network interface" + }, + { + "columnId": "privateIP", + "label": "Private IP" + }, + { + "columnId": "publicIpId", + "label": "Public IP" + }, + { + "columnId": "publicIpAddress", + "label": "Public IP address" + } + ] + } + }, + "name": "Compute networking" + }, + { + "type": 1, + "content": { + "json": "# Managed disk utilization" + }, + "name": "text - 16" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "ec135d58-9c6b-4998-bd1e-75871c540d7f", + "version": "KqlParameterItem/1.0", + "name": "laworkspace", + "label": "Log Analytics workspace", + "type": 5, + "description": "LA workspaces configured in virtual machines insight settings", + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "where type =~ 'microsoft.operationalinsights/workspaces' | project id", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": [] + } + ], + "style": "above", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "name": "Log Analytics workspace selector" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "InsightsMetrics\n| where Origin == \"vm.azm.ms\"\n| where Namespace == \"LogicalDisk\"\n| where Name == \"FreeSpacePercentage\"\n| extend t=parse_json(Tags)\n| summarize arg_max(TimeGenerated, *) by tostring(t[\"vm.azm.ms/mountId\"]), Computer // arg_max over TimeGenerated returns the latest record\n| project Computer, TimeGenerated, t[\"vm.azm.ms/mountId\"], Val\n", + "size": 4, + "title": "Managed disks free space", + "timeContext": { + "durationMs": 604800000 + }, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{laworkspace}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Val", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": ">=", + "thresholdValue": "90", + "representation": "4", + "text": "{0}{1}" + }, + { + "operator": ">=", + "thresholdValue": "50", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 1, + "options": { + "style": "decimal", + "useGrouping": false, + "maximumFractionDigits": 0 + } + } + } + ], + "labelSettings": [ + { + "columnId": "Computer", + "label": "Computer" + }, + { + "columnId": "TimeGenerated", + "label": "TimeGenerated" + }, + { + "columnId": "t_vm.azm.ms/mountId", + "label": "Drive" + }, + { + "columnId": "Val", + "label": "Free space percentage" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "laworkspace", + "comparison": "isNotEqualTo" + }, + "name": "Managed disks free space" + }, + { + "type": 1, + "content": { + "json": "# Compute optimization" + }, + "name": "text - 9" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "advisorresources\r\n| where type == \"microsoft.advisor/recommendations\"\r\n| where tostring (properties.category) has \"Cost\"\r\n| where properties.shortDescription.problem has \"underutilized\"\r\n| where properties.impactedField has \"Compute\" or properties.impactedField has \"Container\" or properties.impactedField has \"Web\"\r\n| project AffectedResource=tostring(properties.resourceMetadata.resourceId),Impact=properties.impact,resourceGroup,AdditionaInfo=properties.extendedProperties,subscriptionId,Recommendation=tostring(properties.shortDescription.problem)\r\n", + "size": 0, + "title": "Underused assets", + "noDataMessage": "No underused asset", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "customWidth": "100", + "name": "Underused assets" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "37cdc20d-07c3-466c-84bb-4d8050932641", + "version": "KqlParameterItem/1.0", + "name": "OrphanDisks", + "label": "Orphaned", + "type": 10, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":\"!=\", \"label\":\"No\" },\r\n { \"value\":\"==\", \"label\":\"Yes\" }\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "!=" + } + ], + "style": "above", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "Disks" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources \r\n| where type contains \"microsoft.compute/disks\" \r\n| extend diskState = tostring(properties.diskState)\r\n| where managedBy {OrphanDisks} \"\" or diskState {OrphanDisks} 'Unattached'\r\n| project id, subscriptionId, resourceGroup, diskState, location", + "size": 0, + "title": "Managed disks", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "location", + "formatter": 17 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Resource Name" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + }, + { + "columnId": "resourceGroup", + "label": "Resource group" + }, + { + "columnId": "diskState", + "label": "Disk state" + }, + { + "columnId": "location", + "label": "Region" + } + ] + } + }, + "name": "Managed disks" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "2d9b8893-0af4-480a-9ac7-639efb771ecb", + "version": "KqlParameterItem/1.0", + "name": "OrphanNIC", + "label": "Orphaned", + "type": 10, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":\"has 'virtualmachine' or isnotnull(privateEndPoint)\", \"label\":\"No\" },\r\n { \"value\":\"!has 'virtualmachine' and isnull(privateEndPoint)\", \"label\":\"Yes\" }\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "has 'virtualmachine' or isnotnull(privateEndPoint)" + } + ], + "style": "above", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "NICs - Copy" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n| where type has \"microsoft.network/networkinterfaces\"\r\n| extend VM = properties.virtualMachine.id\r\n| extend privateEndPoint = properties['privateEndpoint']['id']\r\n| where properties {OrphanNIC}\r\n| where properties['linkedResourceType'] != \"Microsoft.Netapp/volumes\"\r\n| project id, subscriptionId, resourceGroup, location, VM, privateEndPoint, properties\r\n", + "size": 0, + "title": "NICs", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "location", + "formatter": 17 + }, + { + "columnMatch": "properties", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Resource name" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + }, + { + "columnId": "resourceGroup", + "label": "Resource group" + }, + { + "columnId": "location", + "label": "Region" + }, + { + "columnId": "VM", + "label": "Virtual machine" + }, + { + "columnId": "privateEndPoint", + "label": "Private end point" + }, + { + "columnId": "properties", + "label": "Details" + } + ] + } + }, + "name": "NICs" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "98d786aa-8835-493f-9fe4-fe5da150392b", + "version": "KqlParameterItem/1.0", + "name": "VMState", + "label": "Virtual machine state", + "type": 2, + "query": "resources\r\n| where type == \"microsoft.compute/virtualmachines\"\r\n| extend state = properties['extended']['instanceView']['powerState']['displayStatus']\r\n| summarize by tostring(state)", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null + } + ], + "style": "above", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "name": "parameters - VMState" + }, + { + "type": 1, + "content": { + "json": "Select a virtual machine state to display the list of resource.", + "style": "info" + }, + "conditionalVisibility": { + "parameterName": "VMState", + "comparison": "isEqualTo" + }, + "name": "text - VMState" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources | where type == \"microsoft.compute/virtualmachines\"\r\n| extend vmState = tostring(properties.extended.instanceView.powerState.displayStatus)\r\n| extend vmState = iif(isempty(vmState), \"VM State Unknown\", (vmState))\r\n| summarize count() by vmState", + "size": 3, + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "vmState", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "showBorder": false + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "vmState", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "count_", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "name": "query - VM state chart" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == \"microsoft.compute/virtualmachines\"\r\n| extend vmSize = tostring(properties.hardwareProfile.vmSize)\r\n| extend vmState = properties['extended']['instanceView']['powerState']['displayStatus']\r\n| where vmState == '{VMState}'\r\n| project id, subscriptionId, resourceGroup, vmState, vmSize, location", + "size": 0, + "title": "Virtual machine list by powerstate", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": false + } + }, + { + "columnMatch": "id", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "vmSize", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "19.1429ch" + } + }, + { + "columnMatch": "location", + "formatter": 17, + "formatOptions": { + "customColumnWidthSetting": "108px" + } + } + ], + "filter": true, + "labelSettings": [ + { + "columnId": "id", + "label": "Resource Name" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "vmState", + "label": "VM State" + }, + { + "columnId": "vmSize", + "label": "VM Size" + }, + { + "columnId": "location", + "label": "Region" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "VMState", + "comparison": "isNotEqualTo" + }, + "name": "query - VM list by powerstate" + }, + { + "type": 1, + "content": { + "json": "States and billing status of Azure virtual machines : https://learn.microsoft.com/azure/virtual-machines/states-billing", + "style": "info" + }, + "name": "Info VM states" + } + ] + }, + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "group - VMQueries" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_VM" + }, + "name": "RC_VM" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Storage account + backup" + }, + "name": "text - 9" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'microsoft.storagesync/storagesyncservices'\r\n\tor type =~ 'microsoft.recoveryservices/vaults'\r\n\tor type =~ 'microsoft.storage/storageaccounts'\r\n\tor type =~ 'microsoft.keyvault/vaults'\r\n| extend type = case(\r\n\ttype =~ 'microsoft.storagesync/storagesyncservices', 'Azure File Sync',\r\n\ttype =~ 'microsoft.recoveryservices/vaults', 'Azure Backup',\r\n\ttype =~ 'microsoft.storage/storageaccounts', 'Storage Accounts',\r\n\ttype =~ 'microsoft.keyvault/vaults', 'Key Vaults',\r\n\tstrcat(\"Not Translated: \", type))\r\n| where type !has \"Not Translated\"\r\n| summarize count() by type", + "size": 3, + "title": "Count of all resource types", + "noDataMessage": "No resources found", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Resource", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true, + "finalBy": "Resource" + } + }, + "tileSettings": { + "titleContent": { + "columnMatch": "type", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "showBorder": false, + "sortCriteriaField": "type", + "sortOrderField": 1 + } + }, + "name": "query - Storage - Resource Overview " + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'microsoft.storagesync/storagesyncservices'\r\n\tor type =~ 'microsoft.recoveryservices/vaults'\r\n\tor type =~ 'microsoft.storage/storageaccounts'\r\n\tor type =~ 'microsoft.keyvault/vaults'\r\n| extend type = case(\r\n\ttype =~ 'microsoft.storagesync/storagesyncservices', 'Azure File Sync',\r\n\ttype =~ 'microsoft.recoveryservices/vaults', 'Azure Backup',\r\n\ttype =~ 'microsoft.storage/storageaccounts', 'Storage Accounts',\r\n\ttype =~ 'microsoft.keyvault/vaults', 'Key Vaults',\r\n\tstrcat(\"Not Translated: \", type))\r\n| extend Sku = case(\r\n\ttype !has 'Key Vaults', sku.name,\r\n\ttype =~ 'Key Vaults', properties.sku.name,\r\n\t' ')\r\n| extend Details = pack_all()\r\n| project Resource=id, type, kind, subscriptionId, resourceGroup, Sku, Details", + "size": 0, + "title": "Resource details", + "noDataMessage": "No resources found", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Resource", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + }, + { + "columnMatch": "Details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View Details", + "linkIsContextBlade": true + } + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true, + "finalBy": "Resource" + } + } + }, + "name": "query - Storage - Resource Detailed" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "e94aafa3-c5d9-4523-89f0-4e87aa754511", + "version": "KqlParameterItem/1.0", + "name": "Resources", + "label": "Storage accounts", + "type": 5, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "where type =~ 'microsoft.storage/storageaccounts'\n| order by name asc\n| extend Rank = row_number()\n| project value = id, label = id, selected = Rank <= 5", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "resourceTypeFilter": { + "microsoft.storage/storageaccounts": true + }, + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": [ + "value::all" + ] + }, + { + "id": "c4b69c01-2263-4ada-8d9c-43433b739ff3", + "version": "KqlParameterItem/1.0", + "name": "TimeRange", + "type": 4, + "isRequired": true, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 300000, + "createdTime": "2018-08-06T23:52:38.87Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + }, + { + "durationMs": 900000, + "createdTime": "2018-08-06T23:52:38.871Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + }, + { + "durationMs": 1800000, + "createdTime": "2018-08-06T23:52:38.871Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + }, + { + "durationMs": 3600000, + "createdTime": "2018-08-06T23:52:38.871Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + }, + { + "durationMs": 14400000, + "createdTime": "2018-08-06T23:52:38.871Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + }, + { + "durationMs": 43200000, + "createdTime": "2018-08-06T23:52:38.871Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + }, + { + "durationMs": 86400000, + "createdTime": "2018-08-06T23:52:38.871Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + }, + { + "durationMs": 172800000, + "createdTime": "2018-08-06T23:52:38.871Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + }, + { + "durationMs": 259200000, + "createdTime": "2018-08-06T23:52:38.871Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + }, + { + "durationMs": 604800000, + "createdTime": "2018-08-06T23:52:38.871Z", + "isInitialTime": false, + "grain": 1, + "useDashboardTimeRange": false + } + ], + "allowCustom": true + }, + "value": { + "durationMs": 172800000 + }, + "label": "Time range" + }, + { + "id": "9b48988f-dcd2-48cc-b233-5999ed32149f", + "version": "KqlParameterItem/1.0", + "name": "Message", + "type": 1, + "query": "where type == 'microsoft.storage/storageaccounts' \n| summarize Selected = countif(id in ({Resources:value})), Total = count()\n| extend Selected = iff(Selected > 200, 200, Selected)\n| project Message = strcat('# ', Selected, ' / ', Total)", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "070b2474-4e01-478d-a7fa-6c20ad8ea1ad", + "version": "KqlParameterItem/1.0", + "name": "ResourceName", + "type": 1, + "isRequired": true, + "isHiddenWhenLocked": true, + "criteriaData": [ + { + "condition": "else result = 'Storage account'", + "criteriaContext": { + "operator": "Default", + "rightValType": "param", + "resultValType": "static", + "resultVal": "Storage account" + } + } + ] + }, + { + "id": "c6c32b32-6eb4-44d5-9cad-156d5d50ec3e", + "version": "KqlParameterItem/1.0", + "name": "ResourceImageUrl", + "type": 1, + "description": "used as a parameter for No Subcriptions workbook template", + "isHiddenWhenLocked": true + } + ], + "style": "above", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - 1", + "styleSettings": { + "margin": "15px 0 0 0" + } + }, + { + "type": 1, + "content": { + "json": "## Storage accounts details" + }, + "name": "text - 8" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "27d282bb-38ae-4ceb-b2bb-063db08ec6bc", + "cellValue": "selectedTab", + "linkTarget": "parameter", + "linkLabel": "Overview", + "subTarget": "Overview" + }, + { + "id": "9a52f588-fff8-47fe-b56d-81b8068ff6f7", + "cellValue": "selectedTab", + "linkTarget": "parameter", + "linkLabel": "Capacity", + "subTarget": "Capacity" + } + ] + }, + "name": "Navigation links", + "styleSettings": { + "margin": "10px 0 0 0" + } + }, + { + "type": 1, + "content": { + "json": "### Overview section" + }, + "conditionalVisibility": { + "parameterName": "1", + "comparison": "isEqualTo", + "value": "2" + }, + "name": "text - 4" + }, + { + "type": 10, + "content": { + "chartId": "workbookdb19a8d8-91af-44ea-951d-5ffa133b2ebe", + "version": "MetricsItem/2.0", + "size": 2, + "chartType": 0, + "resourceType": "microsoft.storage/storageaccounts", + "metricScope": 0, + "resourceParameter": "Resources", + "resourceIds": [ + "{Resources}" + ], + "timeContextFromParameter": "TimeRange", + "timeContext": { + "durationMs": 172800000 + }, + "metrics": [ + { + "namespace": "microsoft.storage/storageaccounts", + "metric": "microsoft.storage/storageaccounts-Transaction-Transactions", + "aggregation": 1 + }, + { + "namespace": "microsoft.storage/storageaccounts", + "metric": "microsoft.storage/storageaccounts-Transaction-SuccessE2ELatency", + "aggregation": 4 + }, + { + "namespace": "microsoft.storage/storageaccounts", + "metric": "microsoft.storage/storageaccounts-Transaction-SuccessServerLatency", + "aggregation": 4 + }, + { + "namespace": "microsoft.storage/storageaccounts", + "metric": "microsoft.storage/storageaccounts-Transaction-Transactions", + "aggregation": 1, + "splitBy": [ + "ResponseType" + ], + "splitBySortOrder": -1, + "splitByLimit": 4, + "columnName": "Errors" + } + ], + "resourceLimit": 200, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "subTarget": "insights", + "showIcon": true + } + }, + { + "columnMatch": "Subscription", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "Name", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts-Transaction-Transactions$|Transactions$", + "formatter": 8, + "formatOptions": { + "min": 0, + "palette": "blue", + "showIcon": true, + "aggregation": "Sum" + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal", + "maximumFractionDigits": 1 + } + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts-Transaction-Transactions Timeline$|Transactions Timeline$", + "formatter": 21, + "formatOptions": { + "min": 0, + "palette": "blue", + "showIcon": true + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts-Transaction-SuccessE2ELatency$|microsoft.storage/storageaccounts-Transaction-SuccessServerLatency$|E2E Latency$|Server Latency$", + "formatter": 8, + "formatOptions": { + "min": 0, + "palette": "blue", + "linkTarget": "WorkbookTemplate", + "showIcon": true, + "workbookContext": { + "componentIdSource": "column", + "componentId": "Name", + "resourceIdsSource": "column", + "resourceIds": "Name", + "templateIdSource": "static", + "templateId": "Community-Workbooks/Individual Storage/Performance", + "typeSource": "static", + "type": "workbook", + "gallerySource": "static", + "gallery": "microsoft.storage/storageaccounts" + } + }, + "numberFormat": { + "unit": 23, + "options": { + "style": "decimal", + "maximumFractionDigits": 2 + } + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts-Transaction-SuccessE2ELatency Timeline$|E2E Latency Timeline$", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts-Transaction-SuccessServerLatency Timeline", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "Success/Errors", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "success/Errors", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": ".*\\/Errors", + "formatter": 8, + "formatOptions": { + "min": 0, + "palette": "gray", + "linkTarget": "WorkbookTemplate", + "showIcon": true, + "workbookContext": { + "componentIdSource": "column", + "componentId": "Name", + "resourceIdsSource": "column", + "resourceIds": "Name", + "templateIdSource": "static", + "templateId": "Community-Workbooks/Individual Storage/Failures", + "typeSource": "static", + "type": "workbook", + "gallerySource": "static", + "gallery": "microsoft.storage/storageaccounts" + } + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal", + "maximumFractionDigits": 1 + } + } + }, + { + "columnMatch": "Server Latency Timeline", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + } + ], + "rowLimit": 10000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Subscription" + ], + "expandTopLevel": true, + "finalBy": "Name" + }, + "sortBy": [ + { + "itemKey": "$gen_heatmap_microsoft.storage/storageaccounts-Transaction-Transactions$|Transactions$_3", + "sortOrder": 2 + } + ], + "labelSettings": [ + { + "columnId": "Subscription", + "label": "Subscription" + }, + { + "columnId": "microsoft.storage/storageaccounts-Transaction-Transactions", + "label": "Transactions" + }, + { + "columnId": "microsoft.storage/storageaccounts-Transaction-Transactions Timeline", + "label": "Transactions timeline" + }, + { + "columnId": "microsoft.storage/storageaccounts-Transaction-SuccessE2ELatency", + "label": "E2E latency" + }, + { + "columnId": "microsoft.storage/storageaccounts-Transaction-SuccessE2ELatency Timeline", + "label": "E2E latency timeline" + }, + { + "columnId": "microsoft.storage/storageaccounts-Transaction-SuccessServerLatency", + "label": "Server latency" + }, + { + "columnId": "microsoft.storage/storageaccounts-Transaction-SuccessServerLatency Timeline", + "label": "Server latency timeline" + } + ] + }, + "sortBy": [ + { + "itemKey": "$gen_heatmap_microsoft.storage/storageaccounts-Transaction-Transactions$|Transactions$_3", + "sortOrder": 2 + } + ], + "showExportToExcel": true + }, + "conditionalVisibility": { + "parameterName": "selectedTab", + "comparison": "isEqualTo", + "value": "Overview" + }, + "showPin": true, + "name": "storage account metrics", + "styleSettings": { + "margin": "0 10px 0 10px" + } + }, + { + "type": 1, + "content": { + "json": "## Capacity section" + }, + "conditionalVisibility": { + "parameterName": "1", + "comparison": "isEqualTo", + "value": "2" + }, + "name": "text - 6" + }, + { + "type": 10, + "content": { + "chartId": "workbookdb19a8d8-91af-44ea-951d-5ffa133b2ebe", + "version": "MetricsItem/2.0", + "size": 3, + "chartType": 0, + "resourceType": "microsoft.storage/storageaccounts", + "metricScope": 0, + "resourceParameter": "Resources", + "resourceIds": [ + "{Resources}" + ], + "timeContextFromParameter": "TimeRange", + "timeContext": { + "durationMs": 172800000 + }, + "metrics": [ + { + "namespace": "microsoft.storage/storageaccounts", + "metric": "microsoft.storage/storageaccounts-Capacity-UsedCapacity", + "aggregation": 4 + }, + { + "namespace": "microsoft.storage/storageaccounts/blobservices", + "metric": "microsoft.storage/storageaccounts/blobservices-Capacity-BlobCapacity", + "aggregation": 4 + }, + { + "namespace": "microsoft.storage/storageaccounts/fileservices", + "metric": "microsoft.storage/storageaccounts/fileservices-Capacity-FileCapacity", + "aggregation": 4 + }, + { + "namespace": "microsoft.storage/storageaccounts/queueservices", + "metric": "microsoft.storage/storageaccounts/queueservices-Capacity-QueueCapacity", + "aggregation": 4 + }, + { + "namespace": "microsoft.storage/storageaccounts/tableservices", + "metric": "microsoft.storage/storageaccounts/tableservices-Capacity-TableCapacity", + "aggregation": 4 + } + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "subTarget": "insights", + "showIcon": true + } + }, + { + "columnMatch": "Subscription", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "Name", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts-Capacity-UsedCapacity$|microsoft.storage/storageaccounts/blobservices-Capacity-BlobCapacity$|microsoft.storage/storageaccounts/fileservices-Capacity-FileCapacity$|microsoft.storage/storageaccounts/queueservices-Capacity-QueueCapacity$|microsoft.storage/storageaccounts/tableservices-Capacity-TableCapacity$", + "formatter": 8, + "formatOptions": { + "min": 0, + "palette": "blue", + "linkTarget": "WorkbookTemplate", + "showIcon": true, + "workbookContext": { + "componentIdSource": "column", + "componentId": "Name", + "resourceIdsSource": "column", + "resourceIds": "Name", + "templateIdSource": "static", + "templateId": "Community-Workbooks/Individual Storage/Capacity", + "typeSource": "static", + "type": "workbook", + "gallerySource": "static", + "gallery": "microsoft.storage/storageaccounts" + } + }, + "numberFormat": { + "unit": 2, + "options": { + "style": "decimal", + "maximumFractionDigits": 1 + } + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts-Capacity-UsedCapacity Timeline$|Account used capacity Timeline$", + "formatter": 21, + "formatOptions": { + "min": 0, + "palette": "blue", + "showIcon": true + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts/blobservices-Capacity-BlobCapacity Timeline$|Blob capacity Timeline$", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts/fileservices-Capacity-FileCapacity Timeline$|File capacity Timeline$", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts/queueservices-Capacity-QueueCapacity Timeline$|Queue capacity Timeline$", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "microsoft.storage/storageaccounts/tableservices-Capacity-TableCapacity Timeline$|Table capacity Timeline$", + "formatter": 5, + "formatOptions": { + "showIcon": true + } + } + ], + "rowLimit": 10000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Subscription" + ], + "expandTopLevel": true, + "finalBy": "Name" + }, + "sortBy": [ + { + "itemKey": "$gen_link_$gen_group_0", + "sortOrder": 1 + } + ], + "labelSettings": [ + { + "columnId": "Subscription", + "label": "Subscription" + }, + { + "columnId": "microsoft.storage/storageaccounts-Capacity-UsedCapacity", + "label": "Account used capacity" + }, + { + "columnId": "microsoft.storage/storageaccounts-Capacity-UsedCapacity Timeline", + "label": "Account used capacity timeline" + }, + { + "columnId": "microsoft.storage/storageaccounts/blobservices-Capacity-BlobCapacity", + "label": "Blob capacity" + }, + { + "columnId": "microsoft.storage/storageaccounts/blobservices-Capacity-BlobCapacity Timeline", + "label": "Blob capacity timeline" + }, + { + "columnId": "microsoft.storage/storageaccounts/fileservices-Capacity-FileCapacity", + "label": "File capacity" + }, + { + "columnId": "microsoft.storage/storageaccounts/fileservices-Capacity-FileCapacity Timeline", + "label": "File capacity timeline" + }, + { + "columnId": "microsoft.storage/storageaccounts/queueservices-Capacity-QueueCapacity", + "label": "Queue capacity" + }, + { + "columnId": "microsoft.storage/storageaccounts/queueservices-Capacity-QueueCapacity Timeline", + "label": "Queue capacity timeline" + }, + { + "columnId": "microsoft.storage/storageaccounts/tableservices-Capacity-TableCapacity", + "label": "Table capacity" + }, + { + "columnId": "microsoft.storage/storageaccounts/tableservices-Capacity-TableCapacity Timeline", + "label": "Table capacity timeline" + } + ] + }, + "sortBy": [ + { + "itemKey": "$gen_link_$gen_group_0", + "sortOrder": 1 + } + ], + "showExportToExcel": true + }, + "conditionalVisibility": { + "parameterName": "selectedTab", + "comparison": "isEqualTo", + "value": "Capacity" + }, + "showPin": true, + "name": "storage account capacity metrics", + "styleSettings": { + "margin": "0 10px 0 10px" + } + } + ] + }, + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo", + "value": "" + }, + "name": "Storage account + backup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "Azure Backup now provides a set of customizable reporting templates to help you generate audit evidence reports for backup in an easier way. [Learn more](https://aka.ms/BCDRAuditReportTemplates).", + "style": "upsell" + }, + "name": "AuditText" + }, + { + "type": 1, + "content": { + "json": "## Backup details\r\n### Manage and securely backup your resources\r\nExplore and monitor backup estate at scale in real time across vaults." + }, + "name": "text - 8" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "2373a24f-ad32-4909-a7f6-59b373dcde6c", + "version": "KqlParameterItem/1.0", + "name": "Workspaces", + "label": "Workspace", + "type": 5, + "description": "LA workspaces configured in vault diagnostic settings", + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "where type =~ 'microsoft.operationalinsights/workspaces' | project id", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": [] + } + ], + "style": "above", + "doNotRunWhenHidden": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "100", + "name": "Filters1" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Workspaces}" + ], + "parameters": [ + { + "id": "2965ad33-1401-47c9-8f4b-9b7126f87014", + "version": "KqlParameterItem/1.0", + "name": "TimeRange", + "label": "Time Range", + "type": 4, + "description": "Period of time for which reports should be viewed", + "isRequired": true, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 259200000 + }, + { + "durationMs": 604800000 + }, + { + "durationMs": 1209600000 + }, + { + "durationMs": 2419200000 + }, + { + "durationMs": 2592000000 + }, + { + "durationMs": 5184000000 + }, + { + "durationMs": 7776000000 + } + ], + "allowCustom": true + }, + "value": { + "durationMs": 604800000 + } + }, + { + "id": "efede5fa-f577-4766-b9b6-6ba4e525f844", + "version": "KqlParameterItem/1.0", + "name": "DataSourceSubscription", + "label": "Datasource Subscription", + "type": 6, + "description": "Use to filter for datasources within a specific subscription", + "isRequired": true, + "multiSelect": true, + "quote": "", + "delimiter": ",", + "query": "let RangeStart = startofday({TimeRange:start});\r\nlet RangeEnd = iff(startofday({TimeRange:end}) == startofday(now()) ,startofday({TimeRange:end}) - 1d , startofday({TimeRange:end}));\r\nlet VaultSubscriptionList = \"*\";\r\nlet VaultLocationList = \"*\";\r\nlet VaultList = \"*\";\r\nlet VaultTypeList = \"*\";\r\nlet ExcludeLegacyEvent = true;\r\nlet BackupSolutionList = \"*\";\r\nlet ProtectionInfoList = \"*\";\r\nlet Item_search = \"*;*\";\r\nlet ItemArray = split(Item_search, \";\");\r\nlet ItemArray_length = array_length(ItemArray);\r\nlet BackupInstanceName = iff(ItemArray_length == 2, ItemArray[1], ItemArray[0] );\r\nlet DatasourceSetName = iff(ItemArray_length == 2, ItemArray[0], \"\");\r\nlet DisplayAllFields = false;\r\n_AzureBackup_GetBackupInstances(RangeStart, RangeEnd, VaultSubscriptionList, VaultLocationList, VaultList, VaultTypeList, ExcludeLegacyEvent, BackupSolutionList, ProtectionInfoList, DatasourceSetName, BackupInstanceName, DisplayAllFields)\r\n| distinct tostring(split(tostring(todynamic(DatasourceResourceId)),\"/\")[2])", + "crossComponentResources": [ + "{Workspaces}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "selectAllValue": "*", + "showDefault": false + }, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "value": [] + }, + { + "id": "256c7e33-df90-4956-aaf3-699aeaad912f", + "version": "KqlParameterItem/1.0", + "name": "DataSourceLocation", + "label": "Data source location", + "type": 2, + "description": "Use to filter for data sources within a specific location", + "isRequired": true, + "multiSelect": true, + "quote": "", + "delimiter": ",", + "query": "let RangeStart = startofday({TimeRange:start});\r\nlet RangeEnd = iff(startofday({TimeRange:end}) == startofday(now()) ,startofday({TimeRange:end}) - 1d , startofday({TimeRange:end}));\r\nlet VaultSubscriptionList = todynamic( replace(\"/subscriptions/\", \"\", @\"{DataSourceSubscription}\"));\r\nlet VaultLocationList = \"*\";\r\nlet VaultList = \"*\";\r\nlet VaultTypeList = \"*\";\r\nlet ExcludeLegacyEvent = true;\r\nlet BackupSolutionList = \"*\";\r\nlet ProtectionInfoList = \"*\";\r\nlet Item_search = \"*;*\";\r\nlet ItemArray = split(Item_search, \";\");\r\nlet ItemArray_length = array_length(ItemArray);\r\nlet BackupInstanceName = iff(ItemArray_length == 2, ItemArray[1], ItemArray[0] );\r\nlet DatasourceSetName = iff(ItemArray_length == 2, ItemArray[0], \"\");\r\nlet DisplayAllFields = false;\r\n_AzureBackup_GetBackupInstances(RangeStart, RangeEnd, VaultSubscriptionList, VaultLocationList, VaultList, VaultTypeList, ExcludeLegacyEvent, BackupSolutionList, ProtectionInfoList, DatasourceSetName, BackupInstanceName, DisplayAllFields)\r\n| distinct VaultLocation", + "crossComponentResources": [ + "{Workspaces}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "selectAllValue": "*", + "showDefault": false + }, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "value": [ + "value::all" + ] + }, + { + "id": "16ad110f-4ea3-44d6-826b-4ea3bbd68c93", + "version": "KqlParameterItem/1.0", + "name": "JobOperation", + "label": "Job Operation", + "type": 2, + "description": "Use to filter for a particular operation type", + "isRequired": true, + "multiSelect": true, + "quote": "", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "selectAllValue": "*", + "showDefault": false + }, + "jsonData": "\r\n[ \r\n{ \"value\": \"Backup\", \t\t\t\t\t\t\"label\": \"Backup\" },\r\n{ \"value\": \"Restore\", \t\t\t\t\t\t\"label\": \"Restore\" }\r\n]", + "value": [ + "value::all" + ] + }, + { + "id": "6a6222bf-a28a-4c98-9d74-838e74497167", + "version": "KqlParameterItem/1.0", + "name": "JobStatus", + "label": "Job Status", + "type": 2, + "description": "Use to filter for a particular job status", + "isRequired": true, + "multiSelect": true, + "quote": "", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "selectAllValue": "*", + "showDefault": false + }, + "jsonData": "\r\n[ \r\n{ \"value\": \"Completed\", \t\t\t\t\t\t\"label\": \"Completed\" },\r\n{ \"value\": \"Failed\", \t\t\t\"label\": \"Failed\" },\r\n\r\n{ \"value\": \"CompletedWithWarnings\", \t\t\t\t\t\t\"label\": \"CompletedWithWarnings\" },\r\n{ \"value\": \"Cancelled\", \"label\": \"Cancelled\" }\r\n]", + "value": [ + "value::all" + ] + }, + { + "id": "849a6401-cbaf-44b9-a733-0819f8923791", + "version": "KqlParameterItem/1.0", + "name": "SearchItem", + "label": "Search Item", + "type": 1, + "description": "Use to search for an item by name" + } + ], + "style": "above", + "doNotRunWhenHidden": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "100", + "conditionalVisibility": { + "parameterName": "Workspaces", + "comparison": "isNotEqualTo" + }, + "name": "Filters2" + }, + { + "type": 1, + "content": { + "json": "## Backup job history" + }, + "conditionalVisibility": { + "parameterName": "Workspaces", + "comparison": "isNotEqualTo" + }, + "name": "Heading2" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "\r\nlet RangeStart = startofday({TimeRange:start});\r\nlet RangeEnd = iff(startofday({TimeRange:end}) == startofday(now()) ,startofday({TimeRange:end}) - 1d , startofday({TimeRange:end}));\r\nlet DataSourceSubscriptionList = todynamic( replace(\"/subscriptions/\", \"\", @\"{DataSourceSubscription}\"));\r\nlet DataSourceLocationList = todynamic( @\"{DataSourceLocation}\"); \r\nlet VaultTypeList = \"*\";\r\nlet VaultList = \"*\";\r\nlet ExcludeLegacyEvent = true;\r\nlet BackupSolutionList = \"*\";\r\nlet ProtectionInfoList = \"*\";\r\nlet Item_search = \"*;*\";\r\nlet ItemArray = split(Item_search, \";\");\r\nlet ItemArray_length = array_length(ItemArray);\r\nlet BackupInstanceName = iff(ItemArray_length == 2, ItemArray[1], ItemArray[0] );\r\nlet DatasourceSetName = iff(ItemArray_length == 2, ItemArray[0], \"\");\r\nlet JobOperationList = todynamic( @\"{JobOperation}\"); \r\nlet JobStatusList = todynamic( @\"{JobStatus}\");\r\nlet JobFailureCodeList = \"*\";\r\nlet ExcludeLog = true; \r\n_AzureBackup_GetJobs(RangeStart, RangeEnd, DataSourceSubscriptionList, DataSourceLocationList, VaultList, VaultTypeList, ExcludeLegacyEvent, BackupSolutionList, JobOperationList, JobStatusList, JobFailureCodeList, DatasourceSetName, BackupInstanceName, ExcludeLog)\r\n| where BackupInstanceFriendlyName contains iff(isnotempty('{SearchItem}'),'{SearchItem}',BackupInstanceFriendlyName)\r\n| sort by BackupInstanceId\r\n| summarize count() by Status", + "size": 3, + "title": "Jobs by Status", + "noDataMessage": "No record found for the selected time and scope.", + "showRefreshButton": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspaces}" + ], + "visualization": "piechart", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "UniqueId", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "DurationInSecs", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "customWidth": "0", + "conditionalVisibility": { + "parameterName": "Workspaces", + "comparison": "isNotEqualTo" + }, + "name": "Chart1", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Workspaces}" + ], + "parameters": [ + { + "id": "7a64467f-eec7-495b-9099-233fb7bceb08", + "version": "KqlParameterItem/1.0", + "name": "RowsPerPage", + "label": "Rows per page", + "type": 2, + "description": "Number of rows to display in a single page", + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":10, \"label\":\"10\", \"selected\":true },\r\n { \"value\":25, \"label\":\"25\" },\r\n { \"value\":50, \"label\":\"50\" },\r\n { \"value\":100, \"label\":\"100\" },\r\n { \"value\":250, \"label\":\"250\" },\r\n { \"value\":500, \"label\":\"500\" },\r\n { \"value\":1000, \"label\":\"1000\" }\r\n]" + }, + { + "id": "5c65bc61-a721-42b7-960b-3fe7a6170eb6", + "version": "KqlParameterItem/1.0", + "name": "Page", + "type": 2, + "description": "Page number", + "isRequired": true, + "query": "\r\nlet RangeStart = startofday({TimeRange:start});\r\nlet RangeEnd = iff(startofday({TimeRange:end}) == startofday(now()) ,startofday({TimeRange:end}) - 1d , startofday({TimeRange:end}));\r\nlet DataSourceSubscriptionList = todynamic( replace(\"/subscriptions/\", \"\", @\"{DataSourceSubscription}\"));\r\nlet DataSourceLocationList = todynamic( @\"{DataSourceLocation}\"); \r\nlet VaultTypeList = \"*\";\r\nlet VaultList = \"*\";\r\nlet ExcludeLegacyEvent = true;\r\nlet BackupSolutionList = \"*\";\r\nlet ProtectionInfoList = \"*\";\r\nlet Item_search = \"*;*\";\r\nlet ItemArray = split(Item_search, \";\");\r\nlet ItemArray_length = array_length(ItemArray);\r\nlet BackupInstanceName = iff(ItemArray_length == 2, ItemArray[1], ItemArray[0] );\r\nlet DatasourceSetName = iff(ItemArray_length == 2, ItemArray[0], \"\");\r\nlet JobOperationList = todynamic( @\"{JobOperation}\"); \r\nlet JobStatusList = todynamic( @\"{JobStatus}\");\r\nlet JobFailureCodeList = \"*\";\r\nlet ExcludeLog = true; \r\nlet backupItem = '{SearchItem}';\r\n_AzureBackup_GetJobs(RangeStart, RangeEnd, DataSourceSubscriptionList, DataSourceLocationList, VaultList, VaultTypeList, ExcludeLegacyEvent, BackupSolutionList, JobOperationList, JobStatusList, JobFailureCodeList, DatasourceSetName, BackupInstanceName, ExcludeLog)\r\n| where BackupInstanceFriendlyName contains backupItem\r\n| summarize c=count()\r\n| project num = (c-1)/toint('{RowsPerPage}') + 1\r\n| project nums = range(1,num,1), num\r\n| mvexpand nums\r\n| project nums = tostring(nums), num = strcat(tostring(nums),\" of \",tostring(num))\r\n\r\n", + "crossComponentResources": [ + "{Workspaces}" + ], + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "value": "1" + } + ], + "style": "above", + "doNotRunWhenHidden": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "100", + "conditionalVisibility": { + "parameterName": "Workspaces", + "comparison": "isNotEqualTo" + }, + "name": "Filters3" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "\r\nlet RangeStart = startofday({TimeRange:start});\r\nlet RangeEnd = iff(startofday({TimeRange:end}) == startofday(now()) ,startofday({TimeRange:end}) - 1d , startofday({TimeRange:end}));\r\nlet DataSourceSubscriptionList = todynamic( replace(\"/subscriptions/\", \"\", @\"{DataSourceSubscription}\"));\r\nlet DataSourceLocationList = todynamic( @\"{DataSourceLocation}\"); \r\nlet VaultTypeList = \"*\";\r\nlet VaultList = \"*\";\r\nlet ExcludeLegacyEvent = true;\r\nlet BackupSolutionList = \"*\";\r\nlet ProtectionInfoList = \"*\";\r\nlet Item_search = \"*;*\";\r\nlet ItemArray = split(Item_search, \";\");\r\nlet ItemArray_length = array_length(ItemArray);\r\nlet BackupInstanceName = iff(ItemArray_length == 2, ItemArray[1], ItemArray[0] );\r\nlet DatasourceSetName = iff(ItemArray_length == 2, ItemArray[0], \"\");\r\nlet JobOperationList = todynamic( @\"{JobOperation}\"); \r\nlet JobStatusList = todynamic( @\"{JobStatus}\");\r\nlet JobFailureCodeList = \"*\";\r\nlet ExcludeLog = true; \r\nlet backupItem = '{SearchItem}';\r\n_AzureBackup_GetJobs(RangeStart, RangeEnd, DataSourceSubscriptionList, DataSourceLocationList, VaultList, VaultTypeList, ExcludeLegacyEvent, BackupSolutionList, JobOperationList, JobStatusList, JobFailureCodeList, DatasourceSetName, BackupInstanceName, ExcludeLog)\r\n| where BackupInstanceFriendlyName contains iff(isnotempty('{SearchItem}'),'{SearchItem}',BackupInstanceFriendlyName)\r\n| sort by BackupInstanceId\r\n| extend row_num = row_number()\r\n| extend page_num = tostring(((row_num-1)/toint('{RowsPerPage}') + 1))\r\n| where page_num has ('{Page}')\r\n| project BackupItem = BackupInstanceId,BackupItemFriendlyName = BackupInstanceFriendlyName ,Vault = VaultResourceId,Subscription = VaultSubscriptionId, VaultLocation = VaultLocation,JobOperation = OperationCategory,JobStartTime = StartTime,JobDuration = tostring(todouble(DurationInSecs)/60/60),JobStatus = Status,FailureCode = ErrorTitle\r\n", + "size": 3, + "title": "List of jobs in period", + "noDataMessage": "No record found for the selected time and scope.", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspaces}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "BackupItem", + "formatter": 5 + }, + { + "columnMatch": "BackupItemFriendlyName", + "formatter": 16, + "formatOptions": { + "linkColumn": "BackupItem", + "linkTarget": "Resource", + "showIcon": true, + "customColumnWidthSetting": "10%" + } + }, + { + "columnMatch": "Vault", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "10%" + } + }, + { + "columnMatch": "Subscription", + "formatter": 15, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true, + "customColumnWidthSetting": "10%" + } + }, + { + "columnMatch": "VaultLocation", + "formatter": 17, + "formatOptions": { + "customColumnWidthSetting": "10%" + } + }, + { + "columnMatch": "JobOperation", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "10%" + } + }, + { + "columnMatch": "JobStartTime", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "10%" + } + }, + { + "columnMatch": "JobDuration", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "10%" + }, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal", + "minimumFractionDigits": 2, + "maximumFractionDigits": 2 + } + } + }, + { + "columnMatch": "JobStatus", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "contains", + "thresholdValue": "Warning", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "Failed", + "representation": "failed", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Blank", + "text": "{0}{1}" + } + ], + "customColumnWidthSetting": "10%" + } + }, + { + "columnMatch": "FailureCode", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "10%" + } + } + ], + "rowLimit": 1000, + "labelSettings": [ + { + "columnId": "BackupItemFriendlyName", + "label": "Backup instance" + }, + { + "columnId": "Vault", + "label": "Vault" + }, + { + "columnId": "Subscription", + "label": "Subscription" + }, + { + "columnId": "VaultLocation", + "label": "Location" + }, + { + "columnId": "JobOperation", + "label": "Job operation" + }, + { + "columnId": "JobStartTime", + "label": "Job start time (UTC)" + }, + { + "columnId": "JobDuration", + "label": "Job duration (hours)" + }, + { + "columnId": "JobStatus", + "label": "Job status" + }, + { + "columnId": "FailureCode", + "label": "Job failure code" + } + ] + }, + "sortBy": [] + }, + "customWidth": "100", + "conditionalVisibility": { + "parameterName": "Workspaces", + "comparison": "isNotEqualTo" + }, + "name": "Grid1", + "styleSettings": { + "margin": "5px", + "padding": "5px", + "showBorder": true + } + } + ] + }, + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "Backup" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Storage" + }, + { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + } + ], + "name": "RC_Storage" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "where type has \"microsoft.network\"\r\n| extend type = case(\r\n\ttype == 'microsoft.network/networkinterfaces', \"NICs\",\r\n\ttype == 'microsoft.network/networksecuritygroups', \"NSGs\", \r\n\ttype == \"microsoft.network/publicipaddresses\", \"Public IPs\", \r\n\ttype == 'microsoft.network/virtualnetworks', \"vNets\",\r\n\ttype == 'microsoft.network/networkwatchers/connectionmonitors', \"Connection Monitors\",\r\n\ttype == 'microsoft.network/privatednszones', \"Private DNS\",\r\n\ttype == 'microsoft.network/virtualnetworkgateways', @\"vNet Gateways\",\r\n\ttype == 'microsoft.network/connections', \"Connections\",\r\n\ttype == 'microsoft.network/networkwatchers', \"Network Watchers\",\r\n\ttype == 'microsoft.network/privateendpoints', \"Private Endpoints\",\r\n\ttype == 'microsoft.network/localnetworkgateways', \"Local Network Gateways\",\r\n\ttype == 'microsoft.network/privatednszones/virtualnetworklinks', \"vNet Links\",\r\n\ttype == 'microsoft.network/dnszones', 'DNS Zones',\r\n\ttype == 'microsoft.network/networkwatchers/flowlogs', 'Flow Logs',\r\n\ttype == 'microsoft.network/routetables', 'Route Tables',\r\n\ttype == 'microsoft.network/loadbalancers', 'Load Balancers',\r\n type =~ 'Microsoft.Network/applicationGateways', 'Application Gateways',\r\n\tstrcat(\"Not Translated: \", type))\r\n| summarize count() by type\r\n| where type !has \"Not Translated\"", + "size": 3, + "title": "Count of all network resources by resource type", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "type", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "name": "query - Network resource" + }, + { + "type": 1, + "content": { + "json": "# Network security group" + }, + "name": "Network security group title" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "7763ba7f-6187-4448-a94c-890392ed31d0", + "version": "KqlParameterItem/1.0", + "name": "OrphanNSG", + "label": "Orphaned", + "type": 10, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":\"and isnotnull(properties.networkInterfaces) or type =~ 'microsoft.network/networksecuritygroups' and isnotnull(properties.subnets)\", \"label\":\"No\" },\r\n { \"value\":\"and isnull(properties.networkInterfaces) and isnull(properties.subnets)\", \"label\":\"Yes\" }\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "and isnotnull(properties.networkInterfaces) or type =~ 'microsoft.network/networksecuritygroups' and isnotnull(properties.subnets)" + } + ], + "style": "above", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "NSG" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n| where type =~ 'microsoft.network/networksecuritygroups' {OrphanNSG}\r\n| project Resource=id, resourceGroup, subscriptionId, location", + "size": 0, + "title": "NSGs", + "noDataMessage": "No NSGs Found", + "noDataMessageStyle": 3, + "exportedParameters": [ + { + "fieldName": "Resource", + "parameterName": "SelectedResourceId", + "parameterType": 5 + } + ], + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "filter": true + }, + "sortBy": [] + }, + "name": "NSGs" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n | where type =~ 'microsoft.network/networksecuritygroups'\r\n | where id == \"{SelectedResourceId}\"\r\n | project id, nsgRules = parse_json(parse_json(properties).securityRules), networksecurityGroupName = name, subscriptionId, resourceGroup , location\r\n | mvexpand nsgRule = nsgRules\r\n | project id, location, access=nsgRule.properties.access,protocol=nsgRule.properties.protocol ,direction=nsgRule.properties.direction,provisioningState= nsgRule.properties.provisioningState ,priority=nsgRule.properties.priority, \r\n sourceAddressPrefix = nsgRule.properties.sourceAddressPrefix, \r\n sourceAddressPrefixes = nsgRule.properties.sourceAddressPrefixes,\r\n destinationAddressPrefix = nsgRule.properties.destinationAddressPrefix, \r\n destinationAddressPrefixes = nsgRule.properties.destinationAddressPrefixes, \r\n networksecurityGroupName, networksecurityRuleName = tostring(nsgRule.name), \r\n subscriptionId, resourceGroup,\r\n destinationPortRanges = nsgRule.properties.destinationPortRanges,\r\n destinationPortRange = nsgRule.properties.destinationPortRange,\r\n sourcePortRanges = nsgRule.properties.sourcePortRanges,\r\n sourcePortRange = nsgRule.properties.sourcePortRange\r\n| extend Details = pack_all()\r\n| project id, location, access, direction, priority, sourceAddressPrefix, sourcePortRange, destinationPortRange, subscriptionId, resourceGroup, Details", + "size": 1, + "title": "NSG rules", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 5 + }, + { + "columnMatch": "resourceGroup", + "formatter": 5 + }, + { + "columnMatch": "Details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "SelectedResourceId", + "comparison": "isNotEqualTo" + }, + "name": "NSG rules" + }, + { + "type": 1, + "content": { + "json": "# Public IPs" + }, + "name": "Public IP title" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "37cdc20d-07c3-466c-84bb-4d8050932641", + "version": "KqlParameterItem/1.0", + "name": "OrphanIPs", + "label": "Orphaned", + "type": 10, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":\"isnotnull\", \"label\":\"No\" },\r\n { \"value\":\"isnull\", \"label\":\"Yes\" }\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "isnotnull" + } + ], + "style": "above", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "Public IPs" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n| where type =~ 'Microsoft.Network/publicIPAddresses' and {OrphanIPs}(properties.ipAddress)\r\n| extend ipAddress = properties.ipAddress\r\n| extend sku = sku.name\r\n| extend Details = pack_all()\r\n| project Resource=id, subscriptionId, resourceGroup, name, location,sku,Details", + "size": 0, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "linkIsContextBlade": true, + "showIcon": true + } + }, + { + "columnMatch": "Resource", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + }, + { + "columnMatch": "Details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ], + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true, + "finalBy": "Resource" + } + } + }, + "name": "query - Networking Details - PiPs" + }, + { + "type": 1, + "content": { + "json": "# Application gateway" + }, + "name": "Application gateway title" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "007b8dbe-6bc6-40f9-b4bc-55f2ec14916c", + "version": "KqlParameterItem/1.0", + "name": "OrphanAppGW", + "label": "Orphaned", + "type": 10, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":\"//\", \"label\":\"No\" },\r\n { \"value\":\"|\", \"label\":\"Yes\" }\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "//" + } + ], + "style": "above", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "ApplicationGateway" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type =~ 'Microsoft.Network/applicationGateways'\r\n| extend backendPoolsCount = array_length(properties.backendAddressPools),SKUName= tostring(properties.sku.name), SKUTier= tostring(properties.sku.tier),SKUCapacity=properties.sku.capacity,backendPools=properties.backendAddressPools\r\n| project id, name, SKUName, SKUTier, SKUCapacity\r\n| join (\r\n resources\r\n | where type =~ 'Microsoft.Network/applicationGateways'\r\n | mvexpand backendPools = properties.backendAddressPools\r\n | extend backendIPCount = array_length(backendPools.properties.backendIPConfigurations)\r\n | extend backendAddressesCount = array_length(backendPools.properties.backendAddresses)\r\n | extend backendPoolName = backendPools.properties.backendAddressPools.name\r\n | summarize backendIPCount = sum(backendIPCount) ,backendAddressesCount=sum(backendAddressesCount) by id\r\n) on id\r\n| project-away id1\r\n{OrphanAppGW} where (backendIPCount == 0 or isempty(backendIPCount)) and (backendAddressesCount==0 or isempty(backendAddressesCount))\r\n| order by id asc", + "size": 0, + "noDataMessage": "No app gateways", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "name": "query - Application Gateways" + }, + { + "type": 1, + "content": { + "json": "# Load balancer" + }, + "name": "Load balancer title" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "8cffc283-1878-4035-a669-5d9697e9edc1", + "version": "KqlParameterItem/1.0", + "name": "OrphanLB", + "label": "Orphaned", + "type": 10, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":\"!=\", \"label\":\"No\" },\r\n { \"value\":\"==\", \"label\":\"Yes\" }\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "!=" + } + ], + "style": "above", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "LoadBalancers" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == \"microsoft.network/loadbalancers\"\r\n| where properties.backendAddressPools {OrphanLB} \"[]\"\r\n| extend Details = pack_all()\r\n| project Resource=id, subscriptionId, resourceGroup, location, tostring(sku.name), Details", + "size": 0, + "noDataMessage": "No load balancers", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "location", + "formatter": 17 + }, + { + "columnMatch": "Details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ], + "labelSettings": [ + { + "columnId": "Resource", + "label": "Resource Name" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + }, + { + "columnId": "resourceGroup", + "label": "Resource group" + }, + { + "columnId": "location", + "label": "Region" + }, + { + "columnId": "sku_name", + "label": "SKU" + } + ] + } + }, + "name": "query - Load Balancers" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Network" + }, + { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + } + ], + "name": "RC_Network" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Stay informed and act quickly on service issues\r\nAzure Service Health notifies you about Azure service incidents and planned maintenance so you can take action to mitigate downtime. Configure customisable cloud alerts and use your personalised dashboard to analyse health issues, monitor the impact to your cloud resources, get guidance and support, and share details and updates." + }, + "name": "text - 4" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "servicehealthresources\r\n| where type =~ 'Microsoft.ResourceHealth/events'\r\n| extend eventType = properties.EventType, status = properties.Status, description = properties.Title, trackingId = properties.TrackingId, summary = properties.Summary, priority = properties.Priority, impactStartTime = properties.ImpactStartTime, impactMitigationTime = properties.ImpactMitigationTime\r\n| where properties.Status == 'Active' and tolong(impactStartTime) > 1\r\n\r\n| extend Details = pack_all()\r\n| project ServiceHealthID=id, Description=description, Region=location, eventType, Status=status, Details", + "size": 1, + "title": "All active Service Health events", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "ServiceHealthID", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": false, + "customColumnWidthSetting": "20ch" + } + }, + { + "columnMatch": "Description", + "formatter": 1, + "formatOptions": { + "customColumnWidthSetting": "60ch" + } + }, + { + "columnMatch": "eventType", + "formatter": 1 + }, + { + "columnMatch": "Status", + "formatter": 1 + }, + { + "columnMatch": "Details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ] + }, + "tileSettings": { + "showBorder": false + } + }, + "name": "query - 15" + }, + { + "type": 1, + "content": { + "json": "## Activity log monitoring" + }, + "name": "text - 15" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resourcechanges\r\n| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),\r\nchangeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId, \r\nchangedProperties = properties.changes, changeCount = properties.changeAttributes.changesCount\r\n| where changeTime > ago(1d)\r\n| order by changeTime desc\r\n| project changeTime, targetResourceId, changeType, correlationId, changeCount, changedProperties", + "size": 0, + "title": "All changes in the past one day", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "changeTime", + "formatter": 6, + "formatOptions": { + "customColumnWidthSetting": "24ch" + } + }, + { + "columnMatch": "targetResourceId", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "42.7143ch" + } + }, + { + "columnMatch": "changedProperties", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ] + } + }, + "name": "query - 12" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resourcechanges\r\n| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),\r\nchangeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId\r\n| where changeType == \"Delete\"\r\n| order by changeTime desc\r\n| project changeTime, resourceGroup, targetResourceId, changeType, correlationId", + "size": 0, + "title": "Resources deleted", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "changeTime", + "formatter": 6 + } + ] + } + }, + "name": "query - 13" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Monitoring" + }, + { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + } + ], + "name": "RC_Monitoring" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Use tags to organize your Azure resources and management hierarchy\r\nTags are metadata elements that you apply to your Azure resources. They're key-value pairs that help you identify resources based on settings that are relevant to your organization. If you want to track the deployment environment for your resources, add a key named Environment. To identify the resources deployed to production, give them a value of Production. The fully formed key-value pair is Environment = Production.\r\n\r\nTo get more information about tags, see [Resource naming and tagging decision guide](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming-and-tagging-decision-guide?toc=%2Fazure%2Fazure-resource-manager%2Fmanagement%2Ftoc.json)" + }, + "name": "text - 9" + }, + { + "type": 1, + "content": { + "json": "Tag names with spaces, hyphens, and underscores are not supported.", + "style": "info" + }, + "name": "warning tag explorer" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "bae67738-90ef-4698-9020-5e1f91d67f82", + "version": "KqlParameterItem/1.0", + "name": "TagName", + "label": "Tag name", + "type": 2, + "isRequired": true, + "query": "Resources\r\n| where tags != '' and tags != '[]'\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| distinct tagName\r\n| sort by tagName asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null + } + ], + "style": "formVertical", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "33", + "name": "parameters - 0" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "cb0ae78d-a49b-457b-baed-d83c97a2c934", + "version": "KqlParameterItem/1.0", + "name": "TagValue", + "label": "Tag value", + "type": 2, + "query": "Resources\r\n| extend TagValue = tostring(tags.{TagName})\r\n| project TagValue\r\n| distinct TagValue", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + } + ], + "style": "formVertical", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "33", + "conditionalVisibility": { + "parameterName": "TagName", + "comparison": "isNotEqualTo" + }, + "name": "parameters - 2" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "81756016-e942-4fa0-976e-06d8ce919f83", + "version": "KqlParameterItem/1.0", + "name": "ResourceType", + "label": "Resource type", + "type": 7, + "typeSettings": { + "additionalResourceOptions": [], + "includeAll": true, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": null + } + ], + "style": "formVertical", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "33", + "conditionalVisibility": { + "parameterName": "TagName", + "comparison": "isNotEqualTo" + }, + "name": "ResourceType" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n| extend tag = tags.{TagName}\r\n| mv-expand bagexpansion=array tags\r\n| where isnotempty(tags)\r\n//| where tags[0] =~ '{TagName}' and tags[1] =~ '{TagValue}'\r\n| where tags[0] == '{TagName}' and tags[1] == '{TagValue}'\r\n| where type contains '{ResourceType}'\r\n| project id, tag", + "size": 0, + "title": "Resource with tag", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "filter": true, + "labelSettings": [ + { + "columnId": "id", + "label": "Resource name" + }, + { + "columnId": "tag", + "label": "Tag value" + } + ] + } + }, + "customWidth": "50", + "conditionalVisibility": { + "parameterName": "TagName", + "comparison": "isNotEqualTo" + }, + "name": "query - Resource with tag" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n| extend tag = tags.{TagName}\r\n| mv-expand bagexpansion=array tags\r\n| where isnotempty(tags)\r\n| where tags[0] == '{TagName}' and tags[1] == ''\r\n| where type contains '{ResourceType}'\r\n| project id, tag", + "size": 0, + "title": "Tag with empty value", + "noDataMessage": "No tagged resources with empty value found", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "filter": true, + "labelSettings": [ + { + "columnId": "id", + "label": "Resource name" + }, + { + "columnId": "tag", + "label": "Tag value" + } + ] + } + }, + "customWidth": "50", + "conditionalVisibility": { + "parameterName": "TagName", + "comparison": "isNotEqualTo" + }, + "name": "query - Empty value" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where tags =~ '' or tags =~ '{}'\r\n| where type contains '{ResourceType}'\r\n| project Name=id", + "size": 0, + "title": "Untagged resources", + "noDataMessage": "No untagged resources found", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "rowLimit": 100, + "filter": true, + "labelSettings": [ + { + "columnId": "Name", + "label": "Resource name" + } + ] + } + }, + "name": "query - Untagged resources" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resourcecontainers\r\n| where type == \"microsoft.resources/subscriptions\"\r\n| extend tag = tags.{TagName}\r\n| mv-expand bagexpansion=array tags\r\n| where isnotempty(tags)\r\n| where tags[0] == '{TagName}' and tags[1] == '{TagValue}'\r\n| project id, tag", + "size": 0, + "title": "Subscription list", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "tag", + "formatter": 1 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Subscription" + }, + { + "columnId": "tag", + "label": "Tag value" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "TagName", + "comparison": "isNotEqualTo" + }, + "name": "query - Subscription list" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resourcecontainers\r\n| where type == \"microsoft.resources/subscriptions/resourcegroups\"\r\n| extend tag = tags.{TagName}\r\n| mv-expand bagexpansion=array tags\r\n| where isnotempty(tags)\r\n| where tags[0] == '{TagName}' and tags[1] == '{TagValue}'\r\n| project id, tag", + "size": 0, + "title": "Resource groups list", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "tag", + "formatter": 1 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Subscription" + }, + { + "columnId": "tag", + "label": "Tag value" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "TagName", + "comparison": "isNotEqualTo" + }, + "name": "query - ResourceGroup list" + } + ] + }, + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "group - TagQueries" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Tag" + }, + "name": "RC_Tags" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources\r\n| where type == \"microsoft.security/securescores\"\r\n| extend subscriptionSecureScore = round(100 * bin((todouble(properties.score.current))/ todouble(properties.score.max), 0.001))\r\n| where subscriptionSecureScore > 0\r\n| project subscriptionId, subscriptionSecureScore\r\n| order by subscriptionSecureScore asc", + "size": 0, + "title": "Security Scores by Subscription", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true, + "customColumnWidthSetting": "65ch" + } + }, + { + "columnMatch": "subscriptionSecureScore", + "formatter": 8, + "formatOptions": { + "min": 0, + "max": 100, + "palette": "redGreen", + "customColumnWidthSetting": "55ch" + }, + "numberFormat": { + "unit": 1, + "options": { + "style": "decimal", + "useGrouping": false + } + } + } + ], + "labelSettings": [ + { + "columnId": "subscriptionId", + "label": "Subscription Name" + }, + { + "columnId": "subscriptionSecureScore", + "label": "Subscription Secure Score" + } + ] + } + }, + "name": "query - Monitor & Security - Security Scores" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "SecurityResources \r\n| where type == 'microsoft.security/securescores/securescorecontrols' \r\n| extend SecureControl = properties.displayName, unhealthy = properties.unhealthyResourceCount, currentscore = properties.score.current, maxscore = properties.score.max, subscriptionId, details = properties\r\n| project SecureControl , unhealthy, currentscore, maxscore, subscriptionId, details", + "size": 0, + "title": "Security Scores by Control", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": true, + "customColumnWidthSetting": "65ch" + } + }, + { + "columnMatch": "Subscription", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": true, + "customColumnWidthSetting": "65ch" + } + }, + { + "columnMatch": "SecureControl", + "formatter": 5, + "tooltipFormat": {} + }, + { + "columnMatch": "unhealthy", + "formatter": 8, + "formatOptions": { + "min": 0, + "palette": "greenRed", + "customColumnWidthSetting": "20ch" + } + }, + { + "columnMatch": "currentscore", + "formatter": 8, + "formatOptions": { + "palette": "redGreen", + "customColumnWidthSetting": "20ch" + }, + "numberFormat": { + "unit": 1, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "maxscore", + "formatter": 8, + "formatOptions": { + "palette": "blue", + "customColumnWidthSetting": "20ch" + }, + "numberFormat": { + "unit": 1, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + }, + { + "columnMatch": "details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "Details", + "linkIsContextBlade": true + } + }, + { + "columnMatch": "subscriptionSecureScore", + "formatter": 8, + "formatOptions": { + "min": 0, + "max": 100, + "palette": "redGreen", + "customColumnWidthSetting": "20" + }, + "numberFormat": { + "unit": 1, + "options": { + "style": "decimal", + "useGrouping": false + } + } + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true, + "finalBy": "SecureControl" + }, + "labelSettings": [ + { + "columnId": "unhealthy", + "label": "Unhealthy" + }, + { + "columnId": "currentscore", + "label": "Current Score" + }, + { + "columnId": "maxscore", + "label": "Max Score" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + } + ] + } + }, + "name": "query - Monitor & Security - Security Scores by Control" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "4f93ebba-a9d5-4e11-8de4-b605c2b4368f", + "version": "KqlParameterItem/1.0", + "name": "ResourceIdFilter", + "type": 1, + "isGlobal": true, + "isHiddenWhenLocked": true, + "label": "Resource ID" + }, + { + "id": "e505498f-d2eb-4dd6-928f-0f0f0e9cc371", + "version": "KqlParameterItem/1.0", + "name": "AlertDisplayNameFilter", + "type": 1, + "isGlobal": true, + "isHiddenWhenLocked": true, + "label": "Alert display name" + }, + { + "id": "39e382f9-4780-40fa-8595-15eda0f08ad4", + "version": "KqlParameterItem/1.0", + "name": "NewAlertFilter", + "type": 1, + "isGlobal": true, + "isHiddenWhenLocked": true, + "label": "New alert" + } + ], + "style": "above", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - 15" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": " securityresources\r\n | where type =~ 'microsoft.security/locations/alerts'\r\n | where properties.Status in ('Active')\r\n | where properties.Severity in ('Low', 'Medium', 'High')\r\n | extend SeverityRank = case(\r\n properties.Severity == 'High', 3,\r\n properties.Severity == 'Medium', 2,\r\n properties.Severity == 'Low', 1,\r\n 0\r\n )\r\n | project-away SeverityRank\r\n | extend Severity = properties.Severity\r\n | project Severity = tostring(Severity)\r\n | summarize Count = count() by Severity", + "size": 0, + "title": "Severity ", + "exportedParameters": [ + { + "fieldName": "Subscription", + "parameterName": "Subscription", + "parameterType": 1 + }, + { + "fieldName": "Severity", + "parameterName": "SeverityFilter", + "parameterType": 1 + } + ], + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Severity", + "formatter": 1 + } + ] + }, + "chartSettings": { + "yAxis": [ + "Count" + ], + "seriesLabelSettings": [ + { + "seriesName": "Medium", + "color": "orange" + }, + { + "seriesName": "High", + "color": "redDark" + }, + { + "seriesName": "Low", + "color": "yellow" + } + ] + } + }, + "customWidth": "33", + "name": "Severity" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": " securityresources\r\n | where type =~ 'microsoft.security/locations/alerts'\r\n | summarize Count =count() by resourceGroup", + "size": 0, + "title": "Resource Group", + "exportFieldName": "resourceGroup", + "exportParameterName": "resourceGroupFilter", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart" + }, + "customWidth": "33", + "name": "query - 9" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n | project id = tolower(id), tags\r\n | join kind=inner (securityresources\r\n | where type =~ \"microsoft.security/locations/alerts\"\r\n | extend isAzure = tostring(properties.ResourceIdentifiers) matches regex '\"Type\"\\\\s*:\\\\s*\"AzureResource\"'\r\n | extend affectedResourceId = extract('\"AzureResourceId\"\\\\s*:\\\\s*\"([^\"]*)\"', 1, tostring(properties.ResourceIdentifiers))\r\n | extend hostName = iff(isAzure, \"\", extract('\"HostName\"\\\\s*:\\\\s*\"([^\"]*)\"', 1, tostring(properties.Entities)))\r\n | extend splitAffectedResourceId = split(affectedResourceId, \"/\")\r\n | extend resourceNameIndex = iff(array_length(splitAffectedResourceId) > 1, array_length(splitAffectedResourceId) - 1, 0)\r\n | extend affectedResourceName = iff(isAzure, splitAffectedResourceId[resourceNameIndex], iff(isempty(hostName), \"Non-Azure\", hostName))| project-away resourceNameIndex, splitAffectedResourceId, hostName, isAzure\r\n | project alertId = id, subscriptionId, alertProperties = properties, affectedResourceId = tolower(affectedResourceId)\r\n ) on $left.id == $right.affectedResourceId\r\n | extend id = alertId, subscriptionId, properties = alertProperties\r\n | where properties.Status in ('Active')\r\n | where properties.Severity in ('Low', 'Medium', 'High')\r\n | extend SeverityRank = case(\r\n properties.Severity == 'High', 3,\r\n properties.Severity == 'Medium', 2,\r\n properties.Severity == 'Low', 1,\r\n 0\r\n )\r\n | sort by SeverityRank desc, tostring(properties.SystemAlertId) asc\r\n | extend Tag = parse_json(tags)\r\n | mv-expand Tag\r\n | parse Tag with * ':\"' TagValue '\"}'\r\n | project TagValue, alertId\r\n | summarize Count = count() by TagValue", + "size": 0, + "title": "Tag", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart" + }, + "customWidth": "30", + "name": "query - 7", + "styleSettings": { + "maxWidth": "100%" + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "datatable(ResourceId: string) [ \"All\"] | union (securityresources\r\n | where type =~ 'microsoft.security/locations/alerts'\r\n | extend Prop = parse_json(properties)\r\n | where Prop.Severity == \"High\"\r\n | extend ResourceIdentifiers = Prop.[\"ResourceIdentifiers\"]\r\n | project ResourceIdentifiers\r\n | mv-expand ResourceIdentifiers\r\n | extend ResourceId = parse_json(ResourceIdentifiers).[\"AzureResourceId\"]\r\n | where isnotempty(ResourceId )\r\n| summarize Count=count() by tostring(ResourceId)\r\n | top 5 by Count)", + "size": 1, + "title": "Top 5 attacked resources (with High Severity)", + "noDataMessage": "There are no Top 5 attacked resources found", + "exportedParameters": [ + { + "fieldName": "ResourceId", + "parameterName": "ResourceIdFilter", + "defaultValue": "All" + }, + { + "fieldName": "ResourceId", + "parameterName": "ShowTable", + "parameterType": 1 + } + ], + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Resource ID", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "sortBy": [ + { + "itemKey": "Count", + "sortOrder": 2 + } + ], + "labelSettings": [ + { + "columnId": "ResourceId", + "label": "Resource ID" + } + ] + }, + "sortBy": [ + { + "itemKey": "Count", + "sortOrder": 2 + } + ] + }, + "customWidth": "33", + "name": "Top 5 attacked resources (with High Severity)" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": " datatable(AlertDisplayName: string) [ \"All\"] | union(securityresources\r\n | where type =~ 'microsoft.security/locations/alerts'\r\n | extend Prop = parse_json(properties)\r\n | extend AlertDisplayName = Prop.[\"AlertDisplayName\"]\r\n | project tostring(AlertDisplayName)\r\n | summarize Count = count() by AlertDisplayName\r\n | top 5 by Count)", + "size": 1, + "title": "Top alert types ", + "exportedParameters": [ + { + "fieldName": "AlertDisplayName", + "parameterName": "AlertDisplayNameFilter", + "defaultValue": "All" + }, + { + "fieldName": "AlertDisplayName", + "parameterName": "ShowTable", + "parameterType": 1 + } + ], + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "sortBy": [ + { + "itemKey": "Count", + "sortOrder": 2 + } + ], + "labelSettings": [ + { + "columnId": "AlertDisplayName", + "label": "Alert display name" + } + ] + }, + "sortBy": [ + { + "itemKey": "Count", + "sortOrder": 2 + } + ] + }, + "customWidth": "33", + "name": "Top alert types" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": " datatable(AlertDisplayName: string) [ \"All\"] | union(securityresources\r\n| where type =~ 'microsoft.security/locations/alerts'\r\n| extend Prop = parse_json(properties)\r\n| extend TimeGeneratedUtc = Prop.[\"TimeGeneratedUtc\"]\r\n| extend AlertDisplayName = Prop.[\"AlertDisplayName\"]\r\n| where TimeGeneratedUtc > ago(24h)\r\n| summarize Count=count() by tostring(AlertDisplayName))", + "size": 1, + "title": "New Alerts (Since last 24hrs)", + "noDataMessage": "No new alerts in Last 24 hours", + "noDataMessageStyle": 3, + "exportedParameters": [ + { + "fieldName": "AlertDisplayName", + "parameterName": "NewAlertFilter", + "defaultValue": "All" + }, + { + "fieldName": "AlertDisplayName", + "parameterName": "ShowTable", + "parameterType": 1 + } + ], + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "ClearOther", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "AlertDisplayName", + "label": "Alert display name" + } + ] + }, + "sortBy": [] + }, + "customWidth": "33", + "name": "New Alerts (Since last 24hrs)" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "", + "size": 0, + "title": "Parameters at this point", + "queryType": 2 + }, + "conditionalVisibility": { + "parameterName": "parameter1", + "comparison": "isEqualTo", + "value": "1" + }, + "name": "query - 23" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources\r\n| where type == \"microsoft.security/locations/alerts\"\r\n| project-rename P= properties\r\n| extend Details = parse_json(P)\r\n| extend IsIncident = Details.[\"IsIncident\"]\r\n| extend AlertDisplayName = Details.[\"AlertDisplayName\"]\r\n| extend SystemAlertId = Details.[\"SystemAlertId\"]\r\n| extend Severity = tostring(Details.[\"Severity\"])\r\n| where Severity == \"High\"\r\n| extend AlertUri = Details.[\"AlertUri\"]\r\n| extend Status = tostring(Details.[\"Status\"])\r\n| extend Tactics = tostring(Details.[\"Intent\"])\r\n| extend ResourceIdentifiers = Details.[\"ResourceIdentifiers\"]\r\n| mv-expand ResourceIdentifiers\r\n| extend ResourceId = parse_json(ResourceIdentifiers).[\"AzureResourceId\"]\r\n| where Status == \"Active\"\r\n| where (\"{ResourceIdFilter}\" == \"All\" or ResourceId == \"{ResourceIdFilter}\") \r\n // if either alert name or new alert are set, union those 2 together, if neither are set treat as all\r\n and ((\"{AlertDisplayNameFilter}\" == \"All\" and \"{NewAlertFilter}\" == \"All\") or AlertDisplayName == \"{AlertDisplayNameFilter}\" or AlertDisplayName == \"{NewAlertFilter}\")\r\n| extend SeverityRank = case(\r\n Severity == 'High', 3,\r\n Severity == 'Medium', 2,\r\n Severity == 'Low', 1,\r\n 0\r\n )\r\n| parse AlertUri with * '/subscriptionId/' SubscriptionId '/' *\r\n| parse AlertUri with * '/resourceGroup/' ResourceGroup '/' *\r\n| parse AlertUri with * '/location/' Location \r\n| project\r\n Severity,\r\n SystemAlertId,\r\n AlertDisplayName,\r\n IsIncident = iif(IsIncident == \"true\", \"Incident\", \"Alert\"),\r\n AlertUri,\r\n Tactics,\r\n SeverityRank,\r\n SubscriptionId,\r\n ResourceGroup,\r\n Location,\r\n ResourceId\r\n| sort by SeverityRank", + "size": 0, + "title": "{$rowCount} Active Alerts ", + "exportedParameters": [ + { + "fieldName": "ResourceId", + "parameterName": "Resource", + "parameterType": 1 + }, + { + "fieldName": "AlertUri", + "parameterName": "AlertUri", + "parameterType": 1 + }, + { + "fieldName": "SystemAlertId", + "parameterName": "SystemAlertId", + "parameterType": 1 + }, + { + "fieldName": "SubscriptionId", + "parameterName": "SubscriptionId", + "parameterType": 1 + }, + { + "fieldName": "ResourceGroup", + "parameterName": "ResourceGroup", + "parameterType": 1 + }, + { + "fieldName": "Location", + "parameterName": "Location", + "parameterType": 1 + } + ], + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Severity", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "contains", + "thresholdValue": "High", + "representation": "redBright", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "Medium", + "representation": "orange", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "Low", + "representation": "yellow", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "Informational ", + "representation": "gray", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": null, + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "SystemAlertId", + "formatter": 5 + }, + { + "columnMatch": "AlertDisplayName", + "formatter": 1, + "formatOptions": { + "linkTarget": "OpenBlade", + "bladeOpenContext": { + "bladeName": "AlertBlade", + "extensionName": "Microsoft_Azure_Security", + "bladeParameters": [ + { + "name": "alertId", + "source": "column", + "value": "SystemAlertId" + }, + { + "name": "subscriptionId", + "source": "column", + "value": "SubscriptionId" + }, + { + "name": "resourceGroup", + "source": "column", + "value": "ResourceGroup" + }, + { + "name": "referencedFrom", + "source": "static", + "value": "activeAlertsWorkbook" + }, + { + "name": "location", + "source": "column", + "value": "Location" + } + ] + } + } + }, + { + "columnMatch": "IsIncident", + "formatter": 1 + }, + { + "columnMatch": "AlertUri", + "formatter": 5 + }, + { + "columnMatch": "Tactics", + "formatter": 1 + }, + { + "columnMatch": "SubscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Location", + "formatter": 17 + }, + { + "columnMatch": "ResourceId", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "TenantId", + "formatter": 5 + }, + { + "columnMatch": "AlertName", + "formatter": 5 + }, + { + "columnMatch": "Description", + "formatter": 5 + }, + { + "columnMatch": "ProviderName", + "formatter": 5 + }, + { + "columnMatch": "VendorName", + "formatter": 5 + }, + { + "columnMatch": "VendorOriginalId", + "formatter": 5 + }, + { + "columnMatch": "SourceComputerId", + "formatter": 5 + }, + { + "columnMatch": "AlertType", + "formatter": 5 + }, + { + "columnMatch": "ConfidenceLevel", + "formatter": 5 + }, + { + "columnMatch": "ConfidenceScore", + "formatter": 5 + }, + { + "columnMatch": "StartTime", + "formatter": 5 + }, + { + "columnMatch": "EndTime", + "formatter": 5 + }, + { + "columnMatch": "ProcessingEndTime", + "formatter": 5 + }, + { + "columnMatch": "RemediationSteps", + "formatter": 5 + }, + { + "columnMatch": "ExtendedProperties", + "formatter": 5 + }, + { + "columnMatch": "Entities", + "formatter": 5 + }, + { + "columnMatch": "SourceSystem", + "formatter": 5 + }, + { + "columnMatch": "WorkspaceSubscriptionId", + "formatter": 5 + }, + { + "columnMatch": "WorkspaceResourceGroup", + "formatter": 5 + }, + { + "columnMatch": "ExtendedLinks", + "formatter": 5 + }, + { + "columnMatch": "ProductName", + "formatter": 5 + }, + { + "columnMatch": "ProductComponentName", + "formatter": 5 + }, + { + "columnMatch": "AlertLink", + "formatter": 7, + "formatOptions": { + "linkTarget": "Url" + } + }, + { + "columnMatch": "SystemIncidentId", + "formatter": 5 + }, + { + "columnMatch": "SystemAlertId1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "SystemAlertId", + "label": "Alert ID" + }, + { + "columnId": "AlertDisplayName", + "label": "Alert name" + }, + { + "columnId": "IsIncident", + "label": "Incident/alert" + }, + { + "columnId": "SeverityRank", + "label": "Severity" + }, + { + "columnId": "SubscriptionId", + "label": "Subscription" + }, + { + "columnId": "ResourceGroup", + "label": "Resource group" + }, + { + "columnId": "ResourceId", + "label": "Resource" + } + ] + }, + "sortBy": [] + }, + "conditionalVisibility": { + "parameterName": "ShowTable", + "comparison": "isNotEqualTo" + }, + "showPin": true, + "name": "SecurityIncidents - FilterbyResourceId", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "list", + "links": [ + { + "id": "2f6ff56b-9afb-46f6-968d-a59cb744ea14", + "linkTarget": "OpenBlade", + "linkLabel": "Open Alert View", + "style": "primary", + "bladeOpenContext": { + "bladeName": "AlertBlade", + "extensionName": "Microsoft_Azure_Security", + "bladeParameters": [ + { + "name": "alertId", + "source": "static", + "value": "{SystemAlertId}" + }, + { + "name": "subscriptionId", + "source": "static", + "value": "{SubscriptionId}" + }, + { + "name": "resourceGroup", + "source": "static", + "value": "{ResourceGroup}" + }, + { + "name": "referencedFrom", + "source": "static", + "value": "activeAlertsWorkbook" + }, + { + "name": "location", + "source": "static", + "value": "{Location}" + } + ] + } + } + ] + }, + "conditionalVisibility": { + "parameterName": "SystemAlertId", + "comparison": "isNotEqualTo" + }, + "name": "Alerts " + }, + { + "type": 1, + "content": { + "json": "### MITRE ATT&CK tactics                                 " + }, + "customWidth": "100", + "name": "text - 17" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources\r\n| where type == \"microsoft.security/locations/alerts\"\r\n| extend Details = parse_json(properties)\r\n| extend Tactics = Details.[\"Intent\"]\r\n| project Tactics\r\n| extend Tactic = split(Tactics,\",\")\r\n| mv-expand Tactic\r\n| extend Tactic = trim(\" \",tostring(Tactic))\r\n| summarize Count = count() by Tactic\r\n| sort by Count desc\r\n", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "barchart", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "Tactics", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "Tactics", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "count_", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "mapSettings": { + "locInfo": "LatLong", + "sizeSettings": "count_", + "sizeAggregation": "Sum", + "legendMetric": "count_", + "legendAggregation": "Sum", + "itemColorSettings": { + "type": "heatmap", + "colorAggregation": "Sum", + "nodeColorField": "count_", + "heatmapPalette": "greenRed" + } + } + }, + "name": "query - 17" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "bd374a50-b240-4232-ad4a-77725f80bcf5", + "cellValue": "View", + "linkTarget": "parameter", + "linkLabel": "List View", + "subTarget": "List", + "preText": "", + "style": "link" + }, + { + "id": "588b7d9f-8ff1-4afa-8d3f-b0085ae6b148", + "cellValue": "View", + "linkTarget": "parameter", + "linkLabel": "Map View", + "subTarget": "Map", + "preText": "", + "style": "link" + } + ] + }, + "name": "links - 10" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "1ffc8fe9-a919-4c9e-8489-a92f0a7d79e1", + "version": "KqlParameterItem/1.0", + "name": "ResourceFilter", + "label": "Resource", + "type": 5, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "securityresources\r\n | where type =~ 'microsoft.security/locations/alerts'\r\n | extend Prop = parse_json(properties)\r\n | extend ResourceIdentifiers = Prop.[\"ResourceIdentifiers\"]\r\n | project ResourceIdentifiers\r\n | mv-expand ResourceIdentifiers\r\n | extend ResourceId = parse_json(ResourceIdentifiers).[\"AzureResourceId\"]\r\n //| where isnotempty(ResourceId )\r\n | extend Resource = tolower(tostring(ResourceId))\r\n | summarize count() by Resource\r\n | project Resource\r\n //| order by Resource asc\r\n", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": [ + "value::all" + ] + }, + { + "id": "e9522d87-143f-408b-93ea-b8f07223995e", + "version": "KqlParameterItem/1.0", + "name": "SeverityFilter", + "label": "Severity", + "type": 2, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "value": [ + "value::all" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "jsonData": "[\r\n\r\n{\"value\": \"High\", \"label\":\"High\"},\r\n{\"value\": \"Medium\", \"label\":\"Medium\"},\r\n{\"value\": \"Low\", \"label\":\"Low\"},\r\n{\"value\": \"Informational\", \"label\":\"Informational\"}\r\n]\r\n \r\n ", + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all" + }, + { + "id": "664365b5-1fc4-4cfa-b99d-a72e3d35ab11", + "version": "KqlParameterItem/1.0", + "name": "ResourceGroupFilter", + "label": "Resource group", + "type": 2, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": " securityresources\r\n | where type =~ 'microsoft.security/locations/alerts'\r\n | extend resourceGroup = iif(isempty(resourceGroup),\" \",resourceGroup)\r\n| summarize Count =count() by resourceGroup\r\n | project resourceGroup", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": [ + "value::all" + ] + }, + { + "id": "48a8dd7e-43ab-413e-88f8-a433100d92ce", + "version": "KqlParameterItem/1.0", + "name": "AlertNameFilter", + "label": "Alert name", + "type": 2, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": " securityresources\r\n | where type =~ 'microsoft.security/locations/alerts'\r\n | extend Prop = parse_json(properties)\r\n | extend AlertDisplayName = Prop.[\"AlertDisplayName\"]\r\n | distinct tostring(AlertDisplayName)\r\n | order by AlertDisplayName asc\r\n ", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "378aeb0c-9135-43fa-b46a-86f71baa0137", + "version": "KqlParameterItem/1.0", + "name": "TagFilter", + "label": "Tag", + "type": 2, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "securityresources\r\n | where type =~ \"microsoft.security/locations/alerts\"\r\n | extend isAzure = tostring(properties.ResourceIdentifiers) matches regex '\"Type\"\\\\s*:\\\\s*\"AzureResource\"'\r\n | extend Details = parse_json(properties)\r\n| extend IsIncident = Details.[\"IsIncident\"]\r\n| extend AlertDisplayName = Details.[\"AlertDisplayName\"]\r\n| extend SystemAlertId = Details.[\"SystemAlertId\"]\r\n| extend Severity = Details.[\"Severity\"]\r\n| extend AlertUri = Details.[\"AlertUri\"]\r\n| extend Status = Details.[\"Status\"]\r\n| extend Tactics = Details.[\"Intent\"]\r\n| parse AlertUri with * '/subscriptionId/' SubscriptionId '/' *\r\n| parse AlertUri with * '/resourceGroup/' ResourceGroup '/' *\r\n| parse AlertUri with * '/location/' Location \r\n | extend affectedResourceId = extract('\"AzureResourceId\"\\\\s*:\\\\s*\"([^\"]*)\"', 1, tostring(properties.ResourceIdentifiers))\r\n | extend hostName = iff(isAzure, \"\", extract('\"HostName\"\\\\s*:\\\\s*\"([^\"]*)\"', 1, tostring(properties.Entities)))\r\n | extend splitAffectedResourceId = split(affectedResourceId, \"/\")\r\n | extend resourceNameIndex = iff(array_length(splitAffectedResourceId) > 1, array_length(splitAffectedResourceId) - 1, 0)\r\n | extend affectedResourceName = iff(isAzure, splitAffectedResourceId[resourceNameIndex], iff(isempty(hostName), \"Non-Azure\", hostName))| project-away resourceNameIndex, splitAffectedResourceId, hostName\r\n | extend ResourceIdentifiers = Details.[\"ResourceIdentifiers\"]\r\n | mv-expand ResourceIdentifiers\r\n | extend ResourceId = parse_json(ResourceIdentifiers).[\"AzureResourceId\"]\r\n | extend Resource = tolower(tostring(ResourceId))\r\n | project alertId = id, subscriptionId, alertProperties = properties, affectedResourceId = tolower(affectedResourceId),tostring(Severity), SystemAlertId, AlertDisplayName,IsIncident = iif(IsIncident==\"true\",\"Incident\",\"Alert\"),AlertUri,Status,Tactics,SubscriptionId,ResourceGroup,Location, ResourceIdentifier=Details.[\"ResourceIdentifiers\"],Resource\r\n | join kind=leftouter (\r\n resources\r\n | project id = tolower(id), tags\r\n ) on $left.affectedResourceId == $right.id\r\n | extend Tag = parse_json(tags)\r\n | mv-expand Tag\r\n | parse Tag with * ':\"' TagValue '\"}'\r\n | extend TagValue = iif(isempty(TagValue),\" \",TagValue)\r\n | project TagValue, alertId\r\n | distinct TagValue\r\n ", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "conditionalVisibility": { + "parameterName": "View", + "comparison": "isEqualTo", + "value": "List" + }, + "name": "parameters - 23" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources\r\n| where type =~ \"microsoft.security/locations/alerts\"\r\n| extend isAzure = tostring(properties.ResourceIdentifiers) matches regex '\"Type\"\\\\s*:\\\\s*\"AzureResource\"'\r\n| extend Details = parse_json(properties)\r\n| extend IsIncident = Details.[\"IsIncident\"]\r\n| extend AlertDisplayName = Details.[\"AlertDisplayName\"]\r\n| extend SystemAlertId = Details.[\"SystemAlertId\"]\r\n| extend Severity = Details.[\"Severity\"]\r\n| extend AlertUri = Details.[\"AlertUri\"]\r\n| extend Status = Details.[\"Status\"]\r\n| extend Tactics = Details.[\"Intent\"]\r\n| parse AlertUri with * '/subscriptionId/' SubscriptionId '/' *\r\n| parse AlertUri with * '/resourceGroup/' ResourceGroup '/' *\r\n| parse AlertUri with * '/location/' Location \r\n| extend affectedResourceId = extract('\"AzureResourceId\"\\\\s*:\\\\s*\"([^\"]*)\"', 1, tostring(properties.ResourceIdentifiers))\r\n| extend hostName = iff(isAzure, \"\", extract('\"HostName\"\\\\s*:\\\\s*\"([^\"]*)\"', 1, tostring(properties.Entities)))\r\n| extend splitAffectedResourceId = split(affectedResourceId, \"/\")\r\n| extend resourceNameIndex = iff(array_length(splitAffectedResourceId) > 1, array_length(splitAffectedResourceId) - 1, 0)\r\n| extend affectedResourceName = iff(isAzure, splitAffectedResourceId[resourceNameIndex], iff(isempty(hostName), \"Non-Azure\", hostName))\r\n| project-away resourceNameIndex, splitAffectedResourceId, hostName\r\n| extend ResourceIdentifiers = Details.[\"ResourceIdentifiers\"]\r\n| mv-expand ResourceIdentifiers\r\n| extend ResourceId = parse_json(ResourceIdentifiers).[\"AzureResourceId\"]\r\n| extend Resource = tolower(tostring(ResourceId))\r\n| project\r\n alertId = id,\r\n subscriptionId,\r\n alertProperties = properties,\r\n affectedResourceId = tolower(affectedResourceId),\r\n tostring(Severity),\r\n SystemAlertId,\r\n AlertDisplayName,\r\n IsIncident = iif(IsIncident == \"true\", \"Incident\", \"Alert\"),\r\n AlertUri,\r\n Status,\r\n Tactics,\r\n SubscriptionId,\r\n ResourceGroup,\r\n Location,\r\n ResourceId,\r\n ResourceIdentifier=Details.[\"ResourceIdentifiers\"],\r\n Resource\r\n| join kind=leftouter (\r\n resources\r\n | project id = tolower(id), tags\r\n )\r\n on $left.affectedResourceId == $right.id\r\n| extend id = alertId, subscriptionId, properties = alertProperties\r\n| extend ResourceFilter =\" {ResourceFilter}\"\r\n| where Resource in~ ({ResourceFilter})\r\n| where Severity in~ ({SeverityFilter})\r\n| where AlertDisplayName in~ ({AlertNameFilter})\r\n| where Status == \"Active\"\r\n| extend ResourceGroup = iif(isempty(ResourceGroup), \" \", ResourceGroup)\r\n| where ResourceGroup in~ ({ResourceGroupFilter})\r\n| extend tag = iff(isempty(tags), dynamic({\"tags\": \" \"}), parse_json(tags))\r\n| mv-expand tag\r\n| parse tag with * ':\"' TagValue '\"}'\r\n| extend TagValue = iif(isempty(TagValue), \" \", TagValue)\r\n| where TagValue in ({TagFilter})\r\n| where AlertDisplayName !startswith ('[SAMPLE ALERT]')\r\n| project\r\n (Severity),\r\n tostring(SystemAlertId),\r\n tostring(AlertDisplayName),\r\n IsIncident = iif(IsIncident == \"true\", \"Incident\", \"Alert\"),\r\n AlertURI = tostring(AlertUri),\r\n tostring(Status),\r\n tostring(Tactics),\r\n SubscriptionId,\r\n ResourceGroup,\r\n Location,\r\n TagValue,\r\n tostring(tags),\r\n tostring(ResourceId)\r\n| distinct\r\n Severity,\r\n SystemAlertId,\r\n AlertDisplayName,\r\n IsIncident,\r\n AlertURI,\r\n Status,\r\n Tactics,\r\n SubscriptionId,\r\n ResourceGroup,\r\n Location,\r\n tags,\r\n ResourceId\r\n| order by Severity asc", + "size": 0, + "title": "Active Alerts ", + "exportedParameters": [ + { + "fieldName": "Resource", + "parameterName": "Resource", + "parameterType": 1 + }, + { + "fieldName": "AlertUri", + "parameterName": "AlertUri", + "parameterType": 1 + }, + { + "fieldName": "SystemAlertId", + "parameterName": "SystemAlertId", + "parameterType": 1 + }, + { + "fieldName": "SubscriptionId", + "parameterName": "SubscriptionId", + "parameterType": 1 + }, + { + "fieldName": "ResourceGroup", + "parameterName": "ResourceGroup", + "parameterType": 1 + }, + { + "fieldName": "Location", + "parameterName": "Location", + "parameterType": 1 + } + ], + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Severity", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "contains", + "thresholdValue": "High", + "representation": "redBright", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "Medium", + "representation": "orange", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "Low", + "representation": "yellow", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "Informational ", + "representation": "gray", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": null, + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "SystemAlertId", + "formatter": 5 + }, + { + "columnMatch": "IsIncident", + "formatter": 1 + }, + { + "columnMatch": "AlertURI", + "formatter": 5, + "formatOptions": { + "linkTarget": "Url" + } + }, + { + "columnMatch": "Status", + "formatter": 5 + }, + { + "columnMatch": "SubscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Location", + "formatter": 5 + }, + { + "columnMatch": "ResourceId", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Alert ID", + "formatter": 5 + }, + { + "columnMatch": "Alert URI", + "formatter": 5, + "formatOptions": { + "linkTarget": "Url" + } + }, + { + "columnMatch": "Resource ID", + "formatter": 5 + }, + { + "columnMatch": "AlertUri", + "formatter": 5 + }, + { + "columnMatch": "ResourceIdentifier", + "formatter": 5 + }, + { + "columnMatch": "TenantId", + "formatter": 5 + }, + { + "columnMatch": "AlertName", + "formatter": 5 + }, + { + "columnMatch": "Description", + "formatter": 5 + }, + { + "columnMatch": "ProviderName", + "formatter": 5 + }, + { + "columnMatch": "VendorName", + "formatter": 5 + }, + { + "columnMatch": "VendorOriginalId", + "formatter": 5 + }, + { + "columnMatch": "SourceComputerId", + "formatter": 5 + }, + { + "columnMatch": "AlertType", + "formatter": 5 + }, + { + "columnMatch": "ConfidenceLevel", + "formatter": 5 + }, + { + "columnMatch": "ConfidenceScore", + "formatter": 5 + }, + { + "columnMatch": "StartTime", + "formatter": 5 + }, + { + "columnMatch": "EndTime", + "formatter": 5 + }, + { + "columnMatch": "ProcessingEndTime", + "formatter": 5 + }, + { + "columnMatch": "RemediationSteps", + "formatter": 5 + }, + { + "columnMatch": "ExtendedProperties", + "formatter": 5 + }, + { + "columnMatch": "Entities", + "formatter": 5 + }, + { + "columnMatch": "SourceSystem", + "formatter": 5 + }, + { + "columnMatch": "WorkspaceSubscriptionId", + "formatter": 5 + }, + { + "columnMatch": "WorkspaceResourceGroup", + "formatter": 5 + }, + { + "columnMatch": "ExtendedLinks", + "formatter": 5 + }, + { + "columnMatch": "ProductName", + "formatter": 5 + }, + { + "columnMatch": "ProductComponentName", + "formatter": 5 + }, + { + "columnMatch": "AlertLink", + "formatter": 7, + "formatOptions": { + "linkTarget": "Url" + } + }, + { + "columnMatch": "SystemIncidentId", + "formatter": 5 + }, + { + "columnMatch": "SystemAlertId1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "AlertDisplayName", + "label": "Alert name" + }, + { + "columnId": "IsIncident", + "label": "Incident/alert" + }, + { + "columnId": "AlertURI", + "label": "Alert URI" + }, + { + "columnId": "SubscriptionId", + "label": "Subscription" + }, + { + "columnId": "ResourceGroup", + "label": "Resource group" + }, + { + "columnId": "tags", + "label": "Tags" + }, + { + "columnId": "ResourceId", + "label": "Resource" + } + ] + }, + "sortBy": [] + }, + "conditionalVisibility": { + "parameterName": "View", + "comparison": "isEqualTo", + "value": "List" + }, + "showPin": true, + "name": "SecurityIncidents" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "list", + "links": [ + { + "id": "8e6f9368-ccbe-4092-b898-8a27c77a06b3", + "linkTarget": "OpenBlade", + "linkLabel": "Open Alert View", + "preText": "", + "style": "primary", + "bladeOpenContext": { + "bladeName": "AlertBlade", + "extensionName": "Microsoft_Azure_Security", + "bladeParameters": [ + { + "name": "alertId", + "source": "static", + "value": "{SystemAlertId}" + }, + { + "name": "subscriptionId", + "source": "static", + "value": "{SubscriptionId}" + }, + { + "name": "resourceGroup", + "source": "static", + "value": "{ResourceGroup}" + }, + { + "name": "referencedFrom", + "source": "static", + "value": "activeAlertsWorkbook" + }, + { + "name": "location", + "source": "static", + "value": "{Location}" + } + ] + } + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "View", + "comparison": "isEqualTo", + "value": "List" + }, + { + "parameterName": "SystemAlertId", + "comparison": "isNotEqualTo" + } + ], + "name": "links - 19" + }, + { + "type": 1, + "content": { + "json": " To see more information about the alerts in the map view:

  1. Configure continuous export to export your security alerts to a Log Analytics workspace by following the instructions described \r\n
[ here. ](https://docs.microsoft.com/azure/defender-for-cloud/continuous-export?tabs=azure-portal)\r\n
  2. In the \"Workspace\" filter below, choose the Log Analytics workspace your security alerts are exported to.\r\n\r\n" + }, + "conditionalVisibility": { + "parameterName": "View", + "comparison": "isEqualTo", + "value": "Map" + }, + "name": "text - 21" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "8724f927-b766-4814-a895-8c55565fb7f8", + "version": "KqlParameterItem/1.0", + "name": "Workspace", + "type": 5, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "resources\r\n| where type contains \"solution\"\r\n| where name contains \"security\"\r\n| project id = tostring(properties.workspaceResourceId)\r\n| distinct id", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "conditionalVisibility": { + "parameterName": "View", + "comparison": "isEqualTo", + "value": "Map" + }, + "name": "parameters - 15" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources\r\n| where type == \"microsoft.security/locations/alerts\"\r\n| project-rename P= properties\r\n| extend Details = parse_json(P)\r\n | extend ResourceIdentifiers = Details.[\"ResourceIdentifiers\"]\r\n| extend IsIncident = Details.[\"IsIncident\"]\r\n| extend AlertDisplayName = Details.[\"AlertDisplayName\"]\r\n| extend SystemAlertId = Details.[\"SystemAlertId\"]\r\n| extend Severity = Details.[\"Severity\"]\r\n| extend AlertLink = Details.[\"AlertUri\"]\r\n| extend Status = Details.[\"Status\"]\r\n| extend Tactics = Details.[\"Intent\"]\r\n| parse AlertLink with * '/subscriptionId/' SubscriptionId '/' *\r\n| parse AlertLink with * '/resourceGroup/' ResourceGroup '/' *\r\n| parse AlertLink with * '/location/' Location \r\n | mv-expand ResourceIdentifiers\r\n | extend ResourceId = parse_json(ResourceIdentifiers).[\"AzureResourceId\"]\r\n | where isnotempty(ResourceId )\r\n| project Severity, SystemAlertId, tostring(AlertDisplayName),IsIncident = iif(IsIncident==\"true\",\"Incident\",\"Alert\"),tostring(AlertLink),Status,Tactics,tostring(ResourceId),SubscriptionId,ResourceGroup,Location\r\n| distinct tostring(SystemAlertId),tostring(AlertDisplayName),tostring(AlertLink),tostring(ResourceId)\r\n| summarize count() by ResourceId, AlertLink, AlertDisplayName\r\n", + "size": 0, + "title": "AlertsMapView ", + "exportMultipleValues": true, + "exportAggregateParts": true, + "exportedParameters": [ + { + "fieldName": "ResourceId", + "parameterName": "Resource", + "parameterType": 1 + }, + { + "fieldName": "AlertLink", + "parameterName": "AlertLink", + "parameterType": 1 + }, + { + "fieldName": "AlertDisplayName", + "parameterName": "AlertDisplayName", + "parameterType": 1 + } + ], + "exportToExcelOptions": "all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "map", + "mapSettings": { + "locInfo": "AzureResource", + "locInfoColumn": "ResourceId", + "sizeSettings": "count_", + "sizeAggregation": "Sum", + "legendMetric": "count_", + "legendAggregation": "Sum", + "itemColorSettings": { + "nodeColorField": "count_", + "colorAggregation": "Sum", + "type": "heatmap", + "heatmapPalette": "coldHot" + } + } + }, + "customWidth": "50", + "conditionalVisibility": { + "parameterName": "View", + "comparison": "isEqualTo", + "value": "Map" + }, + "name": "AlertsMapView ", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "let T = datatable ( AlertLink:string)\r\n[\r\n{AlertLink}\r\n];\r\nT\r\n| parse AlertLink with * '/alertId/' AlertId '/subscriptionId/' SubscriptionId '/resourceGroup/' ResourceGroup '/' * 'location/' Location \r\n| distinct AlertLink, AlertId, ResourceGroup,Location,SubscriptionId\r\n| join kind = inner (SecurityAlert\r\n| where isempty(ResourceId) == false\r\n| where TimeGenerated > ago(90d)\r\n| project SystemAlertId,ResourceId, DisplayName,StartTime) on $left.AlertId == $right.SystemAlertId\r\n| project ResourceId,DisplayName,AlertId, SubscriptionId, ResourceGroup, Location,StartTime\r\n| order by ResourceId,DisplayName, StartTime asc\r\n\r\n\r\n\r\n", + "size": 0, + "exportedParameters": [ + { + "fieldName": "AlertId", + "parameterName": "AlertId", + "parameterType": 1 + }, + { + "fieldName": "SubscriptionId", + "parameterName": "SubscriptionId", + "parameterType": 1 + }, + { + "fieldName": "Location", + "parameterName": "Location", + "parameterType": 1 + }, + { + "fieldName": "ResourceGroup", + "parameterName": "ResourceGroup", + "parameterType": 1 + } + ], + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{Workspace}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "ResourceId", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "23ch" + } + }, + { + "columnMatch": "DisplayName", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "45ch" + } + }, + { + "columnMatch": "AlertId", + "formatter": 5 + }, + { + "columnMatch": "Location", + "formatter": 5 + }, + { + "columnMatch": "StartTime", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "23ch" + } + }, + { + "columnMatch": "TimeGenerated", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "22ch" + } + }, + { + "columnMatch": "AlertLink", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "ResourceId", + "label": "Resource ID" + }, + { + "columnId": "DisplayName", + "label": "Alert name" + }, + { + "columnId": "AlertId", + "label": "Alert ID" + }, + { + "columnId": "SubscriptionId", + "label": "Subscription ID" + }, + { + "columnId": "ResourceGroup", + "label": "Resource group" + }, + { + "columnId": "StartTime", + "label": "Start time" + } + ] + }, + "sortBy": [], + "tileSettings": { + "showBorder": false + } + }, + "customWidth": "45", + "conditionalVisibilities": [ + { + "parameterName": "View", + "comparison": "isEqualTo", + "value": "Map" + }, + { + "parameterName": "AlertLink", + "comparison": "isNotEqualTo" + } + ], + "name": "AlertLink-Table" + } + ] + }, + "name": "Security Discipline" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Security" + }, + { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + } + ], + "name": "RC_Security" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "1e6e4cc7-5d76-48ef-8ce1-16f33f4f6dea", + "version": "KqlParameterItem/1.0", + "name": "SubscriptionAge", + "label": "Subscription", + "type": 6, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": null + } + ], + "style": "above", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - SubscriptionAge" + }, + { + "type": 1, + "content": { + "json": "## Azure resource age\r\nAzure *resource age* is one of the metric to monitor as part of the \"resource consistency\" discipline of the Cloud Adoption Framework. This metric help you to identify old resources to be assessed and cleaned if they are not used anymore." + }, + "name": "text - ResourceAgeDescription" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadFromTemplateId": "community-Workbooks/Common/noSubscriptions", + "items": [] + }, + "conditionalVisibility": { + "parameterName": "SubscriptionAge", + "comparison": "isEqualTo", + "value": "" + }, + "name": "No Subscriptions group - Age" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"path\":\"/subscriptions/{SubscriptionAge:id}/resources?\",\"urlParams\":[{\"key\":\"api-version\",\"value\":\"2021-04-01\"},{\"key\":\"$expand\",\"value\":\"createdTime,changedTime,provisioningState\"}],\"batchDisabled\":true,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.value\",\"columns\":[{\"path\":\"$..id\",\"columnid\":\"id\",\"columnType\":\"string\"},{\"path\":\"$..type\",\"columnid\":\"type\",\"columnType\":\"string\"},{\"path\":\"$..location\",\"columnid\":\"location\",\"columnType\":\"string\"},{\"path\":\"$..createdTime\",\"columnid\":\"createdTime\",\"columnType\":\"datetime\"},{\"path\":\"$..changedTime\",\"columnid\":\"changedTime\",\"columnType\":\"datetime\"},{\"path\":\"$..provisioningState\",\"columnid\":\"provisioningState\",\"columnType\":\"string\"},{\"path\":\"$..tags\",\"columnid\":\"tags\"}]}}]}", + "size": 0, + "title": "Resource age", + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "formatters": [ + { + "columnMatch": "type", + "formatter": 16, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "location", + "formatter": 17 + }, + { + "columnMatch": "createdTime", + "formatter": 6 + }, + { + "columnMatch": "changedTime", + "formatter": 6 + }, + { + "columnMatch": "provisioningState", + "formatter": 1 + }, + { + "columnMatch": "tags", + "formatter": 1 + } + ], + "filter": true, + "sortBy": [ + { + "itemKey": "changedTime", + "sortOrder": 1 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Resource Name" + }, + { + "columnId": "type", + "label": "Resource Type" + }, + { + "columnId": "location", + "label": "Region" + }, + { + "columnId": "createdTime", + "label": "Created Time" + }, + { + "columnId": "changedTime", + "label": "Last Change" + }, + { + "columnId": "provisioningState", + "label": "Provisioning State" + }, + { + "columnId": "tags", + "label": "Tags" + } + ] + }, + "sortBy": [ + { + "itemKey": "changedTime", + "sortOrder": 1 + } + ] + }, + "conditionalVisibility": { + "parameterName": "SubscriptionAge", + "comparison": "isNotEqualTo" + }, + "name": "query - Resource age" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Age" + }, + "name": "Resource Age" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "e15ef842-dadb-4a7b-b5f6-5d1bbe35b7af", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "description": "Cost information can only be displayed per subscription", + "typeSettings": { + "additionalResourceOptions": [], + "includeAll": true, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": null + }, + { + "id": "b73ef334-95b2-4ead-8dd2-51a90a90ce6f", + "version": "KqlParameterItem/1.0", + "name": "Aggregation", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\": \"SubscriptionId\", \"label\": \"Subscription\", \"selected\":true},\r\n { \"value\": \"ResourceGroup\", \"label\": \"Resource Group\"},\r\n { \"value\": \"ResourceType\", \"label\": \"Resource Type\"}\r\n]", + "timeContext": { + "durationMs": 86400000 + } + }, + { + "id": "55ef4a45-0603-48cf-bb9b-a963e7a33be2", + "version": "KqlParameterItem/1.0", + "name": "TimeFrame", + "type": 2, + "typeSettings": { + "additionalResourceOptions": [] + }, + "jsonData": "[\r\n { \"value\": \"BillingMonthToDate\", \"label\": \"Billing MonthToDate\"},\r\n { \"value\": \"MonthToDate\", \"label\": \"MonthToDate\", \"selected\":true },\r\n { \"value\": \"TheLastBillingMonth\", \"label\": \"Last Billing Month\"},\r\n { \"value\": \"TheLastMonth\", \"label\": \"Last Month\"},\r\n { \"value\": \"WeekToDate\", \"label\": \"WeekToDate\"}\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "label": "Timeframe" + } + ], + "style": "above", + "doNotRunWhenHidden": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - Cost Subscription" + }, + { + "type": 1, + "content": { + "json": "## Microsoft Cost Management\r\n\r\nBefore you can control and optimize your costs, you first need to understand where they originated – from the underlying resources used to support your cloud projects to the environments they're deployed in and the owners who manage them. Full visibility backed by a thorough tagging strategy is critical to accurately understand your spending patterns and enforce cost control mechanisms.\r\n\r\n[Cost Management](https://portal.azure.com/#view/Microsoft_Azure_CostManagement/Menu) is a set of FinOps tools that enable you to analyze, manage, and optimize your costs.\r\n\r\nCalculate your estimated hourly or monthly costs for using Azure with the [Azure Calculator](https://azure.microsoft.com/pricing/calculator/).\r\n\r\nFor more advanced reporting options, build custom [Power BI reports in the FinOps toolkit](https://aka.ms/ftk/pbi)." + }, + "name": "text - AzureCostManagement" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":\" {\\r\\n \\\"type\\\": \\\"Usage\\\",\\r\\n \\\"timeframe\\\": \\\"{TimeFrame}\\\",\\r\\n \\\"dataset\\\": {\\r\\n \\\"granularity\\\": \\\"None\\\",\\r\\n \\\"aggregation\\\": {\\r\\n \\\"totalCost\\\": {\\r\\n \\\"name\\\": \\\"PreTaxCost\\\",\\r\\n \\\"function\\\": \\\"Sum\\\"\\r\\n }\\r\\n },\\r\\n \\\"grouping\\\": [\\r\\n {\\r\\n \\\"type\\\": \\\"Dimension\\\",\\r\\n \\\"name\\\": \\\"{Aggregation}\\\"\\r\\n }\\r\\n ]\\r\\n }\\r\\n }\",\"headers\":[],\"method\":\"POST\",\"path\":\"/subscriptions/{Subscription:id}/providers/Microsoft.CostManagement/query?\",\"urlParams\":[{\"key\":\"api-version\",\"value\":\"2023-11-01\"}],\"batchDisabled\":true,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.properties\",\"columns\":[]}}]}", + "size": 0, + "title": "Overall cost", + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "formatters": [ + { + "columnMatch": "PreTaxCost", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal", + "useGrouping": true, + "maximumFractionDigits": 2 + }, + "emptyValCustomText": "\"0\"" + } + }, + { + "columnMatch": "SubscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "ResourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": false + } + }, + { + "columnMatch": "ResourceType", + "formatter": 16, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": "Resource", + "linkIsContextBlade": false, + "showIcon": false + } + } + ], + "filter": true, + "sortBy": [ + { + "itemKey": "$gen_number_PreTaxCost_0", + "sortOrder": 2 + } + ], + "labelSettings": [ + { + "columnId": "PreTaxCost", + "label": "Cost" + }, + { + "columnId": "Currency", + "label": "Currency" + } + ] + }, + "sortBy": [ + { + "itemKey": "$gen_number_PreTaxCost_0", + "sortOrder": 2 + } + ], + "tileSettings": { + "showBorder": false + } + }, + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "query - Overall cost" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "6cc7fc26-1a56-41cb-ad43-301e0f9f8903", + "version": "KqlParameterItem/1.0", + "name": "TagName", + "label": "Tag name", + "type": 2, + "isRequired": true, + "query": "Resources\r\n| where tags != '' and tags != '[]'\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| distinct tagName\r\n| sort by tagName asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null + }, + { + "id": "2fc46f5d-ce69-42ea-8ebf-1c3d69c4e780", + "version": "KqlParameterItem/1.0", + "name": "TagValue", + "label": "Tag value", + "type": 2, + "isRequired": true, + "query": "Resources\r\n| extend TagValue = tostring(tags.{TagName})\r\n| project TagValue\r\n| distinct TagValue", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": "" + } + ], + "style": "above", + "doNotRunWhenHidden": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "parameters - TagFilter" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":\" {\\r\\n \\\"type\\\": \\\"Usage\\\",\\r\\n \\\"timeframe\\\": \\\"{TimeFrame}\\\",\\r\\n \\\"dataset\\\": {\\r\\n \\\"granularity\\\": \\\"None\\\",\\r\\n \\\"filter\\\": {\\r\\n \\\"tags\\\" : {\\r\\n \\\"name\\\" : \\\"{TagName}\\\",\\r\\n \\\"operator\\\" : \\\"In\\\",\\r\\n \\\"values\\\" : [\\r\\n \\\"{TagValue}\\\"\\r\\n ]\\r\\n }\\r\\n },\\r\\n \\\"aggregation\\\": {\\r\\n \\\"totalCost\\\": {\\r\\n \\\"name\\\": \\\"PreTaxCost\\\",\\r\\n \\\"function\\\": \\\"Sum\\\"\\r\\n }\\r\\n },\\r\\n \\\"grouping\\\": [\\r\\n {\\r\\n \\\"type\\\": \\\"Dimension\\\",\\r\\n \\\"name\\\": \\\"{Aggregation}\\\"\\r\\n }\\r\\n ]\\r\\n }\\r\\n }\",\"headers\":[],\"method\":\"POST\",\"path\":\"/subscriptions/{Subscription:id}/providers/Microsoft.CostManagement/query?\",\"urlParams\":[{\"key\":\"api-version\",\"value\":\"2023-11-01\"}],\"batchDisabled\":true,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.properties\",\"columns\":[]}}]}", + "size": 3, + "title": "Overall cost filtered by tag", + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "formatters": [ + { + "columnMatch": "PreTaxCost", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal", + "useGrouping": true, + "maximumFractionDigits": 2 + }, + "emptyValCustomText": "\"0\"" + } + }, + { + "columnMatch": "SubscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "ResourceType", + "formatter": 16, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": "Resource", + "linkIsContextBlade": false, + "showIcon": true + } + } + ], + "labelSettings": [ + { + "columnId": "PreTaxCost", + "label": "Cost" + } + ] + }, + "tileSettings": { + "showBorder": false + } + }, + "conditionalVisibility": { + "parameterName": "TagValue", + "comparison": "isNotEqualTo", + "value": "" + }, + "name": "query - Sub cost per tag" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Cost" + }, + "name": "RC_Cost Management" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "loadType": "always", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "value::tenant" + ], + "parameters": [ + { + "id": "476f61f4-2271-4e58-9b5e-7958d9a4ca3b", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": null + } + ], + "style": "above", + "doNotRunWhenHidden": true, + "queryType": 1, + "resourceType": "microsoft.resources/tenants" + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Compliance" + }, + "name": "parameters - Scope Filter For RC_Compliance" + }, + { + "type": 1, + "content": { + "json": "## Build and scale your applications quickly while maintaining control\r\nTake advantage of built-in and custom policies to set guardrails in your subscriptions. Easily deploy fully governed environments throughout your organization with Azure Blueprints. And, manage costs by gaining insights into your cloud spend so that you get the most from your cloud investments.
\r\n- Enforce and audit your policies for any Azure service
\r\n- Create compliant environments using Azure Blueprints, including resources, policies, and role-access controls
\r\n- Ensure that you’re compliant with external regulations by using built-in compliance controls
\r\n- Monitor cost and encourage accountability across your entire organization" + }, + "name": "text - 16" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "// Breakdown of compliance information for each assignment at subscription/MG/tenant scope\r\n// Gets aggregated compliance and policy definition information for each of the assignments in the selected scope as well as a few additional details, including: policySetDefinition or policyDefinition details for those assignments, the number of policies/groups within the policysetDefinitions listed, number of non-compliant policies within each policySetDefinition and the resource count breakdown per compliance state for those assignments.\r\n// Click the \"Run query\" command above to execute the query and see results.\r\npolicyResources\r\n| where type =~'Microsoft.Authorization/PolicyAssignments'\r\n| project policyAssignmentId = tolower(tostring(id)), policyAssignmentName = name, policyAssignmentDisplayName = tostring(properties.displayName), policyAssignmentScope = tostring(properties.scope), policyAssignmentDefinitionId = tolower(properties.policyDefinitionId), policyAssignmentNotScopes = tolower(properties.notScopes) \r\n| where policyAssignmentScope == \"{Subscription}\"\r\n| join kind=leftouter(\r\n policyResources\r\n | where type =~'Microsoft.Authorization/PolicySetDefinitions' or type =~'Microsoft.Authorization/PolicyDefinitions'\r\n | project definitionId = tolower(id), type, numberOfPolicies = array_length(properties.policyDefinitions), category = tostring(properties.metadata.category), numberOfGroups= array_length(properties.policyDefinitionGroups), mode = tostring(properties.mode)\r\n | extend isRegulatoryInitiative = iff(category =~ 'Regulatory Compliance', true, false)\r\n | extend definitionType = iff(type =~ 'Microsoft.Authorization/PolicysetDefinitions', 'initiative', 'policy')\r\n | extend isRPMode = iff(mode startswith 'Microsoft.', true, false)\r\n | project definitionId, numberOfPolicies, category, numberOfGroups, isRegulatoryInitiative, definitionType, isRPMode\r\n) on $left.policyAssignmentDefinitionId == $right.definitionId\r\n| join kind=leftouter(\r\n policyResources \r\n | where type =~ 'Microsoft.PolicyInsights/PolicyStates'\r\n | extend complianceState = tostring(properties.complianceState)\r\n | extend policyStateResourceId =id, resourceId = tostring(properties.resourceId), policyAssignmentId = tostring(properties.policyAssignmentId), policyDefinitionId = tostring(properties.policyDefinitionId), policySetDefinitionId = tostring(properties.policySetDefinitionId), policyDefinitionReferenceId = tostring(properties.policyDefinitionReferenceId), policyDefinitionAction = tostring(properties.policyDefinitionAction), policyDefinitionGroupNames = iff(isnotnull(properties.policyDefinitionGroupNames), properties.policyDefinitionGroupNames, dynamic([''])), stateWeight = toint(properties.stateWeight)\r\n | summarize max(stateWeight) by resourceId, policyAssignmentId, policySetDefinitionId\r\n | summarize resourceCounts = count() by policyAssignmentId, policySetDefinitionId, max_stateWeight\r\n| extend complianceState = case(\r\nmax_stateWeight == 300, 'noncompliant',\r\nmax_stateWeight == 200, 'compliant',\r\nmax_stateWeight == 100, 'conflict',\r\nmax_stateWeight == 50, 'exempt',\r\nmax_stateWeight == 10, 'unknown',\r\n'notapplicable')\r\n | extend pack = pack('complianceState', complianceState, 'resourceCounts', resourceCounts), numberOfNonCompliantResources = toint(iff(complianceState =~ 'NonCompliant', resourceCounts,0))\r\n | summarize numberOfNonCompliantResources = max(numberOfNonCompliantResources), details = makelist(pack) by policyAssignmentId, policySetDefinitionId\r\n | limit 5000\r\n) on $left.policyAssignmentId == $right.policyAssignmentId\r\n| sort by numberOfNonCompliantResources desc\r\n| project-away policyAssignmentId1", + "size": 0, + "title": "Resource compliance", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resources/tenants", + "crossComponentResources": [ + "value::tenant" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "policyAssignmentId", + "formatter": 5 + }, + { + "columnMatch": "policyAssignmentName", + "formatter": 5 + }, + { + "columnMatch": "policyAssignmentDisplayName", + "formatter": 7, + "formatOptions": { + "linkTarget": "GenericDetails", + "linkIsContextBlade": true + } + }, + { + "columnMatch": "policyAssignmentScope", + "formatter": 5 + }, + { + "columnMatch": "policyAssignmentDefinitionId", + "formatter": 5 + }, + { + "columnMatch": "policyAssignmentNotScopes", + "formatter": 5 + }, + { + "columnMatch": "definitionId", + "formatter": 5 + }, + { + "columnMatch": "numberOfPolicies", + "formatter": 5 + }, + { + "columnMatch": "numberOfGroups", + "formatter": 5 + }, + { + "columnMatch": "isRegulatoryInitiative", + "formatter": 5 + }, + { + "columnMatch": "isRPMode", + "formatter": 5 + }, + { + "columnMatch": "policySetDefinitionId", + "formatter": 5 + }, + { + "columnMatch": "details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ], + "filter": true, + "sortBy": [ + { + "itemKey": "category", + "sortOrder": 2 + } + ], + "labelSettings": [ + { + "columnId": "policyAssignmentId", + "label": "Assignment ID" + }, + { + "columnId": "policyAssignmentName", + "label": "Assignment name" + }, + { + "columnId": "policyAssignmentDisplayName", + "label": "Assignment display name" + }, + { + "columnId": "policyAssignmentScope", + "label": "Assignment scope" + }, + { + "columnId": "policyAssignmentDefinitionId", + "label": "Assignment definition ID" + }, + { + "columnId": "definitionId", + "label": "Definition ID" + }, + { + "columnId": "numberOfPolicies", + "label": "Number of policies" + }, + { + "columnId": "category", + "label": "Category" + }, + { + "columnId": "definitionType", + "label": "Type" + }, + { + "columnId": "numberOfNonCompliantResources", + "label": "Non compliant resources" + }, + { + "columnId": "details", + "label": "Details" + } + ] + }, + "sortBy": [ + { + "itemKey": "category", + "sortOrder": 2 + } + ] + }, + "name": "query - ResourceCompliance" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AzureActivity\r\n| where ActivityStatusValue has \"Failure\"\r\n| summarize AggregatedValue = count() by ResourceProviderValue\r\n| order by AggregatedValue desc", + "size": 3, + "showAnalytics": true, + "title": "Failures by resources", + "timeContext": { + "durationMs": 604800000 + }, + "queryType": 0, + "resourceType": "microsoft.resources/subscriptions", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "ResourceProviderValue", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "AggregatedValue", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "ResourceProviderValue", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "AggregatedValue", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "customWidth": "33", + "name": "query - Failures by resources" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AzureActivity\r\n| where ActivityStatusValue has \"Failure\" or ActivityStatusValue has \"Failed\"\r\n| summarize AggregatedValue = count() by OperationNameValue\r\n| order by AggregatedValue desc", + "size": 3, + "showAnalytics": true, + "title": "Failures by operations", + "timeContext": { + "durationMs": 604800000 + }, + "queryType": 0, + "resourceType": "microsoft.resources/subscriptions", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "ResourceProviderValue", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "AggregatedValue", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "ResourceProviderValue", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "AggregatedValue", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "customWidth": "33", + "name": "query - Failures by operations" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AzureActivity\r\n| where ActivityStatusValue has \"Failure\" or ActivityStatusValue has \"Failed\"\r\n| summarize AggregatedValue = count() by CategoryValue\r\n| order by AggregatedValue desc", + "size": 3, + "showAnalytics": true, + "title": "Failures by category", + "timeContext": { + "durationMs": 604800000 + }, + "queryType": 0, + "resourceType": "microsoft.resources/subscriptions", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "ResourceProviderValue", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "AggregatedValue", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "ResourceProviderValue", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "AggregatedValue", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "customWidth": "33", + "name": "query - Failures by category" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AzureActivity\r\n| where ActivityStatusValue has \"Failure\" or ActivityStatusValue has \"Failed\"\r\n| order by CategoryValue\r\n", + "size": 0, + "title": "Failure by category details", + "timeContext": { + "durationMs": 604800000 + }, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.resources/subscriptions", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Authorization", + "formatter": 5 + }, + { + "columnMatch": "Authorization_d", + "formatter": 5 + }, + { + "columnMatch": "Claims", + "formatter": 5 + }, + { + "columnMatch": "Claims_d", + "formatter": 5 + }, + { + "columnMatch": "Properties_d", + "formatter": 5 + }, + { + "columnMatch": "_ResourceId", + "formatter": 5 + } + ], + "filter": true + } + }, + "name": "query - Failure by category details" + } + ] + }, + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "group - ComplianceQueries" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Compliance" + }, + "name": "RC_Compliance" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "4168a8b2-a522-4f0d-9575-893d70d9239d", + "version": "KqlParameterItem/1.0", + "name": "RulesCount", + "type": 1, + "description": "Count of the governance rule, when there is no rules, empty state will be shown", + "query": "securityresources\r\n| where type == \"microsoft.security/governancerules\"\r\n| where tostring(properties.isDisabled) == \"false\"\r\n| count", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + } + ], + "style": "above", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "name": "Tabs" + }, + { + "type": 1, + "content": { + "json": "## Security governance in Microsoft Defender for Cloud\r\n\r\n Microsoft Defender for Cloud continuously assesses your hybrid and multi-cloud workloads and provides you with recommendations to harden your assets and enhance your security posture.
Central security teams often experience challenges when driving the personnel within their organizations to implement recommendations. The organizations' security posture can suffer as a result.
\r\nWe're introducing a brand-new, built-in governance experience to set ownership and expected remediation timeframes to resolve recommendations.\r\n\r\nTo use this governance report, you need to create security governance rules.\r\n
[Learn more >](https://aka.ms/GovernanceDocumentation)\r\n" + }, + "conditionalVisibility": { + "parameterName": "RulesCount", + "comparison": "isEqualTo" + }, + "name": "text - 13" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "Select one or more governance rules from the list to see a list of affected recommendations", + "style": "info" + }, + "name": "RulesGridExplination" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources \r\n| where type == \"microsoft.security/assessments\"\r\n| where isnull(properties.resourceDetails.AwsResourceId) and isnull(properties.resourceDetails.GcpResourceId)\r\n| extend DisplayName = tostring(properties.displayName)\r\n| where isempty(DisplayName) == false\r\n| join kind=leftouter (securityresources \r\n| where type == \"microsoft.security/assessments/governanceassignments\"\r\n| extend assignedResourceId = tostring(todynamic(properties).assignedResourceId)\r\n| extend remediationDueDate = todatetime(properties.remediationDueDate)\r\n| project id = assignedResourceId, governanceassignmentsProperties = todynamic(properties), remediationDueDate) on id\r\n| extend hasAssignment = isempty( governanceassignmentsProperties) == false and isnull( governanceassignmentsProperties) == false\r\n| extend assignmentStatus = iif(tostring(properties.status.code) == \"Unhealthy\",iif(hasAssignment == true, iif(bin(remediationDueDate, 1d) < bin(now(), 1d), \"Overdue\", \"Ontime\"), \"Unassigned\") , \"Completed\")\r\n| summarize count() by assignmentStatus\r\n", + "size": 3, + "title": "Resource status", + "noDataMessage": "No unhealthy resources found", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "tileSettings": { + "titleContent": { + "columnMatch": "OsType", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal", + "useGrouping": false, + "maximumFractionDigits": 2, + "maximumSignificantDigits": 3 + } + } + }, + "showBorder": true + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "OsType", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "count_", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "chartSettings": { + "seriesLabelSettings": [ + { + "seriesName": "Ontime", + "color": "blue" + }, + { + "seriesName": "Completed", + "color": "green" + }, + { + "seriesName": "Unassigned", + "color": "orange" + }, + { + "seriesName": "Overdue", + "color": "redBright" + } + ] + } + }, + "customWidth": "20", + "name": "statusePerAssessment" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources\r\n| where type == \"microsoft.security/governancerules\"\r\n| where tostring(properties.isDisabled) == \"false\"\r\n| extend ruleName = todynamic(name)\r\n| extend ownerType = iif(tostring(properties.ownerSource.type) == \"Manually\", \"Email\", \"ByTag\")\r\n| extend description = tostring(properties.description)\r\n| extend displayName = tostring(properties.displayName)\r\n| extend governanceEmailNotification = todynamic(properties.governanceEmailNotification)\r\n| extend isGracePeriod = todynamic(properties.isGracePeriod)\r\n| extend remediationTimeframe = todynamic(properties.remediationTimeframe)\r\n| extend Days = tolong(totimespan(remediationTimeframe)/1d)\r\n| extend Days = iff(Days > 0, iff(Days == 1, \"1 day\", strcat(Days,\" days\")), \"\")\r\n| extend sourceResourceType = todynamic(properties.sourceResourceType)\r\n| extend conditionSets = todynamic(properties.conditionSets)\r\n| extend rulePriority = todynamic(properties.rulePriority)\r\n| extend ownerSource = todynamic(properties.ownerSource)\r\n| extend isDisabled = todynamic(properties.isDisabled)\r\n| extend ruleType = todynamic(properties.ruleType)\r\n| extend RuleConditionSet = tostring(properties.conditionSets), property = properties.conditionSets[0].conditions[0].property, operator = properties.conditionSets[0].conditions[0].operator\r\n| project Subscription = tostring(subscriptionId), [\"Display name\"] = tostring(properties.displayName), Priority = toint(properties.rulePriority), [\"Remediation timeframe\"] = Days, [\"Owner type\"] = ownerType, Owner = tostring(properties.ownerSource.value), [\"Grace period enabled\"] = tostring(properties.isGracePeriod), Rule = id, properties, RuleConditionSet\r\n| sort by Subscription, Priority asc", + "size": 0, + "title": "Governance rules", + "noDataMessage": "No Rules found", + "exportMultipleValues": true, + "exportedParameters": [ + { + "fieldName": "Rule", + "parameterName": "Rule", + "parameterType": 1, + "quote": "" + }, + { + "fieldName": "RuleConditionSet", + "parameterName": "RuleConditionSet", + "parameterType": 1, + "quote": "" + }, + { + "fieldName": "Owner", + "parameterName": "Owner", + "parameterType": 1, + "quote": "" + } + ], + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Subscription", + "formatter": 15, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Display name", + "formatter": 1, + "formatOptions": { + "bladeOpenContext": { + "bladeName": "CreateGovernanceRuleContextBlade", + "extensionName": "Microsoft_Azure_Security", + "bladeParameters": [ + { + "name": "", + "source": "column", + "value": "properties" + }, + { + "name": "subscriptionId", + "source": "column", + "value": "subscriptionId" + }, + { + "name": "governanceRuleToEdit", + "source": "column", + "value": "properties" + } + ] + } + } + }, + { + "columnMatch": "Priority", + "formatter": 1 + }, + { + "columnMatch": "Remediation timeframe", + "formatter": 0, + "tooltipFormat": { + "tooltip": "DD.HH.MM.SS" + } + }, + { + "columnMatch": "Grace period enabled", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "true", + "representation": "success", + "text": "" + }, + { + "operator": "==", + "thresholdValue": "false", + "representation": "4", + "text": "" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Rule", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + }, + { + "columnMatch": "name", + "formatter": 1 + }, + { + "columnMatch": "DisplayName", + "formatter": 1 + }, + { + "columnMatch": "ownerDetails", + "formatter": 1 + }, + { + "columnMatch": "isGracePeriod", + "formatter": 1 + }, + { + "columnMatch": "remediationTimeframe", + "formatter": 1 + } + ], + "rowLimit": 1000, + "filter": true, + "sortBy": [ + { + "itemKey": "$gen_link_Subscription_0", + "sortOrder": 2 + } + ], + "labelSettings": [ + { + "columnId": "Owner", + "label": "Owner details" + } + ] + }, + "sortBy": [ + { + "itemKey": "$gen_link_Subscription_0", + "sortOrder": 2 + } + ] + }, + "customWidth": "80", + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "Rules", + "styleSettings": { + "maxWidth": "100" + } + } + ], + "exportParameters": true + }, + "customWidth": "100", + "conditionalVisibility": { + "parameterName": "RulesCount", + "comparison": "isNotEqualTo" + }, + "name": "subscriptionOverView" + }, + { + "type": 1, + "content": { + "json": "---" + }, + "conditionalVisibility": { + "parameterName": "selectedTab", + "comparison": "isEqualTo", + "value": "resourceView" + }, + "name": "LineSeparator1" + }, + { + "type": 1, + "content": { + "json": "💡 Selected filter for **RuleConditionSet:** {RuleConditionSet}\r\n💡 Selected filter for **Rule:** {Rule}\r\n💡 Selected filter for **Owner:** {Owner}\r\n", + "style": "{selectedTab}" + }, + "conditionalVisibility": { + "parameterName": "parameter1", + "comparison": "isEqualTo", + "value": "1" + }, + "name": "ResourceFilter" + }, + { + "type": 1, + "content": { + "json": " \r\n---" + }, + "conditionalVisibility": { + "parameterName": "selectedTab", + "comparison": "isEqualTo", + "value": "resourceView" + }, + "name": "LineSeparator2" + }, + { + "type": 1, + "content": { + "json": "Select a recommendation from the list to see a list of affected resources", + "style": "info" + }, + "conditionalVisibilities": [ + { + "parameterName": "Rule", + "comparison": "isNotEqualTo" + }, + { + "parameterName": "DisplayName", + "comparison": "isEqualTo" + } + ], + "name": "assessmentsExplaination" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources \r\n| where type == \"microsoft.security/assessments\"\r\n| where isnull(properties.resourceDetails.AwsResourceId) and isnull(properties.resourceDetails.GcpResourceId)\r\n| extend DisplayName = tostring(properties.displayName)\r\n| where isempty(DisplayName) == false\r\n| extend RuleConditionSet = '{RuleConditionSet}'\r\n| where RuleConditionSet contains name or RuleConditionSet contains properties.metadata.severity\r\n| join kind=leftouter (securityresources \r\n| where type == \"microsoft.security/assessments/governanceassignments\"\r\n| extend assignedResourceId = tostring(todynamic(properties).assignedResourceId)\r\n| extend remediationDueDate = todatetime(properties.remediationDueDate)\r\n| project id = assignedResourceId, governanceassignmentsProperties = todynamic(properties), remediationDueDate) on id\r\n| extend hasAssignment = isempty( governanceassignmentsProperties) == false and isnull( governanceassignmentsProperties) == false\r\n| extend assignmentStatus = iif(tostring(properties.status.code) == \"Unhealthy\",iif(hasAssignment == true, iif(bin(remediationDueDate, 1d) < bin(now(), 1d), \"Overdue\", \"Ontime\"), \"Unassigned\") , \"Completed\")\r\n| summarize count() by assignmentStatus", + "size": 3, + "title": "Status per rule", + "noDataMessage": "No unhealthy resources found", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "gridSettings": { + "rowLimit": 10000 + }, + "tileSettings": { + "titleContent": { + "columnMatch": "OsType", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal", + "useGrouping": false, + "maximumFractionDigits": 2, + "maximumSignificantDigits": 3 + } + } + }, + "showBorder": true + }, + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "OsType", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "count_", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "chartSettings": { + "seriesLabelSettings": [ + { + "seriesName": "Ontime", + "color": "blue" + }, + { + "seriesName": "Completed", + "color": "green" + }, + { + "seriesName": "Unassigned", + "color": "orange" + }, + { + "seriesName": "Overdue", + "color": "redBright" + } + ] + } + }, + "customWidth": "20", + "conditionalVisibility": { + "parameterName": "Rule", + "comparison": "isNotEqualTo" + }, + "name": "statusPerRule" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources \r\n| where type == \"microsoft.security/assessments\"\r\n| where isnull(properties.resourceDetails.AwsResourceId) and isnull(properties.resourceDetails.GcpResourceId)\r\n| extend DisplayName = tostring(properties.displayName)\r\n| where isempty(DisplayName) == false\r\n| extend RuleConditionSet = '{RuleConditionSet}'\r\n| where RuleConditionSet contains name or RuleConditionSet contains properties.metadata.severity\r\n| join kind=leftouter (securityresources \r\n| where type == \"microsoft.security/assessments/governanceassignments\"\r\n| extend assignedResourceId = tostring(todynamic(properties).assignedResourceId)\r\n| extend remediationDueDate = todatetime(properties.remediationDueDate)\r\n| project id = assignedResourceId, governanceassignmentsProperties = todynamic(properties), remediationDueDate) on id\r\n| extend hasAssignment = isempty( governanceassignmentsProperties) == false and isnull( governanceassignmentsProperties) == false\r\n| where hasAssignment == true\r\n| extend owner = tostring(governanceassignmentsProperties.owner)\r\n| extend owner = iif(isnull(owner) == false and isempty(owner) == false, owner, \"Unspecified\")\r\n| extend assignmentStatus = iif(bin(remediationDueDate, 1d) < bin(now(), 1d), \"Overdue\", \"Ontime\")\r\n| summarize Ontime = countif(assignmentStatus == \"Ontime\"), Overdue = countif(assignmentStatus == \"Overdue\") by selectedOwner = owner\r\n| sort by Overdue desc", + "size": 0, + "title": "Status per owner", + "exportMultipleValues": true, + "exportedParameters": [ + { + "fieldName": "selectedOwner", + "parameterName": "selectedOwner", + "quote": "" + } + ], + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Ontime", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "!=", + "thresholdValue": "0", + "representation": "info", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Overdue", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "!=", + "thresholdValue": "0", + "representation": "3", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + } + ], + "labelSettings": [ + { + "columnId": "selectedOwner", + "label": "Owner" + } + ] + } + }, + "customWidth": "30", + "conditionalVisibilities": [ + { + "parameterName": "Owner", + "comparison": "isNotEqualTo" + }, + { + "parameterName": "RuleConditionSet", + "comparison": "isNotEqualTo" + } + ], + "name": "Owner status" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources \r\n| where type == \"microsoft.security/assessments\"\r\n| where isnull(properties.resourceDetails.AwsResourceId) and isnull(properties.resourceDetails.GcpResourceId)\r\n| extend DisplayName = tostring(properties.displayName)\r\n| where isempty(DisplayName) == false and isnull(DisplayName) == false\r\n| extend RuleConditionSet = '{RuleConditionSet}'\r\n| where RuleConditionSet contains name or RuleConditionSet contains properties.metadata.severity\r\n| join kind=leftouter (securityresources \r\n| where type == \"microsoft.security/assessments/governanceassignments\"\r\n| extend assignedResourceId = tostring(todynamic(properties).assignedResourceId)\r\n| extend remediationDueDate = todatetime(properties.remediationDueDate)\r\n| project id = assignedResourceId, governanceassignmentsProperties = todynamic(properties), remediationDueDate) on id\r\n| extend hasAssignment = isempty( governanceassignmentsProperties) == false and isnull( governanceassignmentsProperties) == false\r\n| extend assignmentStatus = iif(tostring(properties.status.code) == \"Unhealthy\",iif(hasAssignment == true, iif(bin(remediationDueDate, 1d) < bin(now(), 1d), \"Overdue\", \"Ontime\"), \"Unassigned\") , \"Completed\")\r\n| extend Status = assignmentStatus\r\n| summarize Completed = countif(Status == \"Completed\"), Ontime = countif(Status == \"Ontime\"), Overdue = countif(Status == \"Overdue\"),Unassigned = countif(Status == \"Unassigned\") by DisplayName = tostring(properties.displayName)\r\n| sort by Overdue desc", + "size": 0, + "title": "Recommendations", + "noDataMessage": "No Assessments found", + "exportedParameters": [ + { + "fieldName": "id", + "parameterName": "id", + "parameterType": 1 + }, + { + "fieldName": "DisplayName", + "parameterName": "DisplayName", + "parameterType": 1 + } + ], + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "DisplayName", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "75ch" + } + }, + { + "columnMatch": "Completed", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "!=", + "thresholdValue": "0", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Blank", + "text": "{0}{1}" + } + ], + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "Ontime", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "!=", + "thresholdValue": "0", + "representation": "1", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Blank", + "text": "{0}{1}" + }, + { + "representation": "Unknown", + "text": "{0}{1}" + } + ], + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "Overdue", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "!=", + "thresholdValue": "0", + "representation": "3", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Blank", + "text": "{0}{1}" + } + ], + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "Unassigned", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "!=", + "thresholdValue": "0", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Blank", + "text": "0" + } + ], + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "Status", + "formatter": 1 + }, + { + "columnMatch": "id", + "formatter": 1, + "formatOptions": { + "customColumnWidthSetting": "90ch" + } + }, + { + "columnMatch": "owner", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "40ch" + } + }, + { + "columnMatch": "DueDate", + "formatter": 6 + }, + { + "columnMatch": "Severity", + "formatter": 5 + }, + { + "columnMatch": "Resource", + "formatter": 13, + "formatOptions": { + "linkTarget": "OpenBlade", + "linkIsContextBlade": false, + "showIcon": true, + "bladeOpenContext": { + "bladeName": "GenericResourceHealthDetailsBlade", + "extensionName": "Microsoft_Azure_Security", + "bladeParameters": [ + { + "name": "resourceId", + "source": "cell", + "value": "%2Fsubscriptions%2F3b5bc982-20bc-4b59-b1ca-f8488bb86736%2FresourceGroups%2Fdemo%2Fproviders%2FMicrosoft.HybridCompute%2Fmachines%2FW2019" + } + ] + }, + "customColumnWidthSetting": "20ch" + } + }, + { + "columnMatch": "ResourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true, + "customColumnWidthSetting": "25ch" + } + }, + { + "columnMatch": "Source", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "OperatingSystem", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "25ch" + } + }, + { + "columnMatch": "Category", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "20ch" + } + }, + { + "columnMatch": "Remediation", + "formatter": 5 + }, + { + "columnMatch": "RemediationSteps", + "formatter": 11, + "formatOptions": { + "linkColumn": "Remediation", + "linkTarget": "Url" + }, + "tooltipFormat": { + "tooltip": "Click to view remediation steps" + } + }, + { + "columnMatch": "Code", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "Healthy", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Unhealthy", + "representation": "3", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "rowLimit": 10000, + "filter": true, + "sortBy": [ + { + "itemKey": "$gen_thresholds_Ontime_2", + "sortOrder": 2 + } + ], + "labelSettings": [ + { + "columnId": "DisplayName", + "label": "Display name" + } + ] + }, + "sortBy": [ + { + "itemKey": "$gen_thresholds_Ontime_2", + "sortOrder": 2 + } + ] + }, + "customWidth": "50", + "conditionalVisibility": { + "parameterName": "Rule", + "comparison": "isNotEqualTo" + }, + "name": "Assessmetns" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "" + }, + "customWidth": "50", + "conditionalVisibility": { + "parameterName": "RuleConditionSet", + "comparison": "isNotEqualTo" + }, + "name": "empty text" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "securityresources \r\n| where type == \"microsoft.security/assessments\"\r\n| where isnull(properties.resourceDetails.AwsResourceId) and isnull(properties.resourceDetails.GcpResourceId)\r\n| extend displayNameFilter = tostring(\"{DisplayName}\")\r\n| extend selectedOwner = '{selectedOwner}'\r\n| where displayNameFilter == tostring(properties.displayName)\r\n| join kind=leftouter (securityresources \r\n| where type == \"microsoft.security/assessments/governanceassignments\"\r\n| extend assignedResourceId = tostring(todynamic(properties).assignedResourceId)\r\n| extend remediationDueDate = todatetime(properties.remediationDueDate)\r\n| project id = assignedResourceId, owner = properties.owner,governanceassignmentsProperties = todynamic(properties), remediationDueDate, isGrace = properties.isGracePeriod) on id\r\n| extend hasAssignment = isempty( governanceassignmentsProperties) == false and isnull( governanceassignmentsProperties) == false\r\n| extend assignmentStatus = iif(tostring(properties.status.code) == \"Unhealthy\",iif(hasAssignment == true, iif(bin(remediationDueDate, 1d) < bin(now(), 1d), \"Overdue\", \"Ontime\"), \"Unassigned\") , \"Completed\")\r\n| extend source = trim(' ', tolower(tostring(properties.resourceDetails.Source)))\r\n | extend resourceId = iff(source =~ \"azure\", properties.resourceDetails.Id, iff(source =~ \"aws\" and isnotempty(tostring(properties.resourceDetails.ConnectorId)), properties.resourceDetails.Id, iff(source =~ \"gcp\" and isnotempty(tostring(properties.resourceDetails.ConnectorId)), properties.resourceDetails.Id, iff(source =~ 'aws', properties.resourceDetails.AzureResourceId, iff(source =~ 'gcp', properties.resourceDetails.AzureResourceId, properties.resourceDetails.Id)))))\r\n| extend owner = tostring(governanceassignmentsProperties.owner)\r\n| extend owner = iif(isnull(owner) == false and isempty(owner) == false and hasAssignment == true , owner, iif(hasAssignment == false, owner, \"Unspecified\"))\r\n| where '{selectedOwner}' == '' or (selectedOwner contains owner and hasAssignment == true)\r\n| project [\"Resource\"] = resourceId, Subscription = subscriptionId ,Status = assignmentStatus, Owner = owner, [\"Due date\"] = remediationDueDate, [\"Grace period enabled\"] = isGrace\r\n| sort by Status desc", + "size": 0, + "title": "List of resources for: {DisplayName}", + "noDataMessage": "No Assessments found", + "exportFieldName": "id", + "exportParameterName": "id", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Resource id", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": true, + "customColumnWidthSetting": "90ch" + } + }, + { + "columnMatch": "Subscription", + "formatter": 15, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Status", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "Completed", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Unassigned", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Overdue", + "representation": "3", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Ontime", + "representation": "1", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": null, + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "Grace period enabled", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "true", + "representation": "success", + "text": "" + }, + { + "operator": "==", + "thresholdValue": "false", + "representation": "4", + "text": "" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Blank", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "owner", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "40ch" + } + }, + { + "columnMatch": "DueDate", + "formatter": 6 + }, + { + "columnMatch": "id", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "90ch" + } + }, + { + "columnMatch": "DisplayName", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "100ch" + } + }, + { + "columnMatch": "Completed", + "formatter": 4, + "formatOptions": { + "palette": "green", + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "Ontime", + "formatter": 4, + "formatOptions": { + "palette": "blue", + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "Overdue", + "formatter": 4, + "formatOptions": { + "palette": "redBright", + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "Unassigned", + "formatter": 4, + "formatOptions": { + "palette": "orange", + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "Severity", + "formatter": 5 + }, + { + "columnMatch": "Resource", + "formatter": 13, + "formatOptions": { + "linkTarget": "OpenBlade", + "linkIsContextBlade": false, + "showIcon": true, + "bladeOpenContext": { + "bladeName": "GenericResourceHealthDetailsBlade", + "extensionName": "Microsoft_Azure_Security", + "bladeParameters": [ + { + "name": "resourceId", + "source": "cell", + "value": "%2Fsubscriptions%2F3b5bc982-20bc-4b59-b1ca-f8488bb86736%2FresourceGroups%2Fdemo%2Fproviders%2FMicrosoft.HybridCompute%2Fmachines%2FW2019" + } + ] + }, + "customColumnWidthSetting": "20ch" + } + }, + { + "columnMatch": "ResourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true, + "customColumnWidthSetting": "25ch" + } + }, + { + "columnMatch": "Source", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "15ch" + } + }, + { + "columnMatch": "OperatingSystem", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "25ch" + } + }, + { + "columnMatch": "Category", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "20ch" + } + }, + { + "columnMatch": "Remediation", + "formatter": 5 + }, + { + "columnMatch": "RemediationSteps", + "formatter": 11, + "formatOptions": { + "linkColumn": "Remediation", + "linkTarget": "Url" + }, + "tooltipFormat": { + "tooltip": "Click to view remediation steps" + } + }, + { + "columnMatch": "Code", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "Healthy", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Unhealthy", + "representation": "3", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "rowLimit": 10000, + "filter": true + }, + "sortBy": [] + }, + "conditionalVisibility": { + "parameterName": "DisplayName", + "comparison": "isNotEqualTo" + }, + "name": "Assignments" + } + ] + }, + "name": "assessmentsWithExplaination" + }, + { + "type": 1, + "content": { + "json": "💡 Selected filter for **DisplayName:** {DisplayName}\r\n💡 Selected filter for **selectedOwner:** {selectedOwner}\r\n", + "style": "{selectedTab}" + }, + "conditionalVisibility": { + "parameterName": "parameter1", + "comparison": "isEqualTo", + "value": "1" + }, + "name": "ResourceFilter - Copy" + } + ] + }, + "name": "assessmentsGrid" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Governance" + }, + "name": "RC_Governance" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "cc98cfec-0182-4887-854e-536e9f3857da", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": null + }, + { + "id": "1c3411d9-e319-4d74-8e97-61e2f4c56a56", + "version": "KqlParameterItem/1.0", + "name": "Location", + "type": 2, + "isRequired": true, + "query": "resources\r\n| summarize by location\r\n| where location != \"global\"", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": "westeurope" + } + ], + "style": "above", + "queryType": 1, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "parameters - 0" + }, + { + "type": 1, + "content": { + "json": "## Azure subscription and service limits, quotas, and constraints
\r\nTo know more about Azure service limits & quotas, see [Azure subscription and service limits, quotas, and constraints](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=%2Fazure%2Fnetworking%2Ftoc.json#networking-limits)." + }, + "name": "text - Limits" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadFromTemplateId": "community-Workbooks/Common/noSubscriptions", + "items": [] + }, + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isEqualTo", + "value": "" + }, + "name": "No Subscriptions group - RC_Quota" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"path\":\"/subscriptions/{Subscription:id}/providers/microsoft.compute/locations/{Location}/usages?api-version=2022-03-01\",\"urlParams\":[],\"batchDisabled\":false,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.value\",\"columns\":[{\"path\":\"currentValue\",\"columnid\":\"Used\",\"columnType\":\"long\"},{\"path\":\"limit\",\"columnid\":\"Limit\",\"columnType\":\"long\"},{\"path\":\"name.localizedValue\",\"columnid\":\"Resource\"}]}}]}", + "size": 0, + "title": "Compute resource limits", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "filter": true, + "sortBy": [ + { + "itemKey": "Limit", + "sortOrder": 1 + } + ] + }, + "sortBy": [ + { + "itemKey": "Limit", + "sortOrder": 1 + } + ] + }, + "customWidth": "50", + "conditionalVisibilities": [ + { + "parameterName": "Subscription", + "comparison": "isNotEqualTo", + "value": "" + }, + { + "parameterName": "Location", + "comparison": "isNotEqualTo" + } + ], + "name": "query - ComputeLimits" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"path\":\"/subscriptions/{Subscription:id}/providers/microsoft.network/locations/{Location}/usages?api-version=2022-01-01\",\"urlParams\":[],\"batchDisabled\":false,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.value\",\"columns\":[{\"path\":\"currentValue\",\"columnid\":\"Used\",\"columnType\":\"long\"},{\"path\":\"limit\",\"columnid\":\"Limit\",\"columnType\":\"long\"},{\"path\":\"name.localizedValue\",\"columnid\":\"Resource\"}]}}]}", + "size": 0, + "title": "Network resource limits", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "filter": true, + "sortBy": [ + { + "itemKey": "Limit", + "sortOrder": 1 + } + ] + }, + "sortBy": [ + { + "itemKey": "Limit", + "sortOrder": 1 + } + ] + }, + "customWidth": "50", + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "query - NetworkLimits" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"path\":\"/subscriptions/{Subscription:id}/providers/microsoft.storage/locations/{Location}/usages?api-version=2021-09-01\",\"urlParams\":[],\"batchDisabled\":false,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.value\",\"columns\":[{\"path\":\"currentValue\",\"columnid\":\"Used\",\"columnType\":\"long\"},{\"path\":\"limit\",\"columnid\":\"Limit\",\"columnType\":\"long\"},{\"path\":\"name.localizedValue\",\"columnid\":\"Resource\"}]}}]}", + "size": 4, + "title": "Storage account limits", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "filter": true, + "sortBy": [ + { + "itemKey": "Limit", + "sortOrder": 1 + } + ] + }, + "sortBy": [ + { + "itemKey": "Limit", + "sortOrder": 1 + } + ] + }, + "customWidth": "100", + "conditionalVisibility": { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + }, + "name": "query - StorageLimits" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_Quota" + }, + "name": "Usage + limits" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "Automation", + "expandable": true, + "expanded": true, + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type has 'microsoft.automation'\r\n\tor type has 'microsoft.logic'\r\n\tor type has 'microsoft.web/customapis'\r\n| extend type = case(\r\n\ttype =~ 'microsoft.automation/automationaccounts', 'Automation Accounts',\r\n\ttype == 'microsoft.web/serverfarms', \"App Service Plans\",\r\n\tkind == 'functionapp', \"Azure Functions\", \r\n\tkind == \"api\", \"API Apps\", \r\n\ttype == 'microsoft.web/sites', \"App Services\",\r\n\ttype =~ 'microsoft.web/connections', 'LogicApp Connectors',\r\n\ttype =~ 'microsoft.web/customapis','LogicApp API Connectors',\r\n\ttype =~ 'microsoft.logic/workflows','LogicApps',\r\n\ttype =~ 'microsoft.automation/automationaccounts/runbooks', 'Automation Runbooks',\r\n type =~ 'microsoft.automation/automationaccounts/configurations', 'Automation Configurations',\r\nstrcat(\"Not Translated: \", type))\r\n| summarize count() by type\r\n| where type !has \"Not Translated\"", + "size": 3, + "title": "Count of all resource types", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "type", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "name": "Count of all resource types" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type has 'microsoft.automation'\r\n\t or type has 'microsoft.logic'\r\n\t or type has 'microsoft.web/customapis'\r\n| extend type = case(\r\n\ttype =~ 'microsoft.automation/automationaccounts', 'Automation Accounts',\r\n\ttype =~ 'microsoft.web/connections', 'LogicApp Connectors',\r\n\ttype =~ 'microsoft.web/customapis','LogicApp API Connectors',\r\n\ttype =~ 'microsoft.logic/workflows','LogicApps',\r\n\ttype =~ 'microsoft.automation/automationaccounts/runbooks', 'Automation Runbooks',\r\n\ttype =~ 'microsoft.automation/automationaccounts/configurations', 'Automation Configurations',\r\n\tstrcat(\"Not Translated: \", type))\r\n| extend RunbookType = tostring(properties.runbookType)\r\n| extend LogicAppTrigger = properties.definition.triggers\r\n| extend LogicAppTrigger = iif(type =~ 'LogicApps', case(\r\n\tLogicAppTrigger has 'manual', tostring(LogicAppTrigger.manual.type),\r\n\tLogicAppTrigger has 'Recurrence', tostring(LogicAppTrigger.Recurrence.type),\r\n\tstrcat(\"Unknown Trigger type\", LogicAppTrigger)), LogicAppTrigger)\r\n| extend State = case(\r\n\ttype =~ 'Automation Runbooks', properties.state, \r\n\ttype =~ 'LogicApps', properties.state,\r\n\ttype =~ 'Automation Accounts', properties.state,\r\n\ttype =~ 'Automation Configurations', properties.state,\r\n\t' ')\r\n| extend CreatedDate = case(\r\n\ttype =~ 'Automation Runbooks', properties.creationTime, \r\n\ttype =~ 'LogicApps', properties.createdTime,\r\n\ttype =~ 'Automation Accounts', properties.creationTime,\r\n\ttype =~ 'Automation Configurations', properties.creationTime,\r\n\t' ')\r\n| extend LastModified = case(\r\n\ttype =~ 'Automation Runbooks', properties.lastModifiedTime, \r\n\ttype =~ 'LogicApps', properties.changedTime,\r\n\ttype =~ 'Automation Accounts', properties.lastModifiedTime,\r\n\ttype =~ 'Automation Configurations', properties.lastModifiedTime,\r\n\t' ')\r\n| extend Details = pack_all()\r\n| project Resource=id, subscriptionId, type, resourceGroup, RunbookType, LogicAppTrigger, State, Details", + "size": 0, + "title": "Details", + "noDataMessage": "No resources found", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Resource", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + }, + { + "columnMatch": "Details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true, + "finalBy": "Resource" + } + }, + "tileSettings": { + "titleContent": { + "columnMatch": "type", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "showBorder": true, + "sortCriteriaField": "type", + "sortOrderField": 1 + } + }, + "name": "query - PaaS - Automation Detailed" + } + ] + }, + "name": "Group - Automation", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "App services", + "expandable": true, + "expanded": true, + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type has 'microsoft.web'\r\n\t or type =~ 'microsoft.apimanagement/service'\r\n\t or type =~ 'microsoft.network/frontdoors'\r\n\t or type =~ 'microsoft.network/applicationgateways'\r\n\t or type =~ 'microsoft.appconfiguration/configurationstores'\r\n| extend type = case(\r\n\ttype == 'microsoft.web/serverfarms', \"App Service Plans\",\r\n\tkind == 'functionapp', \"Azure Functions\", \r\n\tkind == \"api\", \"API Apps\", \r\n\ttype == 'microsoft.web/sites', \"App Services\",\r\n\ttype =~ 'microsoft.network/applicationgateways', 'App Gateways',\r\n\ttype =~ 'microsoft.network/frontdoors', 'Front Door',\r\n\ttype =~ 'microsoft.apimanagement/service', 'API Management',\r\n\ttype =~ 'microsoft.web/certificates', 'App Certificates',\r\n\ttype =~ 'microsoft.appconfiguration/configurationstores', 'App Config Stores',\r\n\tstrcat(\"Not Translated: \", type))\r\n| where type !has \"Not Translated\"\r\n| summarize count() by type", + "size": 3, + "title": "Count of all resource types", + "noDataMessage": "No resources found", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Resource", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true, + "finalBy": "Resource" + } + }, + "tileSettings": { + "titleContent": { + "columnMatch": "type", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "showBorder": false, + "sortCriteriaField": "type", + "sortOrderField": 1 + } + }, + "name": "query - PaaS - Apps Overview" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type has 'microsoft.web'\r\n\t or type =~ 'microsoft.apimanagement/service'\r\n\t or type =~ 'microsoft.network/frontdoors'\r\n\t or type =~ 'microsoft.network/applicationgateways'\r\n\t or type =~ 'microsoft.appconfiguration/configurationstores'\r\n| extend type = case(\r\n\ttype == 'microsoft.web/serverfarms', \"App Service Plans\",\r\n\tkind == 'functionapp', \"Azure Functions\", \r\n\tkind == \"api\", \"API Apps\", \r\n\ttype == 'microsoft.web/sites', \"App Services\",\r\n\ttype =~ 'microsoft.network/applicationgateways', 'App Gateways',\r\n\ttype =~ 'microsoft.network/frontdoors', 'Front Door',\r\n\ttype =~ 'microsoft.apimanagement/service', 'API Management',\r\n\ttype =~ 'microsoft.web/certificates', 'App Certificates',\r\n\ttype =~ 'microsoft.appconfiguration/configurationstores', 'App Config Stores',\r\n\tstrcat(\"Not Translated: \", type))\r\n| where type !has \"Not Translated\"\r\n| extend Sku = case(\r\n\ttype =~ 'App Gateways', properties.sku.name, \r\n\ttype =~ 'Azure Functions', properties.sku,\r\n\ttype =~ 'API Management', sku.name,\r\n\ttype =~ 'App Service Plans', sku.name,\r\n\ttype =~ 'App Services', properties.sku,\r\n\ttype =~ 'App Config Stores', sku.name,\r\n\t' ')\r\n| extend State = case(\r\n\ttype =~ 'App Config Stores', properties.provisioningState,\r\n\ttype =~ 'App Service Plans', properties.status,\r\n\ttype =~ 'Azure Functions', properties.state,\r\n\ttype =~ 'App Services', properties.state,\r\n\ttype =~ 'API Management', properties.provisioningState,\r\n\ttype =~ 'App Gateways', properties.provisioningState,\r\n\ttype =~ 'Front Door', properties.provisioningState,\r\n\t' ')\r\n| mv-expand publicIpId = properties.frontendIPConfigurations\r\n| mv-expand publicIpId = publicIpId.properties.publicIPAddress.id\r\n| extend publicIpId = tostring(publicIpId)\r\n\t| join kind=leftouter(\r\n\t \tResources\r\n \t\t| where type =~ 'microsoft.network/publicipaddresses'\r\n \t\t| project publicIpId = id, publicIpAddress = tostring(properties.ipAddress)) on publicIpId\r\n| extend PublicIP = case(\r\n\ttype =~ 'API Management', properties.publicIPAddresses,\r\n\ttype =~ 'App Gateways', publicIpAddress,\r\n type =~ 'App Services', properties.inboundIpAddress,\r\n type =~ 'Azure Functions', properties.inboundIpAddress,\r\n\t' ')\r\n| extend Instances = case(\r\n\ttype =~ 'API Management', sku.capacity,\r\n type =~ 'App Services', properties.siteConfig.numberOfWorkers,\r\n type =~ 'Azure Functions', properties.siteConfig.numberOfWorkers,\r\n type =~ 'App Service Plans', properties.currentNumberOfWorkers,\r\n\t' ')\r\n| extend ServicePlan = case(\r\n type =~ 'App Services', properties.serverFarmId,\r\n type =~ 'Azure Functions', properties.serverFarmId,\r\n\t' ')\r\n| extend Details = pack_all()\r\n| project Resource=id, type, subscriptionId, Sku, State, PublicIP, Instances, ServicePlan, Details", + "size": 0, + "noDataMessage": "No resources found", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Resource", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + }, + { + "columnMatch": "Details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true, + "finalBy": "Resource" + } + }, + "tileSettings": { + "titleContent": { + "columnMatch": "type", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "showBorder": true, + "sortCriteriaField": "type", + "sortOrderField": 1 + } + }, + "name": "query - PaaS - Apps Detailed" + } + ] + }, + "name": "Group - App Services", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "Data", + "expandable": true, + "expanded": true, + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'microsoft.documentdb/databaseaccounts'\r\n\tor type =~ 'microsoft.sql/servers/databases'\r\n\tor type =~ 'microsoft.dbformysql/servers'\r\n\tor type =~ 'microsoft.sql/servers'\r\n or type =~ 'Microsoft.DBforPostgreSQL/servers'\r\n or type =~ 'Microsoft.DBforMariaDB/servers'\r\n or type =~ 'microsoft.dbforpostgresql/flexibleservers'\r\n| extend type = case(\r\n\ttype =~ 'microsoft.documentdb/databaseaccounts', 'CosmosDB',\r\n\ttype =~ 'microsoft.sql/servers/databases', 'SQL DBs',\r\n\ttype =~ 'microsoft.dbformysql/servers', 'MySQL Servers',\r\n\ttype =~ 'microsoft.sql/servers', 'SQL Servers',\r\n type =~ 'Microsoft.DBforPostgreSQL/servers', 'PostgreSQL Servers',\r\n type =~ 'microsoft.dbforpostgresql/flexibleservers', 'PostgreSQL Flexi Servers',\r\n type =~ 'Microsoft.DBforMariaDB/servers', 'MariaDB Servers',\r\n\tstrcat(\"Not Translated: \", type))\r\n| where type !has \"Not Translated\"\r\n| summarize count() by type", + "size": 3, + "title": "Count of all resource types", + "noDataMessage": "No resources found", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "tiles", + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Resource", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true, + "finalBy": "Resource" + } + }, + "tileSettings": { + "titleContent": { + "columnMatch": "type", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "showBorder": true, + "sortCriteriaField": "type", + "sortOrderField": 1 + } + }, + "name": "query - PaaS - Data Overview" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "// data\r\n// Click the \"Run query\" command above to execute the query and see results.\r\nresources \r\n| where type =~ 'microsoft.documentdb/databaseaccounts'\r\n\tor type =~ 'microsoft.sql/servers/databases'\r\n\tor type =~ 'microsoft.dbformysql/servers'\r\n\tor type =~ 'microsoft.sql/servers'\r\n or type =~ 'Microsoft.DBforPostgreSQL/servers'\r\n or type =~ 'Microsoft.DBforMariaDB/servers'\r\n or type =~ 'microsoft.dbforpostgresql/flexibleservers'\r\n| extend type = case(\r\n\ttype =~ 'microsoft.documentdb/databaseaccounts', 'CosmosDB',\r\n\ttype =~ 'microsoft.sql/servers/databases', 'SQL DBs',\r\n\ttype =~ 'microsoft.dbformysql/servers', 'MySQL Servers',\r\n\ttype =~ 'microsoft.sql/servers', 'SQL Servers',\r\n type =~ 'Microsoft.DBforPostgreSQL/servers', 'PostgreSQL Servers',\r\n type =~ 'microsoft.dbforpostgresql/flexibleservers', 'PostgreSQL Flexi Servers',\r\n type =~ 'Microsoft.DBforMariaDB/servers', 'MariaDB Servers',\r\n\tstrcat(\"Not Translated: \", type))\r\n| extend Sku = case(\r\n\ttype =~ 'CosmosDB', properties.databaseAccountOfferType,\r\n\ttype =~ 'SQL DBs', sku.name,\r\n\ttype =~ 'MySQL Servers', sku.name,\r\n type =~ 'PostgreSQL Servers', sku.name,\r\n type =~ 'PostgreSQL Flexi Servers', sku.name,\r\n type =~ 'MariaDB Servers', sku.name,\r\n\t' ')\r\n| extend Status = case(\r\n\ttype =~ 'CosmosDB', properties.provisioningState,\r\n\ttype =~ 'SQL DBs', properties.status,\r\n type =~ 'SQL Servers', properties.state,\r\n\ttype =~ 'MySQL Servers', properties.userVisibleState,\r\n type =~ 'PostgreSQL Servers', properties.state,\r\n type =~ 'PostgreSQL Flexi Servers', properties.state,\r\n type =~ 'MariaDB Servers', properties.userVisibleState,\r\n\t' ')\r\n| extend Endpoint = case(\r\n\ttype =~ 'MySQL Servers', properties.fullyQualifiedDomainName,\r\n\ttype =~ 'SQL Servers', properties.fullyQualifiedDomainName,\r\n\ttype =~ 'CosmosDB', properties.documentEndpoint,\r\n type =~ 'PostgreSQL Servers', properties.fullyQualifiedDomainName,\r\n type =~ 'PostgreSQL Flexi Servers', properties.fullyQualifiedDomainName,\r\n type =~ 'MariaDB Servers', properties.fullyQualifiedDomainName,\r\n\t' ')\r\n| extend PublicNetworkAccess = case(\r\n\ttype =~ 'MySQL Servers', properties.publicNetworkAccess,\r\n\ttype =~ 'SQL Servers', properties.publicNetworkAccess,\r\n type =~ 'PostgreSQL Servers', properties.publicNetworkAccess,\r\n type =~ 'PostgreSQL Flexi Servers', properties.publicNetworkAccess,\r\n type =~ 'MariaDB Servers', properties.publicNetworkAccess,\r\n\t' ')\r\n| extend Version = case(\r\n\ttype =~ 'MySQL Servers', properties.version,\r\n\ttype =~ 'SQL Servers', properties.version,\r\n type =~ 'PostgreSQL Servers', properties.version,\r\n type =~ 'PostgreSQL Flexi Servers', properties.version,\r\n type =~ 'MariaDB Servers', properties.version,\r\n\t' ')\r\n| extend maxSizeGB = todouble(case(\r\n\ttype =~ 'SQL DBs', properties.maxSizeBytes,\r\n\ttype =~ 'MySQL Servers', properties.storageProfile.storageMB,\r\n type =~ 'PostgreSQL Servers', properties.storageProfile.storageMB,\r\n type =~ 'PostgreSQL Flexi Servers', properties.storageProfile.storageMB,\r\n type =~ 'MariaDB Servers', properties.storageProfile.storageMB,\r\n\t' '))\r\n| extend maxSizeGB = iif(type has 'SQL DBs', maxSizeGB /1000 /1000, maxSizeGB)\r\n| extend Details = pack_all()\r\n| project Resource=id, resourceGroup, subscriptionId, type, Sku, Status, Endpoint, Version, PublicNetworkAccess, maxSizeGB, Details\r\n\r\n", + "size": 0, + "title": "Details", + "noDataMessage": "No resources found", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Resource", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 5 + }, + { + "columnMatch": "maxSizeGB", + "formatter": 0, + "numberFormat": { + "unit": 4, + "options": { + "style": "decimal", + "useGrouping": false + } + } + }, + { + "columnMatch": "Details", + "formatter": 7, + "formatOptions": { + "linkTarget": "CellDetails", + "linkLabel": "🔍 View details", + "linkIsContextBlade": true + } + } + ], + "rowLimit": 1000, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true, + "finalBy": "Resource" + } + }, + "tileSettings": { + "titleContent": { + "columnMatch": "type", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "showBorder": true, + "sortCriteriaField": "type", + "sortOrderField": 1 + } + }, + "name": "query - PaaS - Data Detailed" + } + ] + }, + "name": "Data", + "styleSettings": { + "showBorder": true + } + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_PaaS" + }, + { + "parameterName": "Subscription", + "comparison": "isNotEqualTo" + } + ], + "name": "RC_PaaS" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadFromTemplateId": "community-Workbooks/Azure Advisor/AzureServiceRetirement", + "items": [] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RC_ServicesRetirement" + }, + "name": "group - Service retirement" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadFromTemplateId": "community-Workbooks/Common/noSubscriptions", + "items": [] + }, + "conditionalVisibilities": [ + { + "parameterName": "Subscription", + "comparison": "isEqualTo", + "value": "" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "RC_Quota" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "RC_Age" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "RC_ServicesRetirement" + } + ], + "name": "No Subscriptions group" + } + ] + }, + "name": "Azure Governance Workbook" + } + ], + "fallbackResourceIds": [ + "azure monitor" + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/optimization/ftkver.txt b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/optimization/ftkver.txt new file mode 100644 index 000000000000..0e2c93950bb6 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/optimization/ftkver.txt @@ -0,0 +1 @@ +0.7 \ No newline at end of file diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/optimization/main.bicep b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/optimization/main.bicep new file mode 100644 index 000000000000..949c5f7a2a1e --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/optimization/main.bicep @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +targetScope = 'resourceGroup' + +//============================================================================== +// Parameters +//============================================================================== + +@sys.description('Optional. Display name for the workbook used in the Gallery. Must be unique in the resource group.') +param displayName string = 'Cost optimization' + +@sys.description('Optional. Location of the resources. Default: Same as deployment. See https://aka.ms/azureregions.') +param location string = resourceGroup().location + +@sys.description('Optional. Workbook description.') +param description string = 'Reports to help you optimize your cost.' + +@sys.description('Optional. Tags for all resources.') +param tags object = {} + +@sys.description('Optional. Enable telemetry to track anonymous module usage trends, monitor for bugs, and improve future releases.') +param enableDefaultTelemetry bool = true + +//------------------------------------------------------------------------------ +// Variables +//------------------------------------------------------------------------------ + +var version = '' +var workbookJson = string(loadJsonContent('workbook.json')) + +// The last segment of the telemetryId is used to identify this module +var workbookId = '0b2' +var telemetryId = '00f120b5-2007-6120-0000-${workbookId}30126b006' +var finOpsToolkitVersion = loadTextContent('ftkver.txt') + +// Add tags to all resources +var resourceTags = contains(tags, 'ftk-tool') ? tags : union(tags, { + 'ftk-version': finOpsToolkitVersion + 'ftk-tool': '${displayName} workbook' + }) + +//============================================================================== +// Resources +//============================================================================== + +//------------------------------------------------------------------------------ +// Telemetry +// Used to anonymously count the number of times the template has been deployed +// and to track and fix deployment bugs to ensure the highest quality. +// No information about you or your cost data is collected. +//------------------------------------------------------------------------------ + +resource defaultTelemetry 'Microsoft.Resources/deployments@2022-09-01' = if (enableDefaultTelemetry) { + name: 'pid-${telemetryId}-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + metadata: { + _generator: { + name: 'FinOps toolkit' + version: finOpsToolkitVersion + } + } + resources: [] + } + } +} + +//------------------------------------------------------------------------------ +// Workbook +//------------------------------------------------------------------------------ + +resource workbook 'Microsoft.Insights/workbooks@2022-04-01' = { + name: guid(resourceGroup().id, 'Microsoft.Insights/workbooks', displayName) + location: location + tags: resourceTags + kind: 'shared' + properties: { + category: 'workbook' + description: description + displayName: displayName + serializedData: workbookJson + sourceId: 'Azure Monitor' + version: version + } +} + +//============================================================================== +// Outputs +//============================================================================== + +@sys.description('The resource ID of the workbook.') +output workbookId string = workbook.id + +@sys.description('Link to the workbook in the Azure portal.') +output workbookUrl string = '${environment().portal}/#view/AppInsightsExtension/UsageNotebookBlade/ComponentId/Azure%20Monitor/ConfigurationId/${uriComponent(workbook.id)}/Type/${workbook.properties.category}/WorkbookTemplateName/${uriComponent(workbook.properties.displayName)}' diff --git a/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/optimization/workbook.json b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/optimization/workbook.json new file mode 100644 index 000000000000..363caf860663 --- /dev/null +++ b/quickstarts/microsoft.costmanagement/finops-workbooks/workbooks/optimization/workbook.json @@ -0,0 +1,11335 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "ca40468d-4518-43bf-ac6e-0a11d7331e12", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Overview", + "subTarget": "Welcome", + "style": "link" + }, + { + "id": "f280fc2a-f42a-42a4-ad4b-be37ab3e8b48", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Rate optimization", + "subTarget": "RateOptimization", + "style": "link" + }, + { + "id": "26b3c7ef-1a00-4a3f-a773-677f00db9343", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "Usage optimization", + "subTarget": "UsageOptimization", + "style": "link" + } + ] + }, + "name": "links - MainTabs" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "28fdc6e9-2946-4016-8e75-b812ff8f853d", + "cellValue": "SelectedRateOptimizationTab", + "linkTarget": "parameter", + "linkLabel": "Compute", + "subTarget": "Compute", + "style": "link" + }, + { + "id": "4e0a0d2d-1d61-4d04-a35d-93e38d1bac29", + "cellValue": "SelectedRateOptimizationTab", + "linkTarget": "parameter", + "linkLabel": "Storage", + "subTarget": "Storage", + "style": "link" + }, + { + "id": "22d04714-50f4-4d72-baec-e8ccddddc7f3", + "cellValue": "SelectedRateOptimizationTab", + "linkTarget": "parameter", + "linkLabel": "Networking", + "subTarget": "Networking", + "style": "link" + }, + { + "id": "eaedbb0e-e895-4940-80ad-f743c3ab1041", + "cellValue": "SelectedRateOptimizationTab", + "linkTarget": "parameter", + "linkLabel": "Top 10 services", + "subTarget": "Top10Services", + "style": "link" + } + ] + }, + "name": "links - UsageOptimization tabs" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "51aa3a9b-14e0-4c22-a60d-abdbf8813f00", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "label": " Subscription", + "value": [ + "value::all" + ] + }, + { + "id": "f342a111-002a-47fd-807f-0d4ccac0618a", + "version": "KqlParameterItem/1.0", + "name": "ResourceGroup", + "label": "Resource Group", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "resources\r\n| distinct resourceGroup", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "2336f06b-ddaa-4a9e-b72f-a2bec1ea84a9", + "version": "KqlParameterItem/1.0", + "name": "SingleSubHidden", + "type": 1, + "isRequired": true, + "query": "resourcecontainers\r\n| where type==\"microsoft.resources/subscriptions\"\r\n| take 1\r\n| project subscriptionId", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Hidden Subscription" + }, + { + "id": "d6776ffe-e4f6-4c08-8f9e-a2fe2b3b6634", + "version": "KqlParameterItem/1.0", + "name": "TagName", + "type": 2, + "query": "Resources\r\n| where tags != '' and tags != '[]'\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| distinct tagName\r\n| sort by tagName asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Name" + }, + { + "id": "f73dc4a1-ef8b-45c5-a30b-a11bb077a3cc", + "version": "KqlParameterItem/1.0", + "name": "TagValue", + "type": 2, + "query": "Resources\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| extend tagValue = tostring(tags[tagName])\r\n| where tags != '' and tags != '[]' and tostring(bag_keys(tags)[0]) == '{TagName}'\r\n| distinct tagValue\r\n| sort by tagValue asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Value" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "75", + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "UsageOptimization" + }, + "name": "parameters - Filters" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadFromTemplateId": "", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "37ceb1c3-3930-4689-a90b-22f26e42bd81", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "label": " Subscription" + }, + { + "id": "08f5fe68-c2e3-4882-9300-b3e33f572dfe", + "version": "KqlParameterItem/1.0", + "name": "ResourceGroup", + "label": "Resource Group", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "resources\r\n| distinct resourceGroup", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "4fea3013-df84-4930-a453-8a6bd0375130", + "version": "KqlParameterItem/1.0", + "name": "SingleSubHidden", + "type": 1, + "isRequired": true, + "query": "resourcecontainers\r\n| where type==\"microsoft.resources/subscriptions\"\r\n| take 1\r\n| project subscriptionId", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Hidden Subscription" + }, + { + "id": "8412f39d-ee67-4979-b887-47463b8848c2", + "version": "KqlParameterItem/1.0", + "name": "TagName", + "type": 2, + "query": "Resources\r\n| where tags != '' and tags != '[]'\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| distinct tagName\r\n| sort by tagName asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Name" + }, + { + "id": "50c68f38-13a0-4aff-a259-4426c83b7cc0", + "version": "KqlParameterItem/1.0", + "name": "TagValue", + "type": 2, + "query": "Resources\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| extend tagValue = tostring(tags[tagName])\r\n| where tags != '' and tags != '[]' and tostring(bag_keys(tags)[0]) == '{TagName}'\r\n| distinct tagValue\r\n| sort by tagValue asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Value" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "75", + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "CostInformation" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "Welcome" + } + ], + "name": "parameters - Filters" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "eae8a0d2-14e6-4cd1-a2d2-fd6b207cf517", + "version": "KqlParameterItem/1.0", + "name": "Location", + "type": 2, + "query": "Resources\r\n| where type =~ 'Microsoft.Compute/virtualMachines'\r\n| project name, location\r\n| summarize count () by location\r\n| project location", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::1" + ] + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Resource Location" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "25", + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + "name": "parameters - location" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "eae8a0d2-14e6-4cd1-a2d2-fd6b207cf517", + "version": "KqlParameterItem/1.0", + "name": "Location", + "type": 2, + "query": "Resources\r\n| where type =~ 'Microsoft.Compute/virtualMachines'\r\n| project name, location\r\n| summarize count () by location\r\n| project location", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::1" + ] + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Resource Location" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "25", + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + "name": "parameters - location" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "6d563f46-7150-458c-9ee4-0558abe8e29b", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Azure App Service", + "subTarget": "webapp", + "style": "link" + }, + { + "id": "dbe9a7fb-6ab1-4de1-a98b-4ec8a9af906c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Azure Kubernetes Service", + "subTarget": "AKS", + "style": "link" + }, + { + "id": "0211f413-9f36-4750-9ef2-d382ba30ba6c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Azure Synapse", + "subTarget": "Synapse", + "preText": "VM", + "style": "link" + }, + { + "id": "820d600c-8ab3-4622-ba5a-52f60574d111", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Monitoring", + "subTarget": "Monitoring", + "style": "link" + } + ] + }, + "name": "links - Storage" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Synapse\r\nA Synapse Workspace is considered unused if it doesn't have any SQL pools attached to it\r\n", + "style": "upsell" + }, + "name": "Synapse" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n| where type =~ 'Microsoft.Synapse/workspaces'\r\n| join kind=leftouter (\r\n Resources\r\n | where type =~ 'Microsoft.Synapse/workspaces/sqlPools'\r\n | extend SynapseWorkspaceResourceId = substring(id, 0, indexof(id, '/sqlPools/'))\r\n | summarize sqlpoolCount = count() by SynapseWorkspaceResourceId\r\n) on $left.id == $right.SynapseWorkspaceResourceId\r\n| join kind=leftouter (\r\n Resources\r\n | where type =~ 'Microsoft.Synapse/workspaces/bigDataPools'\r\n | extend SynapseWorkspaceResourceId = substring(id, 0, indexof(id, '/bigDataPools/'))\r\n | summarize bigdatapoolCount = count() by SynapseWorkspaceResourceId\r\n) on $left.id == $right.SynapseWorkspaceResourceId\r\n| where (isnull(sqlpoolCount) or sqlpoolCount == 0) and (isnull(bigdatapoolCount) or bigdatapoolCount == 0)\r\n| project id, resourceGroup, subscriptionId, location\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "title": "Unused Synapase workspace", + "noDataMessage": "All of your Synapse workspaces have SQL pools.", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + }, + { + "columnMatch": "storageaccount", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "subTarget": "insights", + "linkIsContextBlade": true, + "showIcon": true + } + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Resource ID" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Name" + } + ] + } + }, + "name": "Get-Synapse1" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "Synapse" + }, + "name": "SynapseGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Azure Kubernetes Service\r\n- Enable cluster autoscaler to automatically adjust the number of agent nodes in response to resource constraints\r\n\r\n- Consider using Azure Spot VMs for workloads that can handle interruptions, early terminations, or evictions. For example, workloads such as batch processing jobs, development and testing environments, and large compute workloads may be good candidates to be scheduled on a spot node pool.\r\n\r\n- Utilize the Horizontal pod autoscaler to adjust the number of pods in a deployment depending on CPU utilization or other select metrics.\r\n\r\n- Use the Start/Stop feature in Azure Kubernetes Services (AKS).\r\n\r\n", + "style": "upsell" + }, + "name": "Azure Kubernetes Service" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "\tresources\r\n | where resourceGroup in ({ResourceGroup})\r\n\t| where type == \"microsoft.containerservice/managedclusters\"\r\n\t| extend AKSname=name,location=location,Sku=tostring(sku.name),Tier=tostring(sku.tier),AgentPoolProfiles=properties.agentPoolProfiles\r\n | project id,AKSname,resourceGroup,subscriptionId,Sku,Tier,AgentPoolProfiles,location\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id\r\n\t| mvexpand AgentPoolProfiles\r\n\t| extend ProfileName = tostring(AgentPoolProfiles.name) ,mode=AgentPoolProfiles.mode,AutoScaleEnabled = AgentPoolProfiles.enableAutoScaling ,SpotVM=AgentPoolProfiles.scaleSetPriority, VMSize=tostring(AgentPoolProfiles.vmSize),minCount=tostring(AgentPoolProfiles.minCount),maxCount=tostring(AgentPoolProfiles.maxCount) , nodeCount=tostring(AgentPoolProfiles.['count'])\r\n | project id,ProfileName,Sku,Tier,mode,AutoScaleEnabled,SpotVM, VMSize,nodeCount,minCount,maxCount,location,resourceGroup,subscriptionId,AKSname\r\n \r\n", + "size": 0, + "noDataMessage": "You have no AKS clusters!", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "AKS Name", + "formatter": 1 + }, + { + "columnMatch": "id", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "subTarget": "Insights", + "showIcon": true + } + }, + { + "columnMatch": "mode", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "System", + "representation": "Gear", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "User", + "representation": "Person", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "AutoScaleEnabled", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "true", + "representation": "success", + "text": "Enabled" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "disabled", + "text": "Disabled" + } + ] + } + }, + { + "columnMatch": "SpotVM", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "is Empty", + "representation": "2", + "text": "{0}{1}Not Spot VM" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Group", + "formatter": 1 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "AKSname", + "formatter": 5 + } + ], + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "AKSname" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "id", + "label": "ID" + }, + { + "columnId": "ProfileName", + "label": "Profile Name" + }, + { + "columnId": "Sku", + "label": "SKU" + }, + { + "columnId": "Tier", + "label": "SKU Tier" + }, + { + "columnId": "mode", + "label": "Mode" + }, + { + "columnId": "AutoScaleEnabled", + "label": "Autoscale enabled?" + }, + { + "columnId": "SpotVM", + "label": "Spot VM?" + }, + { + "columnId": "VMSize", + "label": "VM SKU" + }, + { + "columnId": "nodeCount", + "label": "Number of nodes" + }, + { + "columnId": "minCount", + "label": "Minimum nodes" + }, + { + "columnId": "maxCount", + "label": "Maximum nodes" + }, + { + "columnId": "location", + "label": "Location" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Name" + }, + { + "columnId": "AKSname", + "label": "AKS Name" + } + ] + } + }, + "name": "Get-All-AKS" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "AKS" + }, + "name": "AKSGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Azure App Service\r\n## Save with Premium v3 reserved instances\r\nWhen you commit to an Azure App Service Premium v3 reserved instance you can save money. The reservation discount is applied automatically to the number of running instances that match the reservation scope and attributes - you don't need to assign a reservation to a specific instance to get the discounts.\r\n\r\n## Determine the right reserved instance size before you buy\r\nBefore you buy a reservation, you should determine the size of the Premium v3 reserved instance that you need. The following sections will help you determine the right Premium v3 reserved instance size.\r\n\r\n## Use Autoscale appropriately\r\nAutoscale can be used to provision resources for when they're needed or on demand, which allows you to minimize costs when your environment is idle.\r\n", + "style": "upsell" + }, + "name": "Azure App Service" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'Microsoft.Web/sites'\r\n| extend WebAppRG=resourceGroup, WebAppName=name, AppServicePlan=tostring(properties.serverFarmId), SKU=tostring(properties.sku), Type=kind, Status=tostring(properties.state), WebAppLocation=location, SubscriptionName=subscriptionId\r\n| project id,WebAppName, Type, Status, WebAppLocation, AppServicePlan, WebAppRG,SubscriptionName\r\n| order by id asc\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "Never" + }, + "name": "query - WebFunctionStatus" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where resourceGroup in ({ResourceGroup})\r\n| where type == \"microsoft.web/serverfarms\" and sku.tier !~ 'Free'\r\n| extend planId=tolower(tostring(id)),skuname = tostring(sku.name) , skutier = tostring(sku.tier), workers=tostring(properties.numberOfWorkers),webRG=resourceGroup,maxworkers=tostring(properties.maximumNumberOfWorkers), Sites=tostring(properties.numberOfSites), SubscriptionName=subscriptionId\r\n| project planId, name, skuname, skutier, workers, maxworkers, webRG, Sites, SubscriptionName\r\n| join kind=leftouter (resources | where type ==\"microsoft.insights/autoscalesettings\" | project planId=tolower(tostring(properties.targetResourceUri)), PredictiveAutoscale=properties.predictiveAutoscalePolicy.scaleMode, AutoScaleProfiles=properties.profiles,resourceGroup) on planId\r\n", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "Never" + }, + "name": "query - AppServiceplandetails" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\",\"mergeType\":\"inner\",\"leftTable\":\"query - AppServiceplandetails\",\"rightTable\":\"query - WebFunctionStatus\",\"leftColumn\":\"planId\",\"rightColumn\":\"AppServicePlan\"}],\"projectRename\":[{\"originalName\":\"[query - AppServiceplandetails].type\",\"mergedName\":\"type\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].tenantId\",\"mergedName\":\"tenantId\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].kind\",\"mergedName\":\"kind\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].location\",\"mergedName\":\"location\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].managedBy\",\"mergedName\":\"managedBy\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].sku\",\"mergedName\":\"sku\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].plan\",\"mergedName\":\"plan\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].properties\",\"mergedName\":\"properties\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].tags\",\"mergedName\":\"tags\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].identity\",\"mergedName\":\"identity\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].zones\",\"mergedName\":\"zones\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].extendedLocation\",\"mergedName\":\"extendedLocation\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].planId\",\"mergedName\":\"planId\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - WebFunctionStatus].id\",\"mergedName\":\"id\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].name\",\"mergedName\":\"name\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - WebFunctionStatus].Status\",\"mergedName\":\"Status\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - WebFunctionStatus].Type\",\"mergedName\":\"Type\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - AppServiceplandetails].skuname\",\"mergedName\":\"skuname\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - AppServiceplandetails].skutier\",\"mergedName\":\"skutier\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - AppServiceplandetails].PredictiveAutoscale\",\"mergedName\":\"PredictiveAutoscale\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].AutoScaleProfiles\",\"mergedName\":\"AutoScaleProfiles\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - AppServiceplandetails].workers\",\"mergedName\":\"workers\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - AppServiceplandetails].maxworkers\",\"mergedName\":\"maxworkers\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - AppServiceplandetails].webRG\",\"mergedName\":\"webRG\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - AppServiceplandetails].planId1\",\"mergedName\":\"planId1\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - AppServiceplandetails].resourceGroup\",\"mergedName\":\"resourceGroup\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - WebFunctionStatus].WebAppName\",\"mergedName\":\"WebAppName\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - WebFunctionStatus].WebAppLocation\",\"mergedName\":\"WebAppLocation\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - WebFunctionStatus].AppServicePlan\",\"mergedName\":\"AppServicePlan\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - WebFunctionStatus].WebAppRG\",\"mergedName\":\"WebAppRG\",\"fromId\":\"3fddbdd9-c4eb-46ae-b6b0-654c0da7b1a8\"},{\"originalName\":\"[query - AppServiceplandetails].Sites\",\"mergedName\":\"Sites\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - WebFunctionStatus].SubscriptionName\"},{\"originalName\":\"[query - WebFunctionStatus].id1\"},{\"originalName\":\"[query - AppServiceplandetails].resourceGroup1\"}]}", + "size": 0, + "title": "Web Apps", + "noDataMessage": "You have no WebApps!", + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "Name", + "formatter": 1 + }, + { + "columnMatch": "SubscriptionName", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "name", + "formatter": 5 + }, + { + "columnMatch": "Status", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "Running", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Stopped", + "representation": "disabled", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "webRG", + "formatter": 5 + }, + { + "columnMatch": "planId1", + "formatter": 5 + }, + { + "columnMatch": "resourceGroup", + "formatter": 5 + }, + { + "columnMatch": "WebAppName", + "formatter": 5 + }, + { + "columnMatch": "AppServicePlan", + "formatter": 5 + }, + { + "columnMatch": "WebAppRG", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 1 + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "name" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "planId", + "label": "Plan ID" + }, + { + "columnId": "id", + "label": "ID" + }, + { + "columnId": "name", + "label": "Name" + }, + { + "columnId": "skuname", + "label": "SKU" + }, + { + "columnId": "skutier", + "label": "SKU Tier" + }, + { + "columnId": "PredictiveAutoscale", + "label": "Autoscale Enabled?" + }, + { + "columnId": "AutoScaleProfiles", + "label": "Autoscale Profile" + }, + { + "columnId": "workers", + "label": "Workers" + }, + { + "columnId": "maxworkers", + "label": "Max. Workers" + }, + { + "columnId": "webRG", + "label": "Application Resource Group" + }, + { + "columnId": "WebAppName", + "label": "Application Name" + }, + { + "columnId": "WebAppLocation", + "label": "Application Location" + }, + { + "columnId": "AppServicePlan", + "label": "App Service Plan" + }, + { + "columnId": "WebAppRG", + "label": "Application Resource Group" + } + ] + } + }, + "name": "Get-Idle-WebApp" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where resourceGroup in ({ResourceGroup})\r\n| where type == \"microsoft.web/serverfarms\" and properties.numberOfSites == \"0\"\r\n| extend id, planId=tolower(tostring(id)),skuname = tostring(sku.name) , skutier = tostring(sku.tier), workers=tostring(properties.numberOfWorkers),webRG=resourceGroup,maxworkers=tostring(properties.maximumNumberOfWorkers), Sites=tostring(properties.numberOfSites), SubscriptionName=subscriptionId\r\n| project id, planId, name, skuname, skutier, workers, maxworkers, webRG, Sites, SubscriptionName\r\n| join kind=leftouter (resources | where type ==\"microsoft.insights/autoscalesettings\" | project planId=tolower(tostring(properties.targetResourceUri)), PredictiveAutoscale=properties.predictiveAutoscalePolicy.scaleMode, AutoScaleProfiles=properties.profiles,resourceGroup) on planId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n ) on id", + "size": 0, + "noDataMessage": "All of your App Service's plan have at least one website.", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 5 + }, + { + "columnMatch": "name", + "formatter": 5 + }, + { + "columnMatch": "maxworkers", + "formatter": 5 + }, + { + "columnMatch": "SubscriptionName", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "planId1", + "formatter": 5 + }, + { + "columnMatch": "PredictiveAutoscale", + "formatter": 5 + }, + { + "columnMatch": "AutoScaleProfiles", + "formatter": 5 + }, + { + "columnMatch": "resourceGroup", + "formatter": 5 + }, + { + "columnMatch": "id1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "planId", + "label": "App Service Plan " + }, + { + "columnId": "name", + "label": "SKU Name" + }, + { + "columnId": "skuname", + "label": "SKU Name" + }, + { + "columnId": "skutier", + "label": "SKU Tier" + }, + { + "columnId": "workers", + "label": "Number of Workers " + }, + { + "columnId": "maxworkers", + "label": "Number of websites" + }, + { + "columnId": "webRG", + "label": "Resource Group " + }, + { + "columnId": "Sites", + "label": "Number of websites" + }, + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + } + ] + } + }, + "name": "query - IdleServicePlans" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "webapp" + }, + "name": "WebAppGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Log Analytics workspace\r\nA [Log Analytics workspace](https://learn.microsoft.com/azure/azure-monitor/logs/log-analytics-workspace-overview) is a unique environment for log data from Azure Monitor and other Azure services, such as Microsoft Sentinel and Microsoft Defender for Cloud. Each workspace has its own data repository and configuration but might combine data from multiple services. The following advices could be of help in cost optimization:\r\n\r\n1. Adopt [commitment tiers](https://learn.microsoft.com/azure/azure-monitor/logs/cost-logs#commitment-tiers) where applicable.\r\n2. Adopt [Azure Monitor Logs dedicated cluster](https://learn.microsoft.com/azure/azure-monitor/logs/cost-logs#dedicated-clusters) if a single workspace does not ingest enough data as per the minimum commitment tier (100 GB/day) or if it is possible to aggregate ingestion costs from more than one workspace in the same region.\r\n3. Convert the free tier based workspace to **Pay-as-you-go** model and add them to an Azure Monitor Logs dedicated cluster where possible.", + "style": "upsell" + }, + "name": "MonitoringRecommendations" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type =~ 'microsoft.operationalinsights/workspaces'\r\n| where resourceGroup in ({ResourceGroup})\r\n| extend \r\n state = trim(' ', tostring(properties.provisioningState)),\r\n sku = trim(' ', tostring(properties.sku.name)),\r\n skuUpdate = trim(' ', tostring(properties.sku.lastSkuUpdate)),\r\n retentionDays = toint(properties.retentionInDays),\r\n dailyquotaGB = trim(' ', tostring(properties.workspaceCapping.dailyQuotaGb))\r\n| extend dailyquotaGB = iif(dailyquotaGB !=-1.0, dailyquotaGB,\"--\")\r\n| project id, resourceGroup, location, retentionDays, dailyquotaGB, sku, subscriptionId\r\n| join kind = inner (\r\n resources\r\n | where type =~ 'microsoft.operationalinsights/workspaces'\r\n | where resourceGroup in ({ResourceGroup})\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags[tagName])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | summarize arg_max(tagName, tagValue) by id\r\n) on id\r\n| extend resourceGroup = tostring(split(id,'/providers/')[0])\r\n| project-away id1", + "size": 0, + "title": "Log Analytics Workspaces", + "showRefreshButton": true, + "exportMultipleValues": true, + "exportedParameters": [ + { + "fieldName": "id", + "parameterName": "selectedWorkspaceId", + "parameterType": 1 + } + ], + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "subTarget": "insights", + "linkIsContextBlade": true, + "showIcon": true + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": "Resource", + "linkIsContextBlade": true, + "showIcon": true + } + }, + { + "columnMatch": "retentionDays", + "formatter": 4, + "formatOptions": { + "min": 1, + "max": 730, + "palette": "blue", + "customColumnWidthSetting": "10%" + } + }, + { + "columnMatch": "dailyquotaGB", + "formatter": 0, + "formatOptions": { + "customColumnWidthSetting": "10%" + } + }, + { + "columnMatch": "sku", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "lacluster", + "representation": "green", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "free", + "representation": "gray", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "capacityreservation", + "representation": "green", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "red", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": "Resource", + "linkIsContextBlade": true, + "showIcon": true + } + }, + { + "columnMatch": "tagName", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "is Empty", + "representation": "Blank", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Tags", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "tagValue", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "is Empty", + "representation": "Blank", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Tags", + "text": "{0}{1}" + } + ] + } + } + ], + "rowLimit": 10000, + "filter": true, + "labelSettings": [ + { + "columnId": "id", + "label": "Workspace" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "location", + "label": "Location" + }, + { + "columnId": "retentionDays", + "label": "Retention (days)" + }, + { + "columnId": "dailyquotaGB", + "label": "Daily Cap (GB)" + }, + { + "columnId": "sku", + "label": "Pricing Tier" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + }, + { + "columnId": "tagName", + "label": "Tag Name" + }, + { + "columnId": "tagValue", + "label": "Tag Value" + } + ] + }, + "sortBy": [] + }, + "name": "logAnalyticsWorkspaces", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 1, + "content": { + "json": "💡_Select one or more workspaces from the list above to see daily ingestion trend_" + }, + "conditionalVisibility": { + "parameterName": "selectedWorkspaceId", + "comparison": "isEqualTo" + }, + "name": "text - 3", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "d9c04e61-453f-4f85-8d7e-1a34037d836b", + "version": "KqlParameterItem/1.0", + "name": "selectedWorkspaces", + "type": 5, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "where type =~ 'microsoft.operationalinsights/workspaces'\r\n| where id in ({selectedWorkspaceId})", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "timeContext": { + "durationMs": 2592000000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null + }, + { + "id": "2108523c-fb80-49b3-9ff1-ea5e5eca2091", + "version": "KqlParameterItem/1.0", + "name": "TimeRange", + "label": "Time range", + "type": 4, + "isRequired": true, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 172800000 + }, + { + "durationMs": 604800000 + }, + { + "durationMs": 1209600000 + }, + { + "durationMs": 2592000000 + } + ] + }, + "timeContext": { + "durationMs": 2592000000 + }, + "value": { + "durationMs": 2592000000 + } + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "conditionalVisibility": { + "parameterName": "_", + "comparison": "isEqualTo", + "value": "_" + }, + "name": "parameters - 2" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Usage\r\n| where StartTime >= startofday({TimeRange:start}) and EndTime < startofday(now())\r\n| where IsBillable == true\r\n| project Quantity, ResourceUri, TimeGenerated\r\n| summarize BillableDataGB = sum(Quantity / 1024.) by bin(TimeGenerated, 1d)\r\n| project TimeGenerated, BillableDataGB", + "size": 0, + "aggregation": 5, + "title": "Total Daily Ingestion for selected workspaces - Trend by {TimeRange:label}", + "timeContextFromParameter": "TimeRange", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "crossComponentResources": [ + "{selectedWorkspaces}" + ], + "visualization": "barchart", + "chartSettings": { + "seriesLabelSettings": [ + { + "seriesName": "BillableDataGB", + "label": "Ingested data" + } + ], + "ySettings": { + "numberFormatSettings": { + "unit": 39, + "options": { + "style": "decimal", + "useGrouping": true, + "maximumFractionDigits": 2 + } + } + } + } + }, + "conditionalVisibility": { + "parameterName": "selectedWorkspaceId", + "comparison": "isNotEqualTo" + }, + "name": "dailyIngestionTrend", + "styleSettings": { + "showBorder": true + } + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "Monitoring" + }, + "name": "MonitoringGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "advisorresources\r\n| where type =~ 'microsoft.advisor/recommendations'\r\n| where resourceGroup in ({ResourceGroup})\r\n| where properties.category == 'Cost' and properties.lastUpdated >= ago(1d)\r\n| where properties.impactedField has \"Workspaces\"\r\n| extend AffectedResource=tostring(properties.resourceMetadata.resourceId), Category=properties.category, SubCategory=properties.impactedField, Impact=properties.impact,resourceGroup,subscriptionId,Recommendation=tostring(properties.shortDescription.problem), id, stableId = name, recommendationTypeId = tostring(properties.recommendationTypeId), maxCpuP95 = properties.extendedProperties.MaxCpuP95\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| project AffectedResource=tostring(properties.resourceMetadata.resourceId), Category=properties.category, SubCategory=properties.impactedField, Recommendation=tostring(properties.shortDescription.problem), Impact=properties.impact,resourceGroup,subscriptionId, id, stableId = name, recommendationTypeId = tostring(properties.recommendationTypeId), maxCpuP95 = properties.extendedProperties.MaxCpuP95\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isempty(resourceGroup) == true\r\n| project subscriptionId, excludeRecomm = properties.exclude, lowCpuThreshold = properties.lowCpuThreshold, AffectedResource=tostring(properties.resourceMetadata.resourceId),Impact=properties.impact,resourceGroup,AdditionaInfo=properties.extendedProperties,Recommendation=tostring(properties.shortDescription.problem))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| where Category == 'Cost' \r\n| where SubCategory has \"Workspaces\"\r\n| project-away subscriptionId1, subscriptionId2, AffectedResource1, isActive2, isActive3, Impact1, Recommendation1, resourceGroup1, resourceGroup2", + "size": 0, + "title": "Azure Advisor Cost recommendations", + "noDataMessage": "You are following all of our cost recommendations for Monitoring", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Group", + "formatter": 1 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id", + "formatter": 5 + }, + { + "columnMatch": "stableId", + "formatter": 5 + }, + { + "columnMatch": "recommendationTypeId", + "formatter": 5 + }, + { + "columnMatch": "maxCpuP95", + "formatter": 5 + }, + { + "columnMatch": "excludeRecomm", + "formatter": 5 + }, + { + "columnMatch": "lowCpuThreshold", + "formatter": 5 + }, + { + "columnMatch": "AdditionaInfo", + "formatter": 5, + "formatOptions": { + "customColumnWidthSetting": "19ch" + } + }, + { + "columnMatch": "isActive1", + "formatter": 5 + }, + { + "columnMatch": "excludeProperty", + "formatter": 5 + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Recommendation" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "AffectedResource", + "label": "Affected Resource" + }, + { + "columnId": "Category", + "label": "Recommendation Category" + }, + { + "columnId": "SubCategory", + "label": "Affected Resource Type" + }, + { + "columnId": "Recommendation", + "label": "Recommendation" + }, + { + "columnId": "Impact", + "label": "Impact" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "Get-AdvisorRecommendations-Monitoring" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": " resources\r\n | where resourceGroup in ({ResourceGroup})\r\n | where type has \"microsoft.operationalinsights/workspaces\"\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend AffectedResource=id,ResourceRG=resourceGroup\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n | project id", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "rowLimit": 10000 + } + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "query - tags - list all network resources" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\",\"mergeType\":\"innerunique\",\"leftTable\":\"Get-AdvisorRecommendations-Monitoring\",\"rightTable\":\"query - tags - list all network resources\",\"leftColumn\":\"AffectedResource\",\"rightColumn\":\"id\"}],\"projectRename\":[{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].AffectedResource\",\"mergedName\":\"Affected Resource\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].Category\",\"mergedName\":\"Recommendation Category\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].SubCategory\",\"mergedName\":\"Affected Resource Type\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].Recommendation\",\"mergedName\":\"Recommendation\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].Impact\",\"mergedName\":\"Impact\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].resourceGroup\",\"mergedName\":\"Resource Group\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].subscriptionId\",\"mergedName\":\"Subscription ID\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].id\",\"mergedName\":\"id\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].stableId\",\"mergedName\":\"stableId\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].recommendationTypeId\",\"mergedName\":\"recommendationTypeId\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].maxCpuP95\",\"mergedName\":\"maxCpuP95\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].excludeRecomm\",\"mergedName\":\"excludeRecomm\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].lowCpuThreshold\",\"mergedName\":\"lowCpuThreshold\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].AdditionaInfo\",\"mergedName\":\"AdditionaInfo\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].isActive1\",\"mergedName\":\"isActive1\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Monitoring].excludeProperty\",\"mergedName\":\"excludeProperty\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[query - tags - list all network resources].id\",\"mergedName\":\"id1\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].excludeProperty\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].isActive1\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].AdditionaInfo\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].lowCpuThreshold\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].excludeRecomm\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].maxCpuP95\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].recommendationTypeId\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].stableId\"},{\"originalName\":\"[query - tags - list all network resources].id\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].id\"}]}", + "size": 0, + "title": "Azure Advisor Cost recommendations", + "noDataMessage": "You are following all of our cost recommendations for Monitoring", + "noDataMessageStyle": 3, + "queryType": 7 + }, + "showPin": false, + "name": "query - Merge - Monitoring Advisor recommendations" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "Monitoring" + }, + "name": "AdvisorGroupMonitoring" + } + ] + }, + "name": "group - 0 " + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "UsageOptimization" + }, + { + "parameterName": "SelectedRateOptimizationTab", + "comparison": "isEqualTo", + "value": "Top10Services" + } + ], + "name": "group - Top10Services" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadFromTemplateId": "", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "7a720abf-5b4a-4fb1-adaf-2383e70f625d", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "label": " Subscription" + }, + { + "id": "a29babbc-5092-46c5-b03b-932c90aa61c9", + "version": "KqlParameterItem/1.0", + "name": "ResourceGroup", + "label": "Resource Group", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "resources\r\n| distinct resourceGroup", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "4b9c84b6-14ab-4663-b8b7-8bf0c351bbb5", + "version": "KqlParameterItem/1.0", + "name": "SingleSubHidden", + "type": 1, + "isRequired": true, + "query": "resourcecontainers\r\n| where type==\"microsoft.resources/subscriptions\"\r\n| take 1\r\n| project subscriptionId", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Hidden Subscription" + }, + { + "id": "6637e003-5323-4c6d-9990-426388c833e9", + "version": "KqlParameterItem/1.0", + "name": "TagName", + "type": 2, + "query": "Resources\r\n| where tags != '' and tags != '[]'\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| distinct tagName\r\n| sort by tagName asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Name" + }, + { + "id": "d390e2b5-aa2f-494b-bbb8-0b18c8de9063", + "version": "KqlParameterItem/1.0", + "name": "TagValue", + "type": 2, + "query": "Resources\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| extend tagValue = tostring(tags[tagName])\r\n| where tags != '' and tags != '[]' and tostring(bag_keys(tags)[0]) == '{TagName}'\r\n| distinct tagValue\r\n| sort by tagValue asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Value" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "75", + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "CostInformation" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "Welcome" + } + ], + "name": "parameters - Filters" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "ae7eb928-8873-46f8-a3ff-77f45c207fb3", + "version": "KqlParameterItem/1.0", + "name": "Location", + "type": 2, + "query": "Resources\r\n| where type =~ 'Microsoft.Compute/virtualMachines'\r\n| project name, location\r\n| summarize count () by location\r\n| project location", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::1" + ] + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Resource Location" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "25", + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + "name": "parameters - location" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "Networking cost optimization recommendations", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "ae7eb928-8873-46f8-a3ff-77f45c207fb3", + "version": "KqlParameterItem/1.0", + "name": "Location", + "type": 2, + "query": "Resources\r\n| where type =~ 'Microsoft.Compute/virtualMachines'\r\n| project name, location\r\n| summarize count () by location\r\n| project location", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::1" + ] + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Resource Location" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "25", + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + "name": "parameters - location" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "e5d97e9d-97e6-45f2-871c-376799213b6a", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Azure Firewall", + "subTarget": "firewall", + "style": "link" + }, + { + "id": "0211f413-9f36-4750-9ef2-d382ba30ba6c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Application Gateway", + "subTarget": "appGateway", + "preText": "VM", + "style": "link" + }, + { + "id": "61595d5e-9f25-4919-95a6-1462739f4657", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Load Balancer", + "subTarget": "loadBalancer", + "style": "link" + }, + { + "id": "dbe9a7fb-6ab1-4de1-a98b-4ec8a9af906c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Public IP Address", + "subTarget": "publicIP", + "style": "link" + }, + { + "id": "79e7a97a-1413-41e8-b4c6-ebd1d0a45e2e", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Virtual Network Gateway", + "subTarget": "vpnGw", + "style": "link" + }, + { + "id": "5655ef75-a5ec-4f4b-badf-a99191a0493f", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "NAT Gateway", + "subTarget": "natgw", + "style": "link" + }, + { + "id": "68a77162-06c2-4648-83e0-f8f41c4fbda7", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "ExpressRoute", + "subTarget": "ER", + "style": "link" + }, + { + "id": "5dd4cb39-5aa1-4de9-bc4c-338e15b8d389", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Private DNS & Private Endpoint", + "subTarget": "privatedns", + "style": "link" + }, + { + "id": "6d563f46-7150-458c-9ee4-0558abe8e29b", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Advisor recommendations", + "subTarget": "advisorNetworking", + "style": "link" + } + ] + }, + "name": "links - Networking" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Recommendations for Application Gateways\r\nReview Application Gateways which include backend pools with no targets. Resources listed with 2 red signs are considered idle.", + "style": "upsell" + }, + "name": "Recommendations for Application Gateways" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type =~ 'Microsoft.Network/applicationGateways' and resourceGroup in ({ResourceGroup})\r\n| extend backendPoolsCount = array_length(properties.backendAddressPools),SKUName= tostring(properties.sku.name), SKUTier= tostring(properties.sku.tier),SKUCapacity=properties.sku.capacity,backendPools=properties.backendAddressPools,resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)\r\n| project id, name, SKUName, SKUTier, SKUCapacity,resourceGroup,subscriptionId\r\n| join (\r\n resources\r\n | where type =~ 'Microsoft.Network/applicationGateways' and resourceGroup in ({ResourceGroup})\r\n | mvexpand backendPools = properties.backendAddressPools\r\n | extend backendIPCount = array_length(backendPools.properties.backendIPConfigurations)\r\n | extend backendAddressesCount = array_length(backendPools.properties.backendAddresses)\r\n | extend backendPoolName = backendPools.properties.backendAddressPools.name\r\n | summarize backendIPCount = sum(backendIPCount) ,backendAddressesCount=sum(backendAddressesCount) by id\r\n) on id\r\n| project-away id1\r\n| where (backendIPCount == 0 or isempty(backendIPCount)) and (backendAddressesCount==0 or isempty(backendAddressesCount))\r\n| order by id asc\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "title": "Application gateways with empty backend pools", + "noDataMessage": "You don't have any Application Gateways with empty backendpools", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "SKUCapacity", + "formatter": 1 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "backendIPCount", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "0", + "representation": "disabled", + "text": "No Backend IPs" + }, + { + "operator": ">", + "thresholdValue": "0", + "representation": "success", + "text": "Backend IP configured" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "backendAddressesCount", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "0", + "representation": "disabled", + "text": "No Backend targets" + }, + { + "operator": ">", + "thresholdValue": "0", + "representation": "success", + "text": "Backend targets available" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "id1", + "formatter": 5 + }, + { + "columnMatch": "Recommendation", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "No Backend targets", + "representation": "redBright", + "text": "No Backend targets" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "green", + "text": "Backend targets enabled" + } + ] + } + }, + { + "columnMatch": "backendPoolIPTarget", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": ">", + "thresholdValue": "0", + "representation": "success", + "text": "" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "disabled", + "text": "" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "backendPoolVMTarget", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "is Empty", + "representation": "disabled", + "text": "" + }, + { + "operator": ">", + "thresholdValue": "0", + "representation": "success", + "text": "" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Recommednation", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "No Backend targets", + "representation": "redBright", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "green", + "text": "{0}{1}" + } + ] + } + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "ID" + }, + { + "columnId": "name", + "label": "Name" + }, + { + "columnId": "SKUName", + "label": "SKU" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "SKUCapacity", + "label": "Capacity" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription ID" + }, + { + "columnId": "backendIPCount", + "label": "Has backend pool for IPs?" + }, + { + "columnId": "backendAddressesCount", + "label": "Has backend pool for VMs?" + }, + { + "columnId": "id1", + "label": "ResourceID" + } + ] + } + }, + "name": "Get-Idle-AppGW" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "appGateway" + }, + "name": "NetworkingAppGateway" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Recommendations for Load Balancers\r\nReview Load balancers with no backend pools, and remove them if not needed.", + "style": "upsell" + }, + "name": "Recommendations for Load Balancers" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where resourceGroup in ({ResourceGroup})\r\n| extend resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup), SKUName=tostring(sku.name),SKUTier=tostring(sku.tier),location,backendAddressPools = properties.backendAddressPools\r\n| where type =~ 'microsoft.network/loadbalancers' and array_length(backendAddressPools) == 0 and sku.name!='Basic'\r\n| order by id asc\r\n| project id,name, SKUName,SKUTier,backendAddressPools, location,resourceGroup, subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "title": "Load Balancers with empty backend pools", + "noDataMessage": "You don't have any Load Balancers with empty backendpools", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "backendAddressPools", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "0", + "representation": "disabled", + "text": "Empty Backend Pool" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "" + } + ] + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Resource ID" + }, + { + "columnId": "name", + "label": "Name" + }, + { + "columnId": "SKUName", + "label": "SKU" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "backendAddressPools", + "label": "Has backend pool?" + }, + { + "columnId": "location", + "label": "Location" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Name" + }, + { + "columnId": "id1", + "label": "ResourceID" + } + ] + } + }, + "name": "Get-Idle-LB" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "loadBalancer" + }, + "name": "LoadBalancerGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Recommendations for Public IP Addresses\r\nReview unattached Public IP addresses, as they may represent additional cost.\r\n
This query will also show Public IPs attached to Idle network cards.\r\n", + "style": "upsell" + }, + "name": "Recommendations for PIP" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'Microsoft.Network/publicIPAddresses' and isempty(properties.ipConfiguration) and isempty(properties.natGateway) and properties.publicIPAllocationMethod =~ 'Static'\r\n| extend PublicIpId=id, IPName=name, AllocationMethod=tostring(properties.publicIPAllocationMethod), SKUName=sku.name, Location=location ,resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)\r\n| project PublicIpId,IPName, SKUName, resourceGroup, Location, AllocationMethod, subscriptionId\r\n| union (\r\n Resources \r\n | where type =~ 'microsoft.network/networkinterfaces' and isempty(properties.virtualMachine) and isnull(properties.privateEndpoint) and isnotempty(properties.ipConfigurations) \r\n | extend IPconfig = properties.ipConfigurations \r\n | mv-expand IPconfig \r\n | extend PublicIpId= tostring(IPconfig.properties.publicIPAddress.id)\r\n | project PublicIpId\r\n | join ( \r\n resources \r\n | where type =~ 'Microsoft.Network/publicIPAddresses'\r\n | extend PublicIpId=id, IPName=name, AllocationMethod=tostring(properties.publicIPAllocationMethod), SKUName=sku.name, resourceGroup, Location=location \r\n ) on PublicIpId\r\n | project PublicIpId,IPName, SKUName, resourceGroup, Location, AllocationMethod, subscriptionId\r\n)\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | extend PublicIpId=id\r\n | distinct PublicIpId\r\n )\r\n on PublicIpId\r\n", + "size": 0, + "title": "Unattached Public IPs", + "noDataMessage": "You have no unattached Public IPs", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "PublicIpId1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "PublicIpId", + "label": "ID" + }, + { + "columnId": "IPName", + "label": "Name" + }, + { + "columnId": "SKUName", + "label": "SKU" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "AllocationMethod", + "label": "Allocation Method" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Name" + }, + { + "columnId": "PublicIpId1", + "label": "Resource ID" + } + ] + } + }, + "name": "Get-Idle-PIP" + }, + { + "type": 1, + "content": { + "json": "# Routing Preference\r\n\r\nAzure routing preference enables you to choose how your traffic routes between Azure and the Internet. You can choose to route traffic either via the Microsoft network or via the ISP network (public internet). By default, traffic is routed via the Microsoft global network for all Azure services.\r\n\r\nRouting preference choices include:\r\n\r\n- **Microsoft Network**: Both ingress and egress traffic stays bulk of the travel on the Microsoft global network. This routing is also known as cold potato routing. This option has a higher ingress/egress cost.\r\n\r\n- **Public Internet (ISP network)**: The new routing choice Internet routing minimizes travel on the Microsoft global network and uses the transit ISP network to route your traffic. This routing is also known as hot potato routing.\r\n\r\nFor more information about routing preference, see [What is routing preference?](https://learn.microsoft.com/azure/virtual-network/ip-services/ip-services-overview#routing-preference).\r\n\r\n", + "style": "upsell" + }, + "name": "text - 3" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'Microsoft.Network/publicIPAddresses' and isnotempty(properties.ipConfiguration)\r\n| where tostring(properties.ipTags)== \"[]\"\r\n| extend PublicIpId=id, RoutingMethod=id, IPName=name, AllocationMethod=tostring(properties.publicIPAllocationMethod), SKUName=sku.name, Location=location ,resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)\r\n| project PublicIpId,IPName, RoutingMethod,SKUName, resourceGroup, Location, AllocationMethod, subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | extend PublicIpId=id\r\n | distinct PublicIpId\r\n )\r\n on PublicIpId", + "size": 0, + "title": "Public IP Addresses ", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "RoutingMethod", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "Default", + "thresholdValue": null, + "representation": "info", + "text": "Microsoft Network" + } + ] + } + }, + { + "columnMatch": "PublicIpId1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "PublicIpId", + "label": "ID" + }, + { + "columnId": "IPName", + "label": "Name" + }, + { + "columnId": "RoutingMethod", + "label": "Routing Method" + }, + { + "columnId": "SKUName", + "label": "SKU Name" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "Location", + "label": "Location" + }, + { + "columnId": "AllocationMethod", + "label": "Allocation Method" + }, + { + "columnId": "subscriptionId", + "label": "SubscriptionId" + }, + { + "columnId": "PublicIpId1", + "label": "Resource ID" + } + ] + } + }, + "name": "Query-PIP-RoutingPreference" + }, + { + "type": 1, + "content": { + "json": "# DDoS IP Protection\r\nIf you need to protect fewer than 15 public IP resources, the IP Protection tier is the more cost-effective option. However, if you have more than 15 public IP resources to protect, then the Network Protection tier becomes more cost-effective. \r\n\r\nThis query will surface all Public IP (PIP) addressess with the DDoS Protection enabled. If there are more than 15 Public IP Addresses with DDoS protection in the same virtual network, then it is cheaper to enable DDoS Network protection.\r\n\r\nThe Network Protection tier also provides additional features, including:\r\n\r\n- DDoS Protection Rapid Response (DRR)\r\n- Cost protection guarantees\r\n- Web Application Firewall (WAF) discounts\r\n\r\nFor more information about DDoS protection, see [Which Azure DDoS Protection tier should I choose?](https://learn.microsoft.com/azure/ddos-protection/ddos-faq?source=recommendations#which-azure-ddos-protection-tier-should-i-choose-).", + "style": "upsell" + }, + "name": "text - 5" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == \"microsoft.network/publicipaddresses\"\r\n| project ddosProtection=tostring(properties.ddosSettings), name\r\n| where ddosProtection has \"Enabled\"\r\n| count\r\n| project TotalIpsProtected = Count\r\n| extend CheckIpsProtected = iff(TotalIpsProtected >= 15,\"Enable Network Protection tier\", \"Enable PIP DDoS Protection\")", + "size": 0, + "title": "Public IP Addresses DDoS Protection", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "RoutingMethod", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "Default", + "thresholdValue": null, + "representation": "info", + "text": "Microsoft Network" + } + ] + } + }, + { + "columnMatch": "PublicIpId1", + "formatter": 5 + } + ] + } + }, + "name": "Query-PIP-DDoSProtection" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "publicIP" + }, + "name": "PIPGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Recommendations for Virtual Network Gateways\r\nReview idle Virtual Network Gateways that have no connections defined, as they may represent additional cost.\r\n", + "style": "upsell" + }, + "name": "Recommendations for idle virtualNetworkGateways" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == \"microsoft.network/virtualnetworkgateways\"\r\n| extend resourceGroup =strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)\r\n| project id, GWName=name,resourceGroup,location,subscriptionId\r\n| join kind = leftouter(\r\n resources\r\n | where type == \"microsoft.network/connections\"\r\n | extend id = tostring(properties.virtualNetworkGateway1.id)\r\n | project id\r\n | union (\r\n resources\r\n | where type == \"microsoft.network/connections\"\r\n | extend id = tostring(properties.virtualNetworkGateway2.id)\r\n | project id\r\n )\r\n) on id\r\n| where isempty(id1)\r\n| project id, GWName,resourceGroup,location,subscriptionId,status=id", + "size": 0, + "title": "Idle Virtual Network Gateways", + "noDataMessage": "No Idle Virtual Network Gateways found", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "status", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "Default", + "thresholdValue": null, + "representation": "warning", + "text": "Error-Connection not configured" + } + ] + } + } + ], + "filter": true, + "labelSettings": [ + { + "columnId": "id", + "label": "Resource ID" + }, + { + "columnId": "GWName", + "label": "VPN Gateway Name" + }, + { + "columnId": "status", + "label": "Is connected?" + } + ] + } + }, + "name": "query - Idle Virtual Network gateways" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "vpnGw" + }, + "name": "VPNGW Group" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "advisorresources\r\n| where type =~ 'microsoft.advisor/recommendations'\r\n| where resourceGroup in ({ResourceGroup})\r\n| where properties.category == 'Cost' and properties.lastUpdated >= ago(1d)\r\n| where properties.impactedField has \"Network\"\r\n| extend AffectedResource=tostring(properties.resourceMetadata.resourceId), Category=properties.category, SubCategory=properties.impactedField, Impact=properties.impact,resourceGroup,subscriptionId,Recommendation=tostring(properties.shortDescription.problem), id, stableId = name, recommendationTypeId = tostring(properties.recommendationTypeId), maxCpuP95 = properties.extendedProperties.MaxCpuP95\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| project AffectedResource=tostring(properties.resourceMetadata.resourceId), Category=properties.category, SubCategory=properties.impactedField, Recommendation=tostring(properties.shortDescription.problem), Impact=properties.impact,resourceGroup,subscriptionId, id, stableId = name, recommendationTypeId = tostring(properties.recommendationTypeId), maxCpuP95 = properties.extendedProperties.MaxCpuP95\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isempty(resourceGroup) == true\r\n| project subscriptionId, excludeRecomm = properties.exclude, lowCpuThreshold = properties.lowCpuThreshold, AffectedResource=tostring(properties.resourceMetadata.resourceId),Impact=properties.impact,resourceGroup,AdditionaInfo=properties.extendedProperties,Recommendation=tostring(properties.shortDescription.problem))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| where Category == 'Cost' \r\n| where SubCategory has \"Network\"\r\n| project-away subscriptionId1, subscriptionId2, AffectedResource1, isActive2, isActive3, Impact1, Recommendation1, resourceGroup1, resourceGroup2", + "size": 0, + "title": "Azure Advisor Cost recommendations", + "noDataMessage": "You are following all of our cost recommendations for Networking", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Group", + "formatter": 1 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id", + "formatter": 5 + }, + { + "columnMatch": "stableId", + "formatter": 5 + }, + { + "columnMatch": "recommendationTypeId", + "formatter": 5 + }, + { + "columnMatch": "maxCpuP95", + "formatter": 5 + }, + { + "columnMatch": "excludeRecomm", + "formatter": 5 + }, + { + "columnMatch": "lowCpuThreshold", + "formatter": 5 + }, + { + "columnMatch": "AdditionaInfo", + "formatter": 5, + "formatOptions": { + "customColumnWidthSetting": "19ch" + } + }, + { + "columnMatch": "isActive1", + "formatter": 5 + }, + { + "columnMatch": "excludeProperty", + "formatter": 5 + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Recommendation" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "AffectedResource", + "label": "Affected Resource" + }, + { + "columnId": "Category", + "label": "Recommendation Category" + }, + { + "columnId": "SubCategory", + "label": "Affected Resource Type" + }, + { + "columnId": "Recommendation", + "label": "Recommendation" + }, + { + "columnId": "Impact", + "label": "Impact" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "Get-AdvisorRecommendations-Networking" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": " resources\r\n | where resourceGroup in ({ResourceGroup})\r\n | where type has \"Microsoft.Network\"\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend AffectedResource=id,ResourceRG=resourceGroup\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n | project id", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "query - tags - list all network resources" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\",\"mergeType\":\"innerunique\",\"leftTable\":\"Get-AdvisorRecommendations-Networking\",\"rightTable\":\"query - tags - list all network resources\",\"leftColumn\":\"AffectedResource\",\"rightColumn\":\"id\"}],\"projectRename\":[{\"originalName\":\"[Get-AdvisorRecommendations-Networking].AffectedResource\",\"mergedName\":\"AffectedResource\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].Category\",\"mergedName\":\"Category\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].SubCategory\",\"mergedName\":\"SubCategory\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].Recommendation\",\"mergedName\":\"Recommendation\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].Impact\",\"mergedName\":\"Impact\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].resourceGroup\",\"mergedName\":\"resourceGroup\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d87008d\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].excludeProperty\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].isActive1\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].AdditionaInfo\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].lowCpuThreshold\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].excludeRecomm\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].maxCpuP95\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].recommendationTypeId\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].stableId\"},{\"originalName\":\"[query - tags - list all network resources].id\"},{\"originalName\":\"[Get-AdvisorRecommendations-Networking].id\"}]}", + "size": 0, + "title": "Azure Advisor Cost recommendations", + "noDataMessage": "You are following all of our cost recommendations for Networking", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 7 + }, + "showPin": false, + "name": "query - Merge - Network Advisor recommendations" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "advisorNetworking" + }, + "name": "AdvisorGroupNetworking" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Recommendations for NAT Gateways\r\nReview idle NAT Gateways that have no subnet defined, as they may represent additional cost.\r\n", + "style": "upsell" + }, + "name": "Recommendations for idle NAT Gateway" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == \"microsoft.network/natgateways\" and isnull(properties.subnets)\r\n| project id, GWName=name, SKUName=tostring(sku.name), SKUTier=tostring(sku.tier), Location=location ,resourceGroup=tostring(strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)),subnet=tostring(properties.subnet), subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "title": "Idle NAT Gateways", + "noDataMessage": "No idle NAT gateways found", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subnet", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "Default", + "thresholdValue": null, + "representation": "warning", + "text": "Not associated." + } + ] + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + } + ], + "filter": true, + "labelSettings": [ + { + "columnId": "id", + "label": "Resource ID" + }, + { + "columnId": "GWName", + "label": "NAT Gateway Name" + }, + { + "columnId": "SKUName", + "label": "SKU Name" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "Location", + "label": "Location" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subnet", + "label": "Subnet" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + } + ] + } + }, + "name": "query - Idle NAT gateways" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "natgw" + }, + "name": "NATGW Group" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Recommendations for Private DNS\r\nReview private DNS without [Virtual Network Links](https://learn.microsoft.com/azure/dns/private-dns-virtual-network-links).\r\n", + "style": "upsell" + }, + "name": "Recommendations for idle private dns" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == \"microsoft.network/privatednszones\" and properties.numberOfVirtualNetworkLinks == 0\r\n| project id, PrivateDNSName=name, NumberOfRecordSets=tostring(properties.numberOfRecordSets),resourceGroup=tostring(strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)),vNets=tostring(properties.properties.numberOfVirtualNetworkLinks), subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "title": "Idle private DNS ", + "noDataMessage": "No idle private DNS found", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "vNets", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "0", + "representation": "2", + "text": "Not associated to any vNET" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "warning", + "text": "Not associated to any vNET" + } + ] + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + }, + { + "columnMatch": "subnet", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "Default", + "thresholdValue": null, + "representation": "warning", + "text": "Not associated." + } + ] + } + } + ], + "filter": true, + "labelSettings": [ + { + "columnId": "id", + "label": "Resource ID" + }, + { + "columnId": "PrivateDNSName", + "label": "Private DNS name" + }, + { + "columnId": "NumberOfRecordSets", + "label": "Number of DNS records" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "vNets", + "label": "vNETs associated" + }, + { + "columnId": "subscriptionId", + "label": "Subscription" + } + ] + } + }, + "name": "query - Idle private DNS" + }, + { + "type": 1, + "content": { + "json": "# Recommendations for Private endpoints\r\nReview [Private Endpoints](https://learn.microsoft.com/azure/private-link/private-endpoint-overview) that are not connected to any resource.", + "style": "upsell" + }, + "name": "Recommendations for idle private endpoints" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type =~ \"microsoft.network/privateendpoints\"\r\n| extend connection = iff(array_length(properties.manualPrivateLinkServiceConnections) > 0, properties.manualPrivateLinkServiceConnections[0], properties.privateLinkServiceConnections[0])\r\n| extend subnetId = properties.subnet.id\r\n| extend subnetIdSplit = split(subnetId, \"/\")\r\n| extend vnetId = strcat_array(array_slice(subnetIdSplit,0,8), \"/\")\r\n| extend serviceId = tostring(connection.properties.privateLinkServiceId)\r\n| extend serviceIdSplit = split(serviceId, \"/\")\r\n| extend serviceName = tostring(serviceIdSplit[8])\r\n| extend serviceTypeEnum = iff(isnotnull(serviceIdSplit[6]), tolower(strcat(serviceIdSplit[6], \"/\", serviceIdSplit[7])), \"microsoft.network/privatelinkservices\")\r\n| extend stateEnum = tostring(connection.properties.privateLinkServiceConnectionState.status)\r\n| extend stateDescription = tostring(connection.properties.privateLinkServiceConnectionState.description)\r\n| extend groupIds = tostring(connection.properties.groupIds[0])\r\n| where stateEnum == \"Disconnected\"\r\n| extend Details = pack_all()\r\n| project id, PrivateDNSName=name, stateEnum, stateDescription, resourceGroup=tostring(strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)),serviceName, serviceTypeEnum, groupIds, vnetId, subnetId,subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "title": "Idle private endpoints", + "noDataMessage": "No idle private endpoints found", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "serviceTypeEnum", + "formatter": 16, + "formatOptions": { + "showIcon": true + } + }, + { + "columnMatch": "vnetId", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "subnetId", + "formatter": 13, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + } + ], + "filter": true, + "labelSettings": [ + { + "columnId": "id", + "label": "Resource ID" + }, + { + "columnId": "PrivateDNSName", + "label": "Private Endpoint name" + }, + { + "columnId": "stateEnum", + "label": "State" + }, + { + "columnId": "stateDescription", + "label": "State description" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "serviceName", + "label": "Resource Name" + }, + { + "columnId": "serviceTypeEnum", + "label": "Service Type" + }, + { + "columnId": "groupIds", + "label": "Resource Sub-type" + }, + { + "columnId": "vnetId", + "label": "Subnet" + }, + { + "columnId": "subnetId", + "label": "Subscription" + } + ] + } + }, + "name": "query - Idle private endpoint" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "privatedns" + }, + "name": "Private DNS and Private Endpoints Group" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Recommendations for Azure Firewall\r\n\r\n## Azure Firewall Premium SKU\r\nThis table identifies Azure Firewalls with Premium SKU and evaluates whether the associated policy incorporates premium-only features or not. If a Premium SKU Firewall lacks a policy with premium features, such as TLS or intrusion detection it will be shown here. To learn more about Azure Firewall skus, check this [SKU comparison table](https://learn.microsoft.com/azure/firewall/choose-firewall-sku). ", + "style": "upsell" + }, + "name": "Recommendations for premium Firewall" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'Microsoft.Network/azureFirewalls' and properties.sku.tier==\"Premium\"\r\n| project FWID=id, firewallName = name, SkuTier = tostring(properties.sku.tier), resourceGroup, location\r\n| join kind=inner (\r\n resources\r\n | where type =~ 'microsoft.network/firewallpolicies'\r\n | mv-expand properties.firewalls\r\n | extend intrusionDetection = tostring(properties.intrusionDetection contains \"Alert\" or properties.intrusionDetection contains \"Deny\"), transportSecurity = tostring(properties.transportSecurity contains \"keyVaultSecretId\")\r\n | extend FWID=tostring(properties_firewalls.id)\r\n | where intrusionDetection == \"False\" and transportSecurity == \"False\"\r\n | project PolicyName = name, PolicySKU=tostring(properties.sku.tier), intrusionDetection, transportSecurity, FWID\r\n) on FWID", + "size": 0, + "title": "Azure Firewall Premium", + "noDataMessage": "No Azure Firewall Premium found", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "firewallName", + "formatter": 5 + }, + { + "columnMatch": "FWID1", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "status", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "Default", + "thresholdValue": null, + "representation": "warning", + "text": "Error-Connection not configured" + } + ] + } + } + ], + "filter": true, + "labelSettings": [ + { + "columnId": "FWID", + "label": "Firewall Name" + }, + { + "columnId": "firewallName", + "label": "FWName" + }, + { + "columnId": "SkuTier", + "label": "SKU" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "location", + "label": "Location" + }, + { + "columnId": "PolicyName", + "label": "Policy Name" + }, + { + "columnId": "PolicySKU", + "label": "Policy SKU" + }, + { + "columnId": "intrusionDetection", + "label": "Is Intrusion Detection enabled?" + }, + { + "columnId": "transportSecurity", + "label": "Is TLS enabled?" + } + ] + } + }, + "name": "query - Optimize Premium AZ Firewall" + }, + { + "type": 1, + "content": { + "json": "## Avoid multiple Firewall instances in the same region\r\nOptimize the use of Azure Firewall by having a central instance of Azure Firewall in the hub virtual network or Virtual WAN secure hub and share the same firewall across many spoke virtual networks that are connected to the same hub from the same region. Ensure there's no unexpected cross-region traffic as part of the hub-spoke topology nor multiple Azure firewall instances deployed to the same region. To learn more about Azure Firewall design principles, check [Azure Well-Architected Framework review - Azure Firewall](https://learn.microsoft.com/azure/well-architected/service-guides/azure-firewall#cost-optimization).", + "style": "upsell" + }, + "name": "text - 3" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'Microsoft.Network/azureFirewalls'\r\n| mv-expand properties.ipConfigurations\r\n| project FWID=id, firewallName = name, SkuTier = tostring(properties.sku.tier), FWRG=resourceGroup, FWLocation=location, SubnetID=tostring(properties_ipConfigurations.properties.subnet.id)\r\n| join (\r\nresources\r\n| where type =~ 'Microsoft.Network/virtualNetworks' \r\n| mv-expand properties.subnets\r\n| where properties_subnets.id has 'AzureFirewallSubnet'\r\n| extend SubnetID=tostring(properties_subnets.id), SubnetName=name, SubnetLocation=location, SubnetRG=resourceGroup) on SubnetID\r\n| project FWID, FWRG,FWLocation, SubnetID,SubnetName, SubnetRG, SubnetLocation\r\n", + "size": 0, + "title": "Azure Firewall per location", + "noDataMessage": "No Firewall deployed", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "SubnetName", + "formatter": 5 + }, + { + "columnMatch": "firewallName", + "formatter": 5 + }, + { + "columnMatch": "FWID1", + "formatter": 5 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "status", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "Default", + "thresholdValue": null, + "representation": "warning", + "text": "Error-Connection not configured" + } + ] + } + } + ], + "filter": true, + "labelSettings": [ + { + "columnId": "FWID", + "label": "Firewall Name" + }, + { + "columnId": "FWRG", + "label": "Firewall Resource Group" + }, + { + "columnId": "FWLocation", + "label": "Firewall Location" + }, + { + "columnId": "SubnetID", + "label": "Vnet / Subnet Name" + }, + { + "columnId": "SubnetName", + "label": "Subnet extended Name" + }, + { + "columnId": "SubnetRG", + "label": "Subnet Resource Group" + }, + { + "columnId": "SubnetLocation", + "label": "Subnet Location" + } + ] + } + }, + "name": "query - Firewall per Location" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "firewall" + }, + "name": "Firewall Group" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Recommendations for ExpressRoute\r\n\r\nReview idle ExpressRoute circuits that has not been provisioned (service provider has not completed provisioning or has deprovisioned), as they may represent additional cost.", + "style": "upsell" + }, + "name": "Recommendations for ExpressRoute" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type =~ 'Microsoft.Network/expressRouteCircuits' and properties.serviceProviderProvisioningState == \"NotProvisioned\"\r\n| extend ServiceLocation=tostring(properties.serviceProviderProperties.peeringLocation), ServiceProvider=tostring(properties.serviceProviderProperties.serviceProviderName), BandwidthInMbps=tostring(properties.serviceProviderProperties.bandwidthInMbps)\r\n| project ERId=id,ERName = name, ERRG = resourceGroup, SKUName=tostring(sku.name), SKUTier=tostring(sku.tier), SKUFamily=tostring(sku.family), ERLocation = location, ServiceLocation, ServiceProvider, BandwidthInMbps\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | extend ERId=id\r\n | distinct ERId\r\n )\r\n on ERId\r\n\r\n", + "size": 0, + "title": "Idle ExpressRoute circuits", + "noDataMessage": "No idle ExpressRoute circuits found", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "ERId1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "ERId", + "label": "ExpressRoute ID" + }, + { + "columnId": "ERName", + "label": "ER Name" + }, + { + "columnId": "ERRG", + "label": "Resource Group" + }, + { + "columnId": "SKUName", + "label": "SKU Name" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "SKUFamily", + "label": "SKU Family" + }, + { + "columnId": "ERLocation", + "label": "Location" + }, + { + "columnId": "ServiceLocation", + "label": "Service Location" + }, + { + "columnId": "ServiceProvider", + "label": "Service Provider" + }, + { + "columnId": "BandwidthInMbps", + "label": "Bandwidth in Mbps" + } + ] + } + }, + "name": "Idle ExpressRoute circuits" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "ER" + }, + "name": "ExpressRoute Group" + } + ] + }, + "name": "networking - Subscription" + } + ] + }, + "name": "group - 0" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "UsageOptimization" + }, + { + "parameterName": "SelectedRateOptimizationTab", + "comparison": "isEqualTo", + "value": "Networking" + } + ], + "name": "NetworkingGroup", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "title": "Storage cost optimization recommendations", + "loadFromTemplateId": "", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "37ceb1c3-3930-4689-a90b-22f26e42bd81", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "label": " Subscription" + }, + { + "id": "08f5fe68-c2e3-4882-9300-b3e33f572dfe", + "version": "KqlParameterItem/1.0", + "name": "ResourceGroup", + "label": "Resource Group", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "resources\r\n| distinct resourceGroup", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "4fea3013-df84-4930-a453-8a6bd0375130", + "version": "KqlParameterItem/1.0", + "name": "SingleSubHidden", + "type": 1, + "isRequired": true, + "query": "resourcecontainers\r\n| where type==\"microsoft.resources/subscriptions\"\r\n| take 1\r\n| project subscriptionId", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Hidden Subscription" + }, + { + "id": "8412f39d-ee67-4979-b887-47463b8848c2", + "version": "KqlParameterItem/1.0", + "name": "TagName", + "type": 2, + "query": "Resources\r\n| where tags != '' and tags != '[]'\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| distinct tagName\r\n| sort by tagName asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Name" + }, + { + "id": "50c68f38-13a0-4aff-a259-4426c83b7cc0", + "version": "KqlParameterItem/1.0", + "name": "TagValue", + "type": 2, + "query": "Resources\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| extend tagValue = tostring(tags[tagName])\r\n| where tags != '' and tags != '[]' and tostring(bag_keys(tags)[0]) == '{TagName}'\r\n| distinct tagValue\r\n| sort by tagValue asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Value" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "75", + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "CostInformation" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "Welcome" + } + ], + "name": "parameters - Filters" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "eae8a0d2-14e6-4cd1-a2d2-fd6b207cf517", + "version": "KqlParameterItem/1.0", + "name": "Location", + "type": 2, + "query": "Resources\r\n| where type =~ 'Microsoft.Compute/virtualMachines'\r\n| project name, location\r\n| summarize count () by location\r\n| project location", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::1" + ] + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Resource Location" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "25", + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + "name": "parameters - location" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "eae8a0d2-14e6-4cd1-a2d2-fd6b207cf517", + "version": "KqlParameterItem/1.0", + "name": "Location", + "type": 2, + "query": "Resources\r\n| where type =~ 'Microsoft.Compute/virtualMachines'\r\n| project name, location\r\n| summarize count () by location\r\n| project location", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::1" + ] + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Resource Location" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "25", + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + "name": "parameters - location" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "0211f413-9f36-4750-9ef2-d382ba30ba6c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Storage Accounts", + "subTarget": "Storage", + "preText": "VM", + "style": "link" + }, + { + "id": "dbe9a7fb-6ab1-4de1-a98b-4ec8a9af906c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Managed Disks", + "subTarget": "Disks", + "style": "link" + }, + { + "id": "86ff248b-1ce4-4194-8cd4-b1e0a9956b5d", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Backup", + "subTarget": "Backup", + "style": "link" + }, + { + "id": "6d563f46-7150-458c-9ee4-0558abe8e29b", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Advisor recommendations", + "subTarget": "advisorStorage", + "style": "link" + } + ] + }, + "name": "links - Storage" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Idle backups\r\n\r\nReview protected items backup activity to determine if there are items that have not been backed up in the last 90 days. This could either mean that the underlying resource that's being backed up doesn't exist anymore or there's some issue with the resource that's preventing backups from being taken reliably.\r\n", + "style": "upsell" + }, + "name": "text - idleBackup" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "recoveryservicesresources\r\n| where type =~ 'microsoft.recoveryservices/vaults/backupfabrics/protectioncontainers/protecteditems'\r\n| extend vaultId = tostring(properties.vaultId),resourceId = tostring(properties.sourceResourceId),idleBackup= datetime_diff('day', now(), todatetime(properties.lastBackupTime)) > 90, resourceType=tostring(properties.workloadType), protectionState=tostring(properties.protectionState),lastBackupTime=tostring(properties.lastBackupTime), resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup),lastBackupDate=todatetime(properties.lastBackupTime)\r\n| where idleBackup != 0\r\n| project resourceId,vaultId,idleBackup,lastBackupDate,resourceType,protectionState,lastBackupTime,location,resourceGroup,subscriptionId\r\n| join kind = inner(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | extend vaultId = id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | project vaultId\r\n )\r\n on vaultId\r\n | project-away vaultId1", + "size": 0, + "title": "Idle backups", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "idleBackup", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": ">", + "thresholdValue": "0", + "representation": "2", + "text": "No backup in the last 90 days" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "" + } + ] + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "labelSettings": [ + { + "columnId": "resourceId", + "label": "Resource ID" + }, + { + "columnId": "idleBackup", + "label": "Backup activity" + }, + { + "columnId": "lastBackupDate", + "label": "Last backup date" + }, + { + "columnId": "resourceType", + "label": "Resource type" + }, + { + "columnId": "protectionState", + "label": "Protection state" + }, + { + "columnId": "lastBackupTime", + "label": "Last backup time" + }, + { + "columnId": "location", + "label": "Location" + }, + { + "columnId": "resourceGroup", + "label": "Resource group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription ID" + } + ] + }, + "sortBy": [] + }, + "name": "query - idleBackups" + }, + { + "type": 1, + "content": { + "json": "## Backup storage redundancy settings\r\n\r\nBy default, when you configure backup for resources, geo-redundant storage (GRS) replication is applied to these backups. While this is the recommended storage replication option as it creates more redundancy for your critical data, you can choose to protect items using locally-redundant storage (LRS) if that meets your backup availability needs for dev-test workloads. Using LRS instead of GRS halves the cost of your backup storage. \r\n\r\n🖱ī¸Click on each vault to see the configured storage replication\r\n", + "style": "upsell" + }, + "name": "text - backupReplication" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "Resources\r\n| where type == 'microsoft.recoveryservices/vaults'\r\n| where resourceGroup in ({ResourceGroup})\r\n| extend skuTier = tostring(sku['tier']), skuName = tostring(sku['name']), resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup),redundancySettings = tostring(properties.redundancySettings['standardTierStorageRedundancy'])\r\n| order by id asc\r\n| project id,redundancySettings, resourceGroup, location,subscriptionId, skuTier, skuName\r\n| join kind = innerunique (\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | extend vaultId = id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | project id\r\n)\r\non id\r\n| project-away id1\r\n", + "size": 0, + "title": "Recovery vaults storage replication ", + "exportedParameters": [ + { + "fieldName": "RGVault", + "parameterName": "resourceGroupVault", + "parameterType": 1 + }, + { + "fieldName": "subscriptionId", + "parameterName": "subscriptionId", + "parameterType": 1 + }, + { + "fieldName": "name", + "parameterName": "vaultName", + "parameterType": 1 + } + ], + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "redundancySettings", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "GeoRedundant", + "representation": "Globe", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "ResourceFlat", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "RGVault", + "formatter": 5 + }, + { + "columnMatch": "name", + "formatter": 5 + } + ] + } + }, + "name": "query - backupStorageReplication" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "Backup" + }, + "name": "group - Backup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Storage accounts\r\nGeneral-purpose v2 storage accounts support the latest Azure Storage features and incorporate all of the functionality of general-purpose v1 and Blob storage accounts. General-purpose v2 accounts are recommended for most storage scenarios.\r\n\r\n1. General-purpose v2 accounts deliver the lowest per-gigabyte capacity prices for Azure Storage, as well as industry-competitive transaction prices.\r\n2. General-purpose v2 accounts support default account access tiers of hot or cool and blob level tiering between hot, cool, or archive.\r\n3. General-purpose v2 accounts allows you to also use lifecycle management to optimize your storage cost", + "style": "upsell" + }, + "name": "Storage accounts" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'Microsoft.Storage/StorageAccounts' and kind !='StorageV2' and kind !='FileStorage' and kind != 'BlockBlobStorage'\r\n| where resourceGroup in ({ResourceGroup})\r\n| extend StorageAccountName=name, SAKind=kind,AccessTier=tostring(properties.accessTier),SKUName=sku.name, SKUTier=sku.tier, Location=location\r\n| order by id asc\r\n| project id,StorageAccountName, SKUName, SKUTier, SAKind,AccessTier, resourceGroup, Location, subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "title": "Storage accounts which are not v2", + "noDataMessage": "All storage accounts are General-purpose v2", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "SKUName", + "formatter": 1 + }, + { + "columnMatch": "SKUTier", + "formatter": 1 + }, + { + "columnMatch": "SAKind", + "formatter": 1 + }, + { + "columnMatch": "AccessTier", + "formatter": 1 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + }, + { + "columnMatch": "storageaccount", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "subTarget": "insights", + "linkIsContextBlade": true, + "showIcon": true + } + } + ], + "sortBy": [ + { + "itemKey": "$gen_link_id_0", + "sortOrder": 1 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Resource ID" + }, + { + "columnId": "StorageAccountName", + "label": "Name" + }, + { + "columnId": "SKUName", + "label": "SKU" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "SAKind", + "label": "Kind" + }, + { + "columnId": "AccessTier", + "label": "Access Tier" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "Location", + "label": "Location" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Name" + } + ] + }, + "sortBy": [ + { + "itemKey": "$gen_link_id_0", + "sortOrder": 1 + } + ] + }, + "name": "Get-Storagev1" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "Storage" + }, + "name": "group - StorageAccount" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Unattached Managed Disks\r\n\r\nReview Managed Disks that are not attached to any Virtual machine.\r\n\r\n## Last Modified Date\r\nClick on a cell in the specified row to view the last modified date. This may help identify when the disk became idle.\r\n\r\n", + "style": "upsell" + }, + "name": "text - 3" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'microsoft.compute/disks' and managedBy == \"\"\r\n| extend diskState = tostring(properties.diskState)\r\n| where (tags !contains \"kubernetes.io-created-for-pvc\") and tags !contains \"ASR-ReplicaDisk\" and tags !contains \"asrseeddisk\" and tags !contains \"RSVaultBackup\"\r\n| where (managedBy == \"\" and diskState != 'ActiveSAS')\r\nor (diskState == 'Unattached' and diskState != 'ActiveSAS')\r\n| extend DiskId=id, DiskIDfull=id, DiskName=name, SKUName=sku.name, SKUTier=sku.tier, DiskSizeGB=tostring(properties.diskSizeGB), Location=location, TimeCreated=tostring(properties.timeCreated), QuickFix=id, SubId=subscriptionId\r\n| order by DiskId asc \r\n| project DiskId,DiskIDfull, DiskName, DiskSizeGB, SKUName, SKUTier, resourceGroup, QuickFix, Location, TimeCreated, subscriptionId,SubId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | extend DiskId = id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct DiskId\r\n )\r\n on DiskId", + "size": 0, + "title": "Unattached disks", + "noDataMessage": "There aren't any unattached disks!", + "noDataMessageStyle": 3, + "exportedParameters": [ + { + "fieldName": "DiskIDfull", + "parameterName": "DiskID" + }, + { + "fieldName": "DiskName", + "parameterName": "DiskName", + "parameterType": 1 + }, + { + "fieldName": "resourceGroup", + "parameterName": "ResourceGroup", + "parameterType": 1 + }, + { + "fieldName": "SubId", + "parameterName": "subscriptionId", + "parameterType": 1 + } + ], + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "DiskIDfull", + "formatter": 5 + }, + { + "columnMatch": "QuickFix", + "formatter": 7, + "formatOptions": { + "linkTarget": "ArmAction", + "linkLabel": "Remove Idle Disk", + "linkIsContextBlade": true, + "templateRunContext": { + "componentIdSource": "column", + "componentId": "DiskId", + "templateUriSource": "static", + "templateUri": "https://raw.githubusercontent.com/sebassem/MS-learn-Workbooks/main/Deploy-Tag.json", + "templateParameters": [ + { + "name": "DiskID", + "source": "static", + "value": "DiskId", + "kind": "stringValue" + } + ], + "titleSource": "static", + "title": "Remove Idle Disk", + "descriptionSource": "static", + "description": "# Description\r\nThis ARM Template will remove the selected disk.\r\n\r\n# Actions:\r\n- Click \"Remove Idle Disk\" to remove the selected item.\r\n- Click View Template to examine the template and parameters used during deployment\r\n\r\n\r\n\r\n", + "runLabelSource": "static", + "runLabel": "Remove Idle Disk" + }, + "armActionContext": { + "path": "/{DiskID}?api-version=2021-04-01", + "headers": [], + "params": [ + { + "key": "DiskID", + "value": "" + } + ], + "httpMethod": "DELETE", + "title": "Remove Idle Disks", + "description": "# Disk Deletion Warning: {DiskName}\r\n\r\n**Attention!**\r\n\r\nThis action will permanently remove the disk with the name **{DiskName}**. Please ensure that this disk is not currently in use and that you are deleting the correct disk.\r\n\r\n**Resource Details:**\r\n\r\n- Disk Name: {DiskName}\r\n- Resource Group: {ResourceGroup}\r\n\r\n### Required RBAC Permissions\r\n\r\nTo perform this action, you need to have **Contributor** permissions on the Resource Group where the disk is located.\r\n\r\nPlease review the information carefully before proceeding with the deletion.\r\n", + "actionName": "Removing Idle Dsk", + "runLabel": "I understand, remove disk {DiskName}" + } + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "rowLimit": 1000, + "labelSettings": [ + { + "columnId": "DiskId", + "label": "Resource ID" + }, + { + "columnId": "DiskName", + "label": "Name" + }, + { + "columnId": "DiskSizeGB", + "label": "Disk Size (GB)" + }, + { + "columnId": "SKUName", + "label": "SKU" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "QuickFix", + "label": "Delete disk?" + }, + { + "columnId": "Location", + "label": "Location" + }, + { + "columnId": "TimeCreated", + "label": "Time Created" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Name" + } + ] + }, + "sortBy": [] + }, + "customWidth": "80", + "name": "Get-Idle-Disk" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"path\":\"/subscriptions/{subscriptionId}/resources?\",\"urlParams\":[{\"key\":\"api-version\",\"value\":\"2021-04-01\"},{\"key\":\"$expand\",\"value\":\"createdTime,changedTime,provisioningState\"},{\"key\":\"$filter\",\"value\":\"name eq '{DiskName}' and resourceGroup eq'{ResourceGroup}'\"}],\"batchDisabled\":false,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.value\",\"columns\":[{\"path\":\"$..id\",\"columnid\":\"id\"},{\"path\":\"$..createdTime\",\"columnid\":\"createdTime\"},{\"path\":\"$..changedTime\",\"columnid\":\"changedTime\"},{\"path\":\"$.name\",\"columnid\":\"name\"}]}}]}", + "size": 0, + "title": "Disk last modified date", + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 5 + }, + { + "columnMatch": "createdTime", + "formatter": 5 + }, + { + "columnMatch": "name", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Name" + }, + { + "columnId": "createdTime", + "label": "Created time" + }, + { + "columnId": "changedTime", + "label": "Last change time" + } + ] + } + }, + "customWidth": "20", + "conditionalVisibility": { + "parameterName": "DiskID", + "comparison": "isNotEqualTo", + "value": "" + }, + "name": "IdleDisk date" + } + ] + }, + "name": "Idle Disks Group" + }, + { + "type": 1, + "content": { + "json": "# Premium disks attached to powered off virtual machines\r\nIf the VM associated with these premium disks has been deallocated for an extended period, consider changing the disk SKU to a less expensive option to save on costs. Premium disks are typically used for high-performance workloads, and if the VM is not in use, it might be more economical to downgrade the disk.", + "style": "upsell" + }, + "name": "text - premiumAttachedToPoweredOffVMs" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == \"microsoft.compute/virtualmachines\"\r\n| extend vmId = tolower(tostring(id)), vmName = name, vmState = tostring(properties.extended.instanceView.powerState.displayStatus),VMRG=resourceGroup\r\n| where vmState == \"VM stopped\" or vmState == \"VM deallocated\"\r\n| extend storageProfile = parse_json(tostring(properties.storageProfile.osDisk))\r\n| extend managedDiskId = tolower(tostring(storageProfile.managedDisk.id))\r\n| join kind=inner (\r\n resources\r\n | where type == \"microsoft.compute/disks\"\r\n | where sku.name == \"Premium_LRS\" or sku.name == \"Premium_ZRS\"\r\n | extend diskId = tolower(tostring(id)), diskName = name, diskSKU=tostring(sku.name), diskTier=tostring(sku.tier)\r\n) on $left.managedDiskId == $right.diskId\r\n| project vmId, vmName, vmState, diskName,VMRG, diskId, diskSKU,diskTier\r\n", + "size": 0, + "title": "Premium disks attached to powered off VMs", + "noDataMessage": "None of your deallocated VMs have premium disks", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "vmName", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "vmId", + "label": "VM ID" + }, + { + "columnId": "vmName", + "label": "VM name" + }, + { + "columnId": "vmState", + "label": "VM state" + }, + { + "columnId": "diskName", + "label": "Disk name" + }, + { + "columnId": "VMRG", + "label": "VM RG" + }, + { + "columnId": "diskId", + "label": "Disk ID" + }, + { + "columnId": "diskSKU", + "label": "Disk SKU" + }, + { + "columnId": "diskTier", + "label": "Disk Tier" + } + ] + } + }, + "name": "query-PremiumDiskDeallocatedVM" + }, + { + "type": 1, + "content": { + "json": "## Old Managed Disks snapshots\r\n\r\nReview Managed Disks snapshots that are older than 30 days\r\n", + "style": "upsell" + }, + "name": "text - 4" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == 'microsoft.compute/snapshots'\r\n| where resourceGroup in ({ResourceGroup})\r\n| extend TimeCreated = properties.timeCreated\r\n| extend resourceGroup=strcat(\"/subscriptions/\",subscriptionId,\"/resourceGroups/\",resourceGroup)\r\n| where TimeCreated < ago(30d)\r\n| order by id asc \r\n| project id, resourceGroup, location, TimeCreated ,subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "title": "Disk Snapshots with + 30 Days", + "noDataMessage": "No Snapshots with more than 30 days.", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "TimeCreated", + "formatter": 1 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Name" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "location", + "label": "Location" + }, + { + "columnId": "TimeCreated", + "label": "Time Created" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Name" + } + ] + } + }, + "name": "Get-Old-Snapshots" + }, + { + "type": 1, + "content": { + "json": "## Managed Disks snapshots using Premium storage\r\n\r\nTo save 60% of cost, we recommend storing your snapshots in Standard Storage, regardless of the storage type of the parent disk. It is the default option for Managed Disks snapshots. Migrate your snapshot from Premium to Standard Storage.\r\n", + "style": "upsell" + }, + "name": "text - 5" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == 'microsoft.compute/snapshots'\r\n| where resourceGroup in ({ResourceGroup})\r\n| extend StorageSku = tostring(sku.tier), resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup),diskSize=tostring(properties.diskSizeGB)\r\n| where StorageSku == \"Premium\"\r\n| project id,name,StorageSku,diskSize,location,resourceGroup,subscriptionId\r\n| join kind = innerunique(\r\n    resources\r\n    | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n    | extend replaced_tags = parse_json(replaced_tags)\r\n    | mv-expand replaced_tags\r\n    | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n    | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n    | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n    | distinct id\r\n    )\r\n    on id\r\n", + "size": 0, + "title": "Snapshots using premium storage", + "noDataMessage": "No snapshots are using Premium storage", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "Resource Id" + }, + { + "columnId": "name", + "label": "Name" + }, + { + "columnId": "StorageSku", + "label": "SKU" + }, + { + "columnId": "diskSize", + "label": "Disk Size (GB)" + }, + { + "columnId": "location", + "label": "Location" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Id" + } + ] + } + }, + "name": "query - Snapshots using premium storage" + }, + { + "type": 1, + "content": { + "json": "## Orphaned Managed Disks snapshots\r\n\r\nReview snapshots with deleted source disks.\r\n", + "style": "upsell" + }, + "name": "text - 6" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == 'microsoft.compute/snapshots'\r\n| where resourceGroup in ({ResourceGroup})\r\n| extend parentDisk = properties.creationData.sourceResourceId, diskSize=tostring(properties.diskSizeGB),resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)\r\n| project id,parentDisk,diskSize,location,resourceGroup,subscriptionId\r\n| join kind = innerunique(\r\n    resources\r\n    | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n    | extend replaced_tags = parse_json(replaced_tags)\r\n    | mv-expand replaced_tags\r\n    | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n    | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n    | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n    | distinct id\r\n    )\r\n    on id\r\n", + "size": 0, + "title": "All Managed Disks snapshots", + "noDataMessage": "No snapshots found", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "labelSettings": [ + { + "columnId": "id", + "label": "Resource Id" + }, + { + "columnId": "parentDisk", + "label": "Parent Disk Resource Id" + }, + { + "columnId": "diskSize", + "label": "Disk size (GB)" + }, + { + "columnId": "location", + "label": "Location" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Id" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "IsVisible", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "query - Retrieve all snapshots" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == 'microsoft.compute/disks'\r\n| project id\r\n", + "size": 0, + "title": "All managed disks", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "labelSettings": [ + { + "columnId": "id", + "label": "Resource Id" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "True" + }, + "name": "query - Retrieve all managed disks" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"d0a11ffb-579b-4259-827d-7ea62e3021fe\",\"mergeType\":\"leftanti\",\"leftTable\":\"query - Retrieve all snapshots\",\"rightTable\":\"query - Retrieve all managed disks\",\"leftColumn\":\"parentDisk\",\"rightColumn\":\"id\"}],\"projectRename\":[{\"originalName\":\"[query - Retrieve all snapshots].id\",\"mergedName\":\"Resource Id\",\"fromId\":\"d0a11ffb-579b-4259-827d-7ea62e3021fe\"},{\"originalName\":\"[query - Retrieve all snapshots].parentDisk\",\"mergedName\":\"Parent Disk Resource Id\",\"fromId\":\"d0a11ffb-579b-4259-827d-7ea62e3021fe\"},{\"originalName\":\"[query - Retrieve all snapshots].diskSize\",\"mergedName\":\"Disk size (GB)\",\"fromId\":\"d0a11ffb-579b-4259-827d-7ea62e3021fe\"},{\"originalName\":\"[query - Retrieve all snapshots].location\",\"mergedName\":\"Location\",\"fromId\":\"d0a11ffb-579b-4259-827d-7ea62e3021fe\"},{\"originalName\":\"[query - Retrieve all snapshots].resourceGroup\",\"mergedName\":\"Resource Group\",\"fromId\":\"d0a11ffb-579b-4259-827d-7ea62e3021fe\"},{\"originalName\":\"[query - Retrieve all snapshots].subscriptionId\",\"mergedName\":\"Subscription Id\",\"fromId\":\"d0a11ffb-579b-4259-827d-7ea62e3021fe\"},{\"originalName\":\"[query - Retrieve all snapshots].id1\",\"mergedName\":\"id1\",\"fromId\":\"d0a11ffb-579b-4259-827d-7ea62e3021fe\"}]}", + "size": 0, + "title": "Snapshots with deleted source disk", + "noDataMessage": "No orphaned snapshots found", + "noDataMessageStyle": 3, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "Parent Disk Resource Id", + "formatter": 5 + }, + { + "columnMatch": "Subscription Id", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "Resource Id", + "label": "Resource Id" + }, + { + "columnId": "Parent Disk Resource Id", + "label": "Parent Disk resource Id" + }, + { + "columnId": "Disk size (GB)", + "label": "Disk size (GB)" + }, + { + "columnId": "Location", + "label": "Location" + }, + { + "columnId": "Resource Group", + "label": "Resource Group" + }, + { + "columnId": "Subscription Id", + "label": "Subscription Id" + } + ] + } + }, + "showPin": false, + "name": "query - orphaned snapshots" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "Disks" + }, + "name": "Managed Disks Group" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "advisorresources\r\n| where type =~ 'microsoft.advisor/recommendations'\r\n| where resourceGroup in ({ResourceGroup})\r\n| where properties.category == 'Cost' and properties.lastUpdated >= ago(1d)\r\n| extend AffectedResource=tostring(properties.resourceMetadata.resourceId), Category=tostring(properties.category), SubCategory=tostring(properties.impactedField), Impact=tostring(properties.impact),resourceGroup,subscriptionId,Recommendation=tostring(properties.shortDescription.problem), id, stableId = name, recommendationTypeId = tostring(properties.recommendationTypeId), maxCpuP95 = properties.extendedProperties.MaxCpuP95\r\n| where SubCategory has \"Microsoft.Storage\"\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| project AffectedResource=tostring(properties.resourceMetadata.resourceId), Category=tostring(properties.category), SubCategory=tostring(properties.impactedField), Recommendation=tostring(properties.shortDescription.problem), Impact=tostring(properties.impact),resourceGroup,subscriptionId, id, stableId = name, recommendationTypeId = tostring(properties.recommendationTypeId), maxCpuP95 = properties.extendedProperties.MaxCpuP95\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isempty(resourceGroup) == true\r\n| project subscriptionId, excludeRecomm = properties.exclude, lowCpuThreshold = properties.lowCpuThreshold, AffectedResource=tostring(properties.resourceMetadata.resourceId),Impact=properties.impact,resourceGroup,AdditionaInfo=properties.extendedProperties,Recommendation=tostring(properties.shortDescription.problem))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| project-away subscriptionId1, subscriptionId2, AffectedResource1, isActive2, isActive3, Impact1, Recommendation1, resourceGroup1, resourceGroup2\r\n| where resourceGroup in ({ResourceGroup})", + "size": 0, + "title": "Azure Advisor Cost recommendations", + "noDataMessage": "You are following all of our cost recommendations for Storage", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Group", + "formatter": 1 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id", + "formatter": 5 + }, + { + "columnMatch": "stableId", + "formatter": 5 + }, + { + "columnMatch": "recommendationTypeId", + "formatter": 5 + }, + { + "columnMatch": "maxCpuP95", + "formatter": 5 + }, + { + "columnMatch": "excludeRecomm", + "formatter": 5 + }, + { + "columnMatch": "lowCpuThreshold", + "formatter": 5 + }, + { + "columnMatch": "AdditionaInfo", + "formatter": 5, + "formatOptions": { + "customColumnWidthSetting": "19ch" + } + }, + { + "columnMatch": "isActive1", + "formatter": 5 + }, + { + "columnMatch": "excludeProperty", + "formatter": 5 + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Recommendation" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "AffectedResource", + "label": "Affected Resource" + }, + { + "columnId": "Category", + "label": "Recommendation Category" + }, + { + "columnId": "SubCategory", + "label": "Affected Resource Type" + }, + { + "columnId": "Recommendation", + "label": "Recommendation" + }, + { + "columnId": "Impact", + "label": "Impact" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "Get-AdvisorRecommendations-Storage" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": " resources\r\n | where resourceGroup in ({ResourceGroup})\r\n | where type has \"Microsoft.Storage\"\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend AffectedResource=id,ResourceRG=resourceGroup\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n | project id", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "query - tags - list all storageresources" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"e84cba0d-e501-4f55-a761-9126fb305030\",\"mergeType\":\"innerunique\",\"leftTable\":\"Get-AdvisorRecommendations-Storage\",\"rightTable\":\"query - tags - list all storageresources\",\"leftColumn\":\"AffectedResource\",\"rightColumn\":\"id\"}],\"projectRename\":[{\"originalName\":\"[Get-AdvisorRecommendations-Storage].AffectedResource\",\"mergedName\":\"Affected Resource\",\"fromId\":\"e84cba0d-e501-4f55-a761-9126fb305030\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].Category\",\"mergedName\":\"Recommendation Category\",\"fromId\":\"e84cba0d-e501-4f55-a761-9126fb305030\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].SubCategory\",\"mergedName\":\"Affected Resource Type\",\"fromId\":\"e84cba0d-e501-4f55-a761-9126fb305030\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].Recommendation\",\"mergedName\":\"Recommendation\",\"fromId\":\"e84cba0d-e501-4f55-a761-9126fb305030\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].Impact\",\"mergedName\":\"Impact\",\"fromId\":\"e84cba0d-e501-4f55-a761-9126fb305030\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].resourceGroup\",\"mergedName\":\"Resource Group\",\"fromId\":\"e84cba0d-e501-4f55-a761-9126fb305030\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].subscriptionId\",\"mergedName\":\"Subscription ID\",\"fromId\":\"e84cba0d-e501-4f55-a761-9126fb305030\"},{\"originalName\":\"[query - tags - list all storageresources].id\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].excludeProperty\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].isActive1\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].AdditionaInfo\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].lowCpuThreshold\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].excludeRecomm\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].recommendationTypeId\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].maxCpuP95\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].stableId\"},{\"originalName\":\"[Get-AdvisorRecommendations-Storage].id\"}]}", + "size": 0, + "title": "Azure Advisor Cost recommendations", + "noDataMessage": "You are following all of our cost recommendations for Storage", + "noDataMessageStyle": 3, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "Affected Resource Type", + "formatter": 5 + }, + { + "columnMatch": "Subscription ID", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Recommendation" + ] + } + } + }, + "showPin": false, + "name": "query - Merge - Storage Advisor recommendations" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "advisorStorage" + }, + "name": "AdvisorGroupStorage" + } + ] + }, + "name": "group - 0" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "UsageOptimization" + }, + { + "parameterName": "SelectedRateOptimizationTab", + "comparison": "isEqualTo", + "value": "Storage" + } + ], + "name": "StorageGroup", + "styleSettings": { + "showBorder": true + } + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadFromTemplateId": "", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "94bd2bd0-5aa8-4df6-8cf7-603407f4e2d8", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "label": " Subscription" + }, + { + "id": "faa42c49-ab77-42a1-9aaf-d8508b9408af", + "version": "KqlParameterItem/1.0", + "name": "ResourceGroup", + "label": "Resource Group", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "resources\r\n| distinct resourceGroup", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "99a44dfa-30e2-4b2e-80a8-e05d2daab672", + "version": "KqlParameterItem/1.0", + "name": "SingleSubHidden", + "type": 1, + "isRequired": true, + "query": "resourcecontainers\r\n| where type==\"microsoft.resources/subscriptions\"\r\n| take 1\r\n| project subscriptionId", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Hidden Subscription" + }, + { + "id": "a02c21a6-cd5e-4e02-bb87-00993a06d8e8", + "version": "KqlParameterItem/1.0", + "name": "TagName", + "type": 2, + "query": "Resources\r\n| where tags != '' and tags != '[]'\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| distinct tagName\r\n| sort by tagName asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Name" + }, + { + "id": "add52b5b-2e8d-45d3-a304-f6d8f4b205f7", + "version": "KqlParameterItem/1.0", + "name": "TagValue", + "type": 2, + "query": "Resources\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| extend tagValue = tostring(tags[tagName])\r\n| where tags != '' and tags != '[]' and tostring(bag_keys(tags)[0]) == '{TagName}'\r\n| distinct tagValue\r\n| sort by tagValue asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Value" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "75", + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "CostInformation" + }, + { + "parameterName": "SelectedTab", + "comparison": "isNotEqualTo", + "value": "Welcome" + } + ], + "name": "parameters - Filters" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "1fc44b9a-2dd3-4b1f-bebd-b89d4ba6dfec", + "version": "KqlParameterItem/1.0", + "name": "Location", + "type": 2, + "query": "Resources\r\n| where type =~ 'Microsoft.Compute/virtualMachines'\r\n| project name, location\r\n| summarize count () by location\r\n| project location", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::1" + ] + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Resource Location" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "25", + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + "name": "parameters - location" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "0211f413-9f36-4750-9ef2-d382ba30ba6c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Virtual machines", + "subTarget": "VM", + "preText": "VM", + "style": "link" + }, + { + "id": "8a2fa734-a30e-404e-bf99-927c1891d4b9", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Virtual machine scale sets", + "subTarget": "VMSS", + "style": "link" + }, + { + "id": "6d563f46-7150-458c-9ee4-0558abe8e29b", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Advisor recommendations", + "subTarget": "advisorCompute", + "style": "link" + } + ] + }, + "name": "links - Compute" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Virtual Machines\r\n## Stopped virtual machines\r\nA virtual machine in a stopped state is still allocated the resources it was assigned, such as CPU and memory, but the VM itself is powered off. This allows for a quick startup when needed, but you are still billed for the allocated resources.", + "style": "upsell" + }, + "name": "text - StoppedVM" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'microsoft.compute/virtualmachines' and tostring(properties.extended.instanceView.powerState.displayStatus) != 'VM deallocated' and tostring(properties.extended.instanceView.powerState.displayStatus) != 'VM running'\r\n| where resourceGroup in ({ResourceGroup})\r\n| extend PowerState=tostring(properties.extended.instanceView.powerState.displayStatus), VMLocation=location, resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)\r\n| order by id asc\r\n| project id, PowerState, VMLocation, resourceGroup, subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id\r\n | project-away id1", + "size": 0, + "title": "Virtual Machines in a Stopped State", + "noDataMessage": "You have no VMs in a stopped state", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ] + } + }, + "name": "Get-StoppedVM" + }, + { + "type": 1, + "content": { + "json": "## Deallocated virtual machines\r\nA virtual machine in a deallocated state is not only powered off, but the underlying host infrastructure is also released, resulting in no charges for the allocated resources while the VM is in this state. However, some Azure resources such as disks and networking continue to incur charges.", + "style": "upsell" + }, + "name": "text - DeallocatedVM" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'microsoft.compute/virtualmachines' and tostring(properties.extended.instanceView.powerState.displayStatus) == 'VM deallocated'\r\n| where resourceGroup in ({ResourceGroup})\r\n| extend PowerState=tostring(properties.extended.instanceView.powerState.displayStatus), VMLocation=location, resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)\r\n| order by id asc\r\n| project id, PowerState, VMLocation, resourceGroup, subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id\r\n | project-away id1", + "size": 0, + "title": "Virtual Machines in a deallocated State", + "noDataMessage": "You have no VMs in a deallocated state", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "filter": true + } + }, + "name": "query - vmDeallocatedState" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "### Explore Different Processor Architectures to Optimize Costs\r\n\r\nDifferent processor architectures may offer cost advantages depending on your workload requirements. By exploring various processor types, you may find opportunities to reduce compute costs.\r\n\r\nConsider evaluating different architectures to determine the best fit for your needs.\r\n", + "style": "info" + }, + "name": "Text Processor type" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == 'microsoft.compute/virtualmachines'\r\n| extend vmSize = properties.hardwareProfile.vmSize\r\n| extend processorType = case(\r\n // ARM Processors\r\n vmSize has \"Epsv5\" or vmSize has \"Epdsv5\" or vmSize has \"Dpsv5\" or vmSize has \"Dpdsv\", \"ARM\",\r\n // AMD Processors\r\n vmSize has \"Standard_D2a\" or vmSize has \"Standard_D4a\" or vmSize has \"Standard_D8a\" or vmSize has \"Standard_D16a\" or vmSize has \"Standard_D32a\" or vmSize has \"Standard_D48a\" or vmSize has \"Standard_D64a\" or vmSize has \"Standard_D96a\" or vmSize has \"Standard_D2as\" or vmSize has \"Standard_D4as\" or vmSize has \"Standard_D8as\" or vmSize has \"Standard_D16as\" or vmSize has \"Standard_D32as\" or vmSize has \"Standard_D48as\" or vmSize has \"Standard_D64as\" or vmSize has \"Standard_D96as\", \"AMD\",\r\n \"Intel\"\r\n)\r\n| summarize count() by processorType\r\n", + "size": 0, + "title": "ProcessorType per VM", + "noDataMessage": "There are no VMs in your environment.", + "noDataMessageStyle": 5, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "tileSettings": { + "showBorder": false + } + }, + "customWidth": "50", + "name": "ProcessorType per VM" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\r\n| where type == 'microsoft.compute/virtualmachines'\r\n| extend vmSize = properties.hardwareProfile.vmSize\r\n| extend processorType = case(\r\n // ARM Processors\r\n vmSize has \"Epsv5\" or vmSize has \"Epdsv5\" or vmSize has \"Dpsv5\" or vmSize has \"Dpdsv\", \"ARM\",\r\n // AMD Processors\r\n vmSize has \"Standard_D2a\" or vmSize has \"Standard_D4a\" or vmSize has \"Standard_D8a\" or vmSize has \"Standard_D16a\" or vmSize has \"Standard_D32a\" or vmSize has \"Standard_D48a\" or vmSize has \"Standard_D64a\" or vmSize has \"Standard_D96a\" or vmSize has \"Standard_D2as\" or vmSize has \"Standard_D4as\" or vmSize has \"Standard_D8as\" or vmSize has \"Standard_D16as\" or vmSize has \"Standard_D32as\" or vmSize has \"Standard_D48as\" or vmSize has \"Standard_D64as\" or vmSize has \"Standard_D96as\" or vmSize has \"Standard_D2ads\" or vmSize has \"Standard_D4ads\"or vmSize has \"Standard_D8ads\" or vmSize has \"Standard_D16ads\" or vmSize has \"Standard_D32ads\"or vmSize has \"Standard_D48ads\"or vmSize has \"Standard_D64ads\"or vmSize has \"Standard_D96ads\", \"AMD\",\r\n \"Intel\"\r\n)\r\n| project vmName = name, processorType, vmSize, resourceGroup\r\n", + "size": 0, + "title": "List of VMs per processor type", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "customWidth": "50", + "name": "query - 1" + } + ] + }, + "name": "Group VM per Processor Type" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "VM" + }, + "name": "group - VMs" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "advisorresources\r\n| where type =~ 'microsoft.advisor/recommendations'\r\n| where resourceGroup in ({ResourceGroup})\r\n| where properties.category == 'Cost' and properties.lastUpdated >= ago(1d)\r\n| extend AffectedResource=tostring(properties.resourceMetadata.resourceId), Category=tostring(properties.category), SubCategory=tostring(properties.impactedField), Impact=tostring(properties.impact),subscriptionId,Recommendation=tostring(properties.shortDescription.problem), id, stableId = name, recommendationTypeId = tostring(properties.recommendationTypeId), maxCpuP95 = properties.extendedProperties.MaxCpuP95,resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| project AffectedResource=tostring(properties.resourceMetadata.resourceId), Category=tostring(properties.category), SubCategory=tostring(properties.impactedField), Recommendation=tostring(properties.shortDescription.problem), Impact=tostring(properties.impact),resourceGroup,subscriptionId, id, stableId = name, recommendationTypeId = tostring(properties.recommendationTypeId), maxCpuP95 = properties.extendedProperties.MaxCpuP95\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isempty(resourceGroup) == true\r\n| project subscriptionId, excludeRecomm = properties.exclude, lowCpuThreshold = properties.lowCpuThreshold, AffectedResource=tostring(properties.resourceMetadata.resourceId),Impact=tostring(properties.impact),resourceGroup,AdditionaInfo=properties.extendedProperties,Recommendation=tostring(properties.shortDescription.problem))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| where Category == 'Cost' \r\n| where SubCategory has \"Microsoft.Compute\" or SubCategory has \"Container\" or SubCategory has \"Web\"\r\n| where SubCategory !has \"Microsoft.Compute/disks\"\r\n| project-away subscriptionId1, subscriptionId2, AffectedResource1, isActive2, isActive3, Impact1, Recommendation1, resourceGroup1, resourceGroup2", + "size": 0, + "title": "Azure Advisor Cost recommendations", + "noDataMessage": "You are following all of our cost recommendations for Compute", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Group", + "formatter": 1 + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id", + "formatter": 5 + }, + { + "columnMatch": "stableId", + "formatter": 5 + }, + { + "columnMatch": "recommendationTypeId", + "formatter": 5 + }, + { + "columnMatch": "maxCpuP95", + "formatter": 5 + }, + { + "columnMatch": "excludeRecomm", + "formatter": 5 + }, + { + "columnMatch": "lowCpuThreshold", + "formatter": 5 + }, + { + "columnMatch": "AdditionaInfo", + "formatter": 5, + "formatOptions": { + "customColumnWidthSetting": "19ch" + } + }, + { + "columnMatch": "isActive1", + "formatter": 5 + }, + { + "columnMatch": "excludeProperty", + "formatter": 5 + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Recommendation" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "AffectedResource", + "label": "Affected Resource" + }, + { + "columnId": "Category", + "label": "Recommendation Category" + }, + { + "columnId": "SubCategory", + "label": "Affected Resource Type" + }, + { + "columnId": "Recommendation", + "label": "Recommendation" + }, + { + "columnId": "Impact", + "label": "Impact" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "subscriptionId", + "label": "Subscription ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "IsVisible", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "Get-AdvisorRecommendations-Compute" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": " resources\r\n | where resourceGroup in ({ResourceGroup})\r\n | where (type has \"Microsoft.Compute\" or type has \"Microsoft.ContainerService\" or type has \"serverfarms\") and type !has \"Disks\"\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend AffectedResource=id,ResourceRG=resourceGroup\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n | project id", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "isVisible", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "query - tags - list all compute resources" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"d446799d-b1af-4bca-9d72-84ba2d870039\",\"mergeType\":\"innerunique\",\"leftTable\":\"Get-AdvisorRecommendations-Compute\",\"rightTable\":\"query - tags - list all compute resources\",\"leftColumn\":\"AffectedResource\",\"rightColumn\":\"id\"}],\"projectRename\":[{\"originalName\":\"[Get-AdvisorRecommendations-Compute].AffectedResource\",\"mergedName\":\"Affected Resource\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].Category\",\"mergedName\":\"Recommendation Category\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].SubCategory\",\"mergedName\":\"Affected Resource Type\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].Recommendation\",\"mergedName\":\"Recommendation\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].Impact\",\"mergedName\":\"Impact\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].resourceGroup\",\"mergedName\":\"Resource Group\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].subscriptionId\",\"mergedName\":\"Subscription ID\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].id\",\"mergedName\":\"id\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].stableId\",\"mergedName\":\"stableId\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].recommendationTypeId\",\"mergedName\":\"recommendationTypeId\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].maxCpuP95\",\"mergedName\":\"maxCpuP95\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].excludeRecomm\",\"mergedName\":\"excludeRecomm\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].lowCpuThreshold\",\"mergedName\":\"lowCpuThreshold\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].AdditionaInfo\",\"mergedName\":\"AdditionaInfo\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].isActive1\",\"mergedName\":\"isActive1\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].excludeProperty\",\"mergedName\":\"excludeProperty\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[query - tags - list all compute resources].id\",\"mergedName\":\"id1\",\"fromId\":\"d446799d-b1af-4bca-9d72-84ba2d870039\"},{\"originalName\":\"[Get-AdvisorRecommendations-Compute].location\",\"mergedName\":\"location\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "Azure Advisor Cost recommendations", + "noDataMessage": "You are following all of our cost recommendations for Compute", + "noDataMessageStyle": 3, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "Group", + "formatter": 1 + }, + { + "columnMatch": "Affected Resource Type", + "formatter": 5 + }, + { + "columnMatch": "Resource Group", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Subscription ID", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id", + "formatter": 5 + }, + { + "columnMatch": "stableId", + "formatter": 5 + }, + { + "columnMatch": "recommendationTypeId", + "formatter": 5 + }, + { + "columnMatch": "maxCpuP95", + "formatter": 5 + }, + { + "columnMatch": "excludeRecomm", + "formatter": 5 + }, + { + "columnMatch": "lowCpuThreshold", + "formatter": 5 + }, + { + "columnMatch": "AdditionaInfo", + "formatter": 5 + }, + { + "columnMatch": "isActive1", + "formatter": 5 + }, + { + "columnMatch": "excludeProperty", + "formatter": 5 + }, + { + "columnMatch": "id1", + "formatter": 5 + } + ], + "rowLimit": 1000, + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Recommendation" + ] + } + } + }, + "showPin": false, + "name": "query - Merge - Compute Advisor recommendations" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "advisorCompute" + }, + "name": "AdvisorGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Virtual Machine Scale Sets\r\n## Save with Azure Spot VMs on Virtual Machine Scale Sets\r\nUsing Azure Spot Virtual Machines on scale sets allows you to take advantage of our unused capacity at a significant cost savings. At any point in time when Azure needs the capacity back, the Azure infrastructure will evict Azure Spot Virtual Machine instances. Therefore, Azure Spot Virtual Machine instances are great for workloads that can handle interruptions like batch processing jobs, dev/test environments, large compute workloads, and more.\r\n\r\n## Spot Priority Mix\r\nAzure allows you to have the flexibility of running a mix of uninterruptible standard VMs and interruptible Spot VMs for Virtual Machine Scale Set deployments. You're able to deploy this Spot Priority Mix using Flexible orchestration to easily balance between high-capacity availability and lower infrastructure costs according to your workload requirements\r\n", + "style": "upsell" + }, + "name": "text - 8" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where type =~ 'microsoft.compute/virtualmachinescalesets'\r\n| where resourceGroup in ({ResourceGroup})\r\n| extend SpotVMs=tostring(properties.virtualMachineProfile.priority), SpotPriorityMix=tostring(properties.priorityMixPolicy), SKU=tostring(sku.name), resourceGroup=strcat('/subscriptions/',subscriptionId,'/resourceGroups/',resourceGroup)\r\n| project id, SKU, SpotVMs,SpotPriorityMix,subscriptionId,resourceGroup, location\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}'])\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct id\r\n )\r\n on id", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "SpotVMs", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "Spot", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "warning", + "text": "Not using Spot VMs" + } + ] + } + }, + { + "columnMatch": "SpotPriorityMix", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "is Empty", + "representation": "2", + "text": "Not using Spot Priority Mix" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "id1", + "formatter": 5 + } + ], + "labelSettings": [ + { + "columnId": "id", + "label": "ID" + }, + { + "columnId": "SKU", + "label": "SKU" + }, + { + "columnId": "SpotVMs", + "label": "Spot VMs" + }, + { + "columnId": "SpotPriorityMix", + "label": "Spot Priority Mix" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Name" + }, + { + "columnId": "resourceGroup", + "label": "Resource Group" + }, + { + "columnId": "location", + "label": "Location" + } + ] + } + }, + "name": "query - 9" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "VMSS" + }, + "name": "group - VMSS" + } + ] + }, + "name": "Compute - Subscription" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "UsageOptimization" + }, + { + "parameterName": "SelectedRateOptimizationTab", + "comparison": "isEqualTo", + "value": "Compute" + } + ], + "name": "ComputeGroup", + "styleSettings": { + "showBorder": true + } + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "UsageOptimization" + }, + "name": "group - usage optimization" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Commitment-based savings\r\nTo maximize your Azure savings, consider savings plans for flexible usage and reserved instances for persistent needs. Azure Savings plans offer reduced rates with a fixed hourly spend and reserved instances allow pre-purchasing VM base price. Both options provide discounts and adapt to your usage patterns, helping you manage costs effectively. Below is an estimate of how much you can potentially save with 1-Year commitment for each option based on your usage pattern for the last 30 days.​", + "style": "upsell" + }, + "customWidth": "50", + "name": "text - P1YTotalSavings" + }, + { + "type": 1, + "content": { + "json": "## Commitment-based savings\r\nTo maximize your Azure savings, consider savings plans for flexible usage and reserved instances for persistent needs. Savings plans offer reduced rates with a fixed hourly spend, while reserved instances allow pre-purchasing VM base price. Both options provide discounts and adapt to your usage patterns, helping you manage costs effectively. Below is an estimate of how much you can save with 3-Year commitment for each option based on your usage pattern for the last 30 days.​", + "style": "upsell" + }, + "customWidth": "50", + "name": "text - P3YTotalSavings - Copy" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AdvisorResources \r\n| where type == 'microsoft.advisor/recommendations' \r\n| where properties.category == 'Cost' and (properties.shortDescription.solution contains \"Reserved Instance\" or properties.shortDescription.solution contains \"savings plan\")\r\n| extend\r\nrecommendationTypeId = tostring(properties.recommendationTypeId),\r\nreservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nterm=tostring(properties.extendedProperties.term),\r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId)\r\n| where term == \"P1Y\" and lookbackPeriod == \"Last 30 days\"\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources \r\n| where type =~ 'microsoft.advisor/configurations'\r\n| where isempty(resourceGroup) == true\r\n| extend\r\nmaxCpuP95 = properties.extendedProperties.MaxCpuP95,\r\nlowCpuThreshold = properties.lowCpuThreshold,\r\nexcludeRecomm = properties.exclude,\r\nreservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\nregion = tostring(properties.extendedProperties.region),\r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| extend reservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\nregion = tostring(properties.extendedProperties.region),\r\nresources=tostring(properties.resourceMetadata.resourceId), \r\nsubscription = tostring(properties.extendedProperties.subId),\r\ntypeOfRecommendation = iif(properties.shortDescription.solution contains \"Reserved Instance\", \"Reservations\", \"Savings plan\")\r\n| where term == \"P1Y\" and lookbackPeriod == \"Last 30 days\"\r\n| summarize bin (sum(savings), 0.01) by typeOfRecommendation,currency\r\n| order by sum_savings desc\r\n", + "size": 0, + "title": "1 year total commitment-based savings", + "noDataMessage": "There are no commitment-based recommendations", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "value::all" + ], + "visualization": "piechart", + "chartSettings": { + "seriesLabelSettings": [ + { + "seriesName": "Reservations", + "label": "Azure Reservations" + }, + { + "seriesName": "Savings plan", + "label": "Azure Savings Plan for Compute" + } + ] + } + }, + "customWidth": "50", + "name": "query - CommitmentBasedSavingsP1Y" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AdvisorResources \r\n| where type == 'microsoft.advisor/recommendations' \r\n| where properties.category == 'Cost' and (properties.shortDescription.solution contains \"Reserved Instance\" or properties.shortDescription.solution contains \"savings plan\")\r\n| extend\r\nrecommendationTypeId = tostring(properties.recommendationTypeId),\r\nreservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nterm=tostring(properties.extendedProperties.term),\r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId)\r\n| where term == \"P3Y\" and lookbackPeriod == \"Last 30 days\"\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources \r\n| where type =~ 'microsoft.advisor/configurations'\r\n| where isempty(resourceGroup) == true\r\n| extend\r\nmaxCpuP95 = properties.extendedProperties.MaxCpuP95,\r\nlowCpuThreshold = properties.lowCpuThreshold,\r\nexcludeRecomm = properties.exclude,\r\nreservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\nregion = tostring(properties.extendedProperties.region),\r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| extend reservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\nregion = tostring(properties.extendedProperties.region),\r\nresources=tostring(properties.resourceMetadata.resourceId), \r\nsubscription = tostring(properties.extendedProperties.subId),\r\ntypeOfRecommendation = iif(properties.shortDescription.solution contains \"Reserved Instance\", \"Reservations\", \"Savings plan\")\r\n| where term == \"P3Y\" and lookbackPeriod == \"Last 30 days\"\r\n| summarize bin (sum(savings), 0.01) by typeOfRecommendation,currency\r\n| order by sum_savings desc\r\n", + "size": 0, + "title": "3 years total commitment-based savings", + "noDataMessage": "There are no commitment-based recommendations", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "value::all" + ], + "visualization": "piechart", + "chartSettings": { + "seriesLabelSettings": [ + { + "seriesName": "Reservations", + "label": "Azure Reservations" + }, + { + "seriesName": "Savings plan", + "label": "Azure Savings Plan for Compute" + } + ] + } + }, + "customWidth": "50", + "name": "query - CommitmentBasedSavingsP3Y" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "792df0b2-35da-403d-999d-ff81ea8d4f56", + "cellValue": "selectedRateOptimizationTab", + "linkTarget": "parameter", + "linkLabel": "Azure Hybrid Benefit", + "subTarget": "AHB", + "style": "link" + }, + { + "id": "56eb4166-cb7c-4384-94a9-c5f201e1316d", + "cellValue": "selectedRateOptimizationTab", + "linkTarget": "parameter", + "linkLabel": "Azure Reservations", + "subTarget": "Reservations", + "style": "link" + }, + { + "id": "799d4fc7-5790-467c-84cc-ce4b4cc34a3f", + "cellValue": "selectedRateOptimizationTab", + "linkTarget": "parameter", + "linkLabel": "Azure savings plan for compute", + "subTarget": "SavingsPlan", + "style": "link" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RateOptimization" + }, + "name": "links - rate optimization tabs" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadFromTemplateId": "", + "items": [ + { + "type": 1, + "content": { + "json": "**Reserved instances** can provide a significant discount over on-demand prices. With reserved instances, you can pre-purchase the base costs for your virtual machines. \r\n
Discounts will automatically apply to new or existing VMs that have the same size and region as your reserved instance.
We analyzed your usage over selected Term, look-back period and recommend money-saving reserved instances​.\r\n
This query will only provide you recommendations for single scope reserved instances. *To learn more about Reserved Instances, go to this [link.](https://learn.microsoft.com/azure/cost-management-billing/manage/understand-vm-reservation-charges)*", + "style": "info" + }, + "name": "text - advisorReservationdDisclaimer" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "a1960768-9da4-455d-b6f6-6d43098cff76", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "label": " Subscription", + "value": [ + "value::all" + ] + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "75", + "name": "parameters - Filters" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "2b8ca845-75ba-4f4b-acad-54ee50d66d54", + "version": "KqlParameterItem/1.0", + "name": "LookBackPeriod", + "label": "Look back period", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\": \"Last 7 days\"},\r\n {\"value\": \"Last 30 days\"},\r\n {\"value\": \"Last 60 days\"}\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "Last 60 days" + }, + { + "id": "953c9e4c-af03-4fb7-bf30-3f1bfdf09199", + "version": "KqlParameterItem/1.0", + "name": "term", + "label": "Term", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [] + }, + "jsonData": "[\r\n {\r\n \"value\": \"P1Y\",\r\n \"Selected\": \"true\"\r\n },\r\n {\r\n \"value\": \"P3Y\"\r\n }\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "P3Y" + }, + { + "id": "c46193fe-f1b2-49d1-a9bc-c9f5149f0194", + "version": "KqlParameterItem/1.0", + "name": "resourceType", + "label": "Resource type", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "AdvisorResources \r\n| where type == 'microsoft.advisor/recommendations' \r\n| where properties.category == 'Cost' and properties.shortDescription.solution contains \"Reserved Instance\"\r\n| extend reservedResourceType=tostring(properties.extendedProperties.reservedResourceType)\r\n| distinct reservedResourceType", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": [ + "value::all" + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "name": "parameters - reservationsParams" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AdvisorResources \r\n| where type == 'microsoft.advisor/recommendations' \r\n| where properties.category == 'Cost' and properties.shortDescription.solution contains \"Reserved Instance\" \r\n| extend\r\nrecommendationTypeId = tostring(properties.recommendationTypeId),\r\nreservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nterm=tostring(properties.extendedProperties.term),\r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId)\r\n| where term == \"{term}\" and lookbackPeriod == \"{LookBackPeriod}\" and reservedResourceType in ({resourceType})\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources \r\n| where type =~ 'microsoft.advisor/configurations'\r\n| where isempty(resourceGroup) == true\r\n| extend\r\nmaxCpuP95 = properties.extendedProperties.MaxCpuP95,\r\nlowCpuThreshold = properties.lowCpuThreshold,\r\nexcludeRecomm = properties.exclude,\r\nreservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\nregion = tostring(properties.extendedProperties.region),\r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| extend reservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\nregion = tostring(properties.extendedProperties.region),\r\nresources=tostring(properties.resourceMetadata.resourceId), \r\nsubscription = tostring(properties.extendedProperties.subId)\r\n| where term == \"{term}\" and lookbackPeriod == \"{LookBackPeriod}\" and reservedResourceType in ({resourceType})\r\n| summarize Subscriptions=dcount(resources), \r\n bin (sum(savings), 0.01) by Recommendation ,reservedResourceType ,lookbackPeriod,scope,term ,currency\r\n| order by sum_savings desc\r\n", + "size": 0, + "title": "Reservations Summary", + "noDataMessage": "No reservations recommendations found!", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "categoricalbar", + "gridSettings": { + "filter": true, + "labelSettings": [ + { + "columnId": "reservedResourceType", + "label": "Resource type" + }, + { + "columnId": "lookbackPeriod", + "label": "Look back period" + }, + { + "columnId": "scope", + "label": "Scope" + }, + { + "columnId": "term", + "label": "Term" + }, + { + "columnId": "currency", + "label": "Currency" + }, + { + "columnId": "sum_savings", + "label": "Total annual savings" + } + ] + }, + "chartSettings": { + "xAxis": "reservedResourceType", + "yAxis": [ + "sum_savings" + ], + "group": "reservedResourceType", + "createOtherGroup": 0, + "showLegend": true, + "ySettings": { + "numberFormatSettings": { + "unit": 0, + "options": { + "style": "decimal", + "useGrouping": true + } + } + } + } + }, + "name": "query - Reservations Summary" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AdvisorResources \r\n| where type == 'microsoft.advisor/recommendations' \r\n| where properties.category == 'Cost' and properties.shortDescription.solution contains \"Reserved Instance\" \r\n| extend\r\nrecommendationTypeId = tostring(properties.recommendationTypeId),\r\nreservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nterm=tostring(properties.extendedProperties.term),\r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId)\r\n| where term == \"{term}\" and lookbackPeriod == \"{LookBackPeriod}\" and reservedResourceType in ({resourceType})\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources \r\n| where type =~ 'microsoft.advisor/configurations'\r\n| where isempty(resourceGroup) == true\r\n| extend\r\nmaxCpuP95 = properties.extendedProperties.MaxCpuP95,\r\nlowCpuThreshold = properties.lowCpuThreshold,\r\nexcludeRecomm = properties.exclude,\r\nreservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| extend reservedResourceType=tostring(properties.extendedProperties.reservedResourceType),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\nregion = tostring(properties.extendedProperties.region),\r\nsubscription = tostring(properties.extendedProperties.subId)\r\n| where term == \"{term}\" and lookbackPeriod == \"{LookBackPeriod}\" and reservedResourceType in ({resourceType})\r\n| project Recommendation,reservedResourceType,displaySKU,displayQty,savings,currency,lookbackPeriod,term,region,subscription\r\n| order by savings desc\r\n", + "size": 0, + "title": "Reservations details", + "noDataMessage": "No reservations recommendations found!", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Recommendation", + "formatter": 5 + }, + { + "columnMatch": "reservedResourceType", + "formatter": 5 + }, + { + "columnMatch": "subscription", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscription", + "reservedResourceType" + ], + "expandTopLevel": false + }, + "labelSettings": [ + { + "columnId": "displaySKU", + "label": "SKU" + }, + { + "columnId": "displayQty", + "label": "Quantity" + }, + { + "columnId": "savings", + "label": "Total annual savings" + }, + { + "columnId": "currency", + "label": "Currency" + }, + { + "columnId": "lookbackPeriod", + "label": "Look back period" + }, + { + "columnId": "term", + "label": "Term" + }, + { + "columnId": "region", + "label": "Region" + }, + { + "columnId": "subscription", + "label": "Subscription" + } + ] + }, + "chartSettings": { + "xAxis": "reservedResourceType", + "yAxis": [ + "sum_savings" + ], + "group": "reservedResourceType", + "createOtherGroup": 0, + "showLegend": true, + "ySettings": { + "numberFormatSettings": { + "unit": 0, + "options": { + "style": "decimal", + "useGrouping": true + } + } + } + } + }, + "name": "query - Reservations details" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RateOptimization" + }, + { + "parameterName": "selectedRateOptimizationTab", + "comparison": "isEqualTo", + "value": "Reservations" + } + ], + "name": "group - Reservations" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadFromTemplateId": "", + "items": [ + { + "type": 1, + "content": { + "json": "We analyzed your compute usage over the last 30 days and recommend adding a savings plan to increase your savings.
The savings plan unlocks lower prices on select compute services when you commit to spend a fixed hourly amount for 1 or 3 years.
As you use select compute services globally, your usage is covered by the plan at reduced prices. During the times when your usage is above your hourly commitment, you’ll simply be billed at your regular pay-as-you-go prices. With savings automatically applying across compute usage globally, you’ll continue saving even as your usage needs change over time.
Savings plan are more suited for dynamic workloads while accommodating for planned or unplanned changes while reservations are more suited for stable, predictable workloads with no planned changes.
Saving estimates are calculated for individual subscriptions and the usage pattern observed over last 30 days. **Shared scope savings plans are available in purchase experience and can further increase savings.**
\r\nTo learn more about Savings Plan, check out this [link.](https://learn.microsoft.com/azure/cost-management-billing/savings-plan/purchase-recommendations)​", + "style": "info" + }, + "name": "text - advisorSavingsPlanDisclaimer" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "a1960768-9da4-455d-b6f6-6d43098cff76", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "label": " Subscription", + "value": [ + "value::all" + ] + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "75", + "name": "parameters - Filters" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "2b8ca845-75ba-4f4b-acad-54ee50d66d54", + "version": "KqlParameterItem/1.0", + "name": "LookBackPeriod", + "label": "Look back period", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\": \"Last 7 days\"},\r\n {\"value\": \"Last 30 days\"},\r\n {\"value\": \"Last 60 days\"}\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "Last 30 days" + }, + { + "id": "953c9e4c-af03-4fb7-bf30-3f1bfdf09199", + "version": "KqlParameterItem/1.0", + "name": "term", + "label": "Term", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [] + }, + "jsonData": "[\r\n {\r\n \"value\": \"P1Y\",\r\n \"Selected\": \"true\"\r\n },\r\n {\r\n \"value\": \"P3Y\"\r\n }\r\n]", + "timeContext": { + "durationMs": 86400000 + }, + "value": "P1Y" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "name": "parameters - savingsPlanParams" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AdvisorResources \r\n| where type == 'microsoft.advisor/recommendations' \r\n| where properties.category == 'Cost' and properties.shortDescription.solution contains \"savings plan\"\r\n| extend recommendationTypeId = tostring(properties.recommendationTypeId),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nterm=tostring(properties.extendedProperties.term),\r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId),\r\ncommitment = tostring(properties.extendedProperties.commitment)\r\n| where term == \"{term}\" and lookbackPeriod == \"{LookBackPeriod}\"\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources \r\n| where type =~ 'microsoft.advisor/configurations'\r\n| where isempty(resourceGroup) == true\r\n| extend\r\nmaxCpuP95 = properties.extendedProperties.MaxCpuP95,\r\nlowCpuThreshold = properties.lowCpuThreshold,\r\nexcludeRecomm = properties.exclude,\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\nregion = tostring(properties.extendedProperties.region),\r\nstableId = name,\r\ncommitment = tostring(properties.extendedProperties.commitment),\r\nsubscriptionId = tostring(properties.extendedProperties.subId))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| extend lookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\nregion = tostring(properties.extendedProperties.region),\r\nresources=tostring(properties.resourceMetadata.resourceId), \r\nsubscription = tostring(properties.extendedProperties.subId),\r\ncommitment = tostring(properties.extendedProperties.commitment)\r\n| where term == \"{term}\" and lookbackPeriod == \"{LookBackPeriod}\"\r\n| summarize Subscriptions=dcount(resources), \r\n bin (sum(savings), 0.01) by subscription ,commitment ,lookbackPeriod,scope,term ,currency\r\n| order by sum_savings desc\r\n| join (\r\nresourcecontainers\r\n| where type == 'microsoft.resources/subscriptions'\r\n| extend subscription = subscriptionId\r\n| project name,subscription\r\n) on subscription\r\n| project-away subscription1,subscription\r\n", + "size": 0, + "title": "Savings plan Summary", + "noDataMessage": "No savings plan recommendations found!", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "categoricalbar", + "gridSettings": { + "filter": true + }, + "chartSettings": { + "xAxis": "name", + "yAxis": [ + "sum_savings" + ], + "group": "reservedResourceType", + "createOtherGroup": 0, + "showLegend": true, + "ySettings": { + "numberFormatSettings": { + "unit": 0, + "options": { + "style": "decimal", + "useGrouping": true + } + } + } + } + }, + "name": "query - Saving plan Summary" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "AdvisorResources \r\n| where type == 'microsoft.advisor/recommendations' \r\n| where properties.category == 'Cost' and properties.shortDescription.solution contains \"savings plan\"\r\n| extend\r\nrecommendationTypeId = tostring(properties.recommendationTypeId),\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nterm=tostring(properties.extendedProperties.term),\r\nstableId = name,\r\nsubscriptionId = tostring(properties.extendedProperties.subId),\r\ncommitment = tostring(properties.extendedProperties.commitment)\r\n| where term == \"{term}\" and lookbackPeriod == \"{LookBackPeriod}\"\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources | where type=~'microsoft.advisor/suppressions'\r\n| extend tokens = split(id, '/')\r\n| extend stableId = iff(array_length(tokens) > 3, tokens[(array_length(tokens)-3)], '')\r\n| extend expirationTimeStamp = todatetime(iff(strcmp(tostring(properties.ttl), '-1') == 0, '9999-12-31', properties.expirationTimeStamp))\r\n| where expirationTimeStamp > now()\r\n| project stableId, expirationTimeStamp)\r\non stableId\r\n| where isempty(expirationTimeStamp)\r\n| extend subscriptionId,stableId\r\n| join kind = leftouter\r\n(advisorresources \r\n| where type =~ 'microsoft.advisor/configurations'\r\n| where isempty(resourceGroup) == true\r\n| extend\r\nmaxCpuP95 = properties.extendedProperties.MaxCpuP95,\r\nlowCpuThreshold = properties.lowCpuThreshold,\r\nexcludeRecomm = properties.exclude,\r\nlookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\nstableId = name,\r\ncommitment = tostring(properties.extendedProperties.commitment),\r\nsubscriptionId = tostring(properties.extendedProperties.subId))\r\non subscriptionId\r\n| extend isActive1 = iff(isnull(excludeRecomm), true, tobool(excludeRecomm) == false)\r\n| extend isActive2 = iff(recommendationTypeId == 'e10b1381-5f0a-47ff-8c7b-37bd13d7c974', iff((isnotempty(lowCpuThreshold) and isnotempty(maxCpuP95)), toint(maxCpuP95) < toint(lowCpuThreshold), iff((isempty(maxCpuP95) or toint(maxCpuP95) < 5), true, false)), true)\r\n| where isActive1 == true and isActive2 == true\r\n| join kind = leftouter\r\n(advisorresources | where type =~ 'microsoft.advisor/configurations' | where isnotempty(resourceGroup) == true\r\n| project subscriptionId, resourceGroup, excludeProperty = properties.exclude)\r\non subscriptionId, resourceGroup\r\n| extend isActive3 = iff(isnull(excludeProperty), true, tobool(excludeProperty) == false)\r\n| where isActive3 == true\r\n| extend lookbackPeriod=tostring(strcat(\"Last \",properties.extendedProperties.lookbackPeriod,\" days\")),\r\nscope=tostring(properties.extendedProperties.scope),\r\nterm=tostring(properties.extendedProperties.term),\r\nsavings=todouble(properties.extendedProperties.annualSavingsAmount),\r\nsavingsAmount = todouble(properties.extendedProperties.savingsAmount),\r\nRecommendation=tostring(properties.shortDescription.solution), \r\ncurrency = tostring(properties.extendedProperties.savingsCurrency),\r\ndisplayQty = tostring(properties.extendedProperties.displayQty),\r\ndisplaySKU = tostring(properties.extendedProperties.displaySKU),\r\ncommitment = tostring(properties.extendedProperties.commitment),\r\nregion = tostring(properties.extendedProperties.region),\r\nsubscription = tostring(properties.extendedProperties.subId)\r\n| where term == \"{term}\" and lookbackPeriod == \"{LookBackPeriod}\"\r\n| project Recommendation,savings,commitment,currency,lookbackPeriod,term,subscription\r\n| order by savings desc\r\n| join (\r\nresourcecontainers\r\n| where type == 'microsoft.resources/subscriptions'\r\n| extend subscription = subscriptionId\r\n| project id,name,subscription\r\n) on subscription\r\n| project-away subscription1,subscription\r\n", + "size": 0, + "title": "Savings plan details", + "noDataMessage": "No savings plan recommendations found!", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Recommendation", + "formatter": 5 + }, + { + "columnMatch": "id", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "name", + "formatter": 5 + }, + { + "columnMatch": "reservedResourceType", + "formatter": 5 + }, + { + "columnMatch": "subscription", + "formatter": 5 + } + ], + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "id" + ] + }, + "labelSettings": [ + { + "columnId": "savings", + "label": "Total annual savings" + }, + { + "columnId": "commitment", + "label": "Commitment" + }, + { + "columnId": "currency", + "label": "Currency" + }, + { + "columnId": "lookbackPeriod", + "label": "Look back period" + }, + { + "columnId": "term", + "label": "Term" + } + ] + }, + "chartSettings": { + "xAxis": "reservedResourceType", + "yAxis": [ + "sum_savings" + ], + "group": "reservedResourceType", + "createOtherGroup": 0, + "showLegend": true, + "ySettings": { + "numberFormatSettings": { + "unit": 0, + "options": { + "style": "decimal", + "useGrouping": true + } + } + } + } + }, + "name": "query - Savings plan details" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RateOptimization" + }, + { + "parameterName": "selectedRateOptimizationTab", + "comparison": "isEqualTo", + "value": "SavingsPlan" + } + ], + "name": "group - SavingsPlan" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "2b43eb64-bca3-444a-8003-003554236fe7", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "label": " Subscription", + "value": [ + "value::all" + ] + }, + { + "id": "03fbf28a-892d-4b68-929c-3ba5056f4b94", + "version": "KqlParameterItem/1.0", + "name": "ResourceGroup", + "label": "Resource Group", + "type": 2, + "isRequired": true, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "query": "resources\r\n| distinct resourceGroup", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "showDefault": false + }, + "defaultValue": "value::all", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "566c43ae-f300-43be-aa0d-61d92ba8da87", + "version": "KqlParameterItem/1.0", + "name": "SingleSubHidden", + "type": 1, + "isRequired": true, + "query": "resourcecontainers\r\n| where type==\"microsoft.resources/subscriptions\"\r\n| take 1\r\n| project subscriptionId", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Hidden Subscription" + }, + { + "id": "a9df02ed-7100-4130-952f-a3d9d5d364af", + "version": "KqlParameterItem/1.0", + "name": "TagName", + "type": 2, + "query": "Resources\r\n| where tags != '' and tags != '[]'\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| distinct tagName\r\n| sort by tagName asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Name" + }, + { + "id": "66406915-1f07-448f-8170-2f3b0dc6dc00", + "version": "KqlParameterItem/1.0", + "name": "TagValue", + "type": 2, + "query": "Resources\r\n| mvexpand tags\r\n| extend tagName = tostring(bag_keys(tags)[0])\r\n| extend tagValue = tostring(tags[tagName])\r\n| where tags != '' and tags != '[]' and tostring(bag_keys(tags)[0]) == '{TagName}'\r\n| distinct tagValue\r\n| sort by tagValue asc", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [] + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "value": null, + "label": "Tag Value" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "75", + "conditionalVisibility": { + "parameterName": "selectedRateOptimizationTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + "name": "parameters - Filters" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "{Subscription}" + ], + "parameters": [ + { + "id": "f74bc7f5-2b16-4440-8053-106e040b73b6", + "version": "KqlParameterItem/1.0", + "name": "Location", + "type": 2, + "query": "Resources\r\n| where type =~ 'Microsoft.Compute/virtualMachines'\r\n| project name, location\r\n| summarize count () by location\r\n| project location", + "crossComponentResources": [ + "{Subscription}" + ], + "typeSettings": { + "additionalResourceOptions": [ + "value::1" + ] + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::1", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "label": "Resource Location" + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "customWidth": "25", + "conditionalVisibility": { + "parameterName": "selectedRateOptimizationTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + "name": "parameters - location" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "template", + "loadType": "always", + "loadFromTemplateId": "", + "items": [ + { + "type": 1, + "content": { + "json": "# Azure Hybrid Benefit\r\nFor customers with Software Assurance, Azure Hybrid Benefit for Windows Server allows you to use your on-premises Windows Server licenses to run Windows virtual machines on Azure at a reduced cost. This article discusses how to deploy new VMs with Azure Hybrid Benefit for Windows Server enabled, and how you can update any existing running VMs. For more information about Azure Hybrid Benefit for Windows Server licensing and cost savings, see the [Azure Hybrid Benefit for Windows Server licensing page](https://azure.microsoft.com/pricing/hybrid-use-benefit/)\r\n\r\n", + "style": "upsell" + }, + "name": "Azure Hybrid Benefit" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"path\":\"/subscriptions/{SingleSubHidden}/providers/Microsoft.Compute/skus?$filter=location eq '{Location}'\",\"urlParams\":[{\"key\":\"api-version\",\"value\":\"2021-07-01\"}],\"batchDisabled\":false,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.*[?(@.resourceType=='virtualMachines')]\",\"columns\":[{\"path\":\"name\",\"columnid\":\"Name\"},{\"path\":\"capabilities[?(@.name=='vCPUs')].value\",\"columnid\":\"vCPUs\"},{\"path\":\"capabilities[?(@.name=='MemoryGB')].value\",\"columnid\":\"MemoryGB\"},{\"path\":\"capabilities[?(@.name=='MaxNetworkInterfaces')].value\",\"columnid\":\"MaxNetworkInterfaces\"},{\"path\":\"capabilities[?(@.name=='HyperVGenerations')].value\",\"columnid\":\"HyperVGenerations\"},{\"path\":\"capabilities[?(@.name=='vCPUsPerCore')].value\",\"columnid\":\"vCPUsPerCore\"}]}}]}", + "size": 0, + "title": "Get VM vCPU", + "exportParameterName": "ResourceSKU", + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "rowLimit": 5000 + } + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "API-Get_VM_SKU" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "3f12a4b6-b18d-4191-8c1c-6045a7edcb6b", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "VM/VMSS", + "subTarget": "VM", + "style": "link" + }, + { + "id": "78ac1878-4b69-4f32-af1f-a8f095afbed5", + "cellValue": "SelectedTab", + "linkTarget": "parameter", + "linkLabel": "SQL", + "subTarget": "SQL", + "style": "link" + } + ] + }, + "name": "links - 1" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "0211f413-9f36-4750-9ef2-d382ba30ba6c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Windows Virtual Machines", + "subTarget": "VM", + "preText": "VM", + "style": "link" + }, + { + "id": "dbe9a7fb-6ab1-4de1-a98b-4ec8a9af906c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "Linux Virtual Machines", + "subTarget": "LinuxVM", + "style": "link" + }, + { + "id": "79e7a97a-1413-41e8-b4c6-ebd1d0a45e2e", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "VM Scale Set", + "subTarget": "VMSS", + "style": "link" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "VM" + }, + "name": "links - 4" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "Virtual Machines", + "loadType": "always", + "items": [ + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "loadType": "always", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\nresources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'microsoft.compute/virtualmachines' or type =~ 'microsoft.compute/virtualMachineScaleSets'\r\n| where tostring(properties.storageProfile.imageReference.publisher ) == \"MicrosoftWindowsServer\" or tostring(properties.virtualMachineProfile.storageProfile.osDisk.osType) == 'Windows' or tostring(properties.storageProfile.imageReference.publisher ) == \"microsoftsqlserver\"\r\n| where tostring(properties.['licenseType']) !has 'Windows' and tostring(properties.virtualMachineProfile.['licenseType']) != 'Windows_Server'\r\n| extend WindowsId=id, VMIDFull=id, VMName=name, VMLocation=location, VMRG=resourceGroup, OSType=tostring(properties.storageProfile.imageReference.offer), OsVersion = tostring(properties.storageProfile.imageReference.sku), VMSize=tostring (properties.hardwareProfile.vmSize), LicenseType = tostring(properties.['licenseType']), VMSSize=tostring(sku.name), QuickFix=id\r\n ) on subscriptionId \r\n| order by type asc \r\n| project WindowsId,VMName,VMRG,VMSize, VMSSize, VMLocation,OSType, OsVersion,LicenseType, subscriptionId, QuickFix, VMIDFull\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), WindowsId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct WindowsId\r\n )\r\n on WindowsId", + "size": 0, + "title": "AHB Disabled", + "noDataMessage": "All of your VMs have AHB enabled.", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "AHB Disabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\nresources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'microsoft.compute/virtualmachines'\r\n| where tostring(properties.storageProfile.imageReference.publisher ) == \"MicrosoftWindowsServer\" or tostring(properties.virtualMachineProfile.storageProfile.osDisk.osType) == 'Windows' or tostring(properties.storageProfile.imageReference.publisher ) == \"microsoftsqlserver\"\r\n| where tostring(properties.['licenseType']) has \"Windows\"\r\n| extend WindowsId=id, VMName=name, VMLocation=location, VMRG=resourceGroup, OSType=tostring(properties.storageProfile.imageReference.offer), OsVersion = tostring(properties.storageProfile.imageReference.sku), VMSize=tostring (properties.hardwareProfile.vmSize), LicenseType = tostring(properties.['licenseType']), VMSSize=tostring(sku.name)\r\n) on subscriptionId \r\n| order by type asc \r\n| project WindowsId,VMName,VMRG,VMSize, VMSSize, VMLocation,OSType, OsVersion,LicenseType, subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), WindowsId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct WindowsId\r\n )\r\n on WindowsId", + "size": 0, + "title": "AHB Enabled", + "noDataMessage": "None of your VMs have AHB enabled.", + "noDataMessageStyle": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "VMRG", + "formatter": 0, + "tooltipFormat": { + "tooltip": "test" + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "WindowsAHBEnabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resourcechanges\r\n| where properties.changeType == \"Update\" and properties.targetResourceType == \"microsoft.compute/virtualmachines\"\r\n| mv-expand changes = properties.changes\r\n| mv-expand LicenseChanges=changes.['properties.licenseType']\r\n| extend WindowsId=id\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), WindowsId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct WindowsId\r\n )\r\n on WindowsId\r\n| where isnotnull(LicenseChanges)\r\n| where tostring(LicenseChanges.newValue) has \"Windows\"\r\n| project VMID=properties.targetResourceId, NewLicense=tostring(LicenseChanges.newValue), DateofChange=todatetime(properties.changeAttributes.timestamp)\r\n", + "size": 0, + "title": "VM Latest Change Last 7 days", + "noDataMessage": "AHB was not enabled in the last 7 days.", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "VM Latest Change Last 7 days" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"path\":\"/subscriptions/{SingleSubHidden}/providers/Microsoft.Compute/skus?$filter=location eq '{Location}'\",\"urlParams\":[{\"key\":\"api-version\",\"value\":\"2021-07-01\"}],\"batchDisabled\":false,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.*[?(@.resourceType=='virtualMachines')]\",\"columns\":[{\"path\":\"name\",\"columnid\":\"Name\"},{\"path\":\"capabilities[?(@.name=='vCPUs')].value\",\"columnid\":\"vCPUs\"},{\"path\":\"capabilities[?(@.name=='MemoryGB')].value\",\"columnid\":\"MemoryGB\"},{\"path\":\"capabilities[?(@.name=='MaxNetworkInterfaces')].value\",\"columnid\":\"MaxNetworkInterfaces\"},{\"path\":\"capabilities[?(@.name=='HyperVGenerations')].value\",\"columnid\":\"HyperVGenerations\"},{\"path\":\"capabilities[?(@.name=='vCPUsPerCore')].value\",\"columnid\":\"vCPUsPerCore\"}]}}]}", + "size": 0, + "title": "Get VM vCPU", + "exportParameterName": "ResourceSKU", + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "rowLimit": 5000 + } + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "query - Get VM vCPU" + }, + { + "type": 1, + "content": { + "json": "## Windows Azure Hybrid Benefit (AHB) Overview" + }, + "name": "AHB Overview" + }, + { + "type": 1, + "content": { + "json": "Each two-processor license or each set of 16-core licenses, either Datacenter or Standard editions, are entitled to two instances of up to 8 cores, or one instance of up to 16 cores.\r\n\r\nThe virtual machines (VMs) with less than 8 cores are categorized as **Low Priority**, while those with 8 or more cores are classified as **High Priority**. In situations where there are insufficient Azure Hybrid benefit licenses to cover all the VMs in the environment, it is recommended to prioritize the High Priority VMs.", + "style": "info" + }, + "name": "NUmber of Processors", + "styleSettings": { + "margin": "10px", + "showBorder": true + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\nresources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'microsoft.compute/virtualmachines'\r\n| where tostring(properties.storageProfile.osDisk.osType) == 'Windows'\r\n| extend WindowsId=id\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), WindowsId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct WindowsId\r\n )\r\n on WindowsId\r\n| extend LicenseType = tostring(properties.['licenseType'])\r\n| extend CheckAHBWindows = case(\r\n type == 'microsoft.compute/virtualmachines' or type =~ 'microsoft.compute/virtualMachineScaleSets', iif((properties.['licenseType'])\r\n !has 'Windows' and (properties.virtualMachineProfile.['licenseType']) !has 'Windows' , \"AHB Not Enabled\", \"AHB Enabled\"),\r\n \"Not Windows\"\r\n )\r\n) on subscriptionId \r\n| summarize count() by SubscriptionName, CheckAHBWindows\r\n", + "size": 0, + "title": "Summary of Windows VMs with or without AHB per Subscription", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "sortBy": [ + { + "itemKey": "SubscriptionName", + "sortOrder": 1 + } + ], + "labelSettings": [ + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "CheckAHBWindows", + "label": "Is AHB enabled?" + }, + { + "columnId": "count_", + "label": "Number of resources" + } + ] + }, + "sortBy": [ + { + "itemKey": "SubscriptionName", + "sortOrder": 1 + } + ], + "tileSettings": { + "titleContent": { + "columnMatch": "CheckAHBWindows", + "formatter": 1 + }, + "subtitleContent": { + "columnMatch": "SubscriptionName", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": false, + "size": "auto" + }, + "chartSettings": { + "xAxis": "SubscriptionName" + } + }, + "customWidth": "50", + "name": "Summary of Windows VMs with or without AHB per Subscription" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\nresources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'microsoft.compute/virtualmachines'\r\n| where tostring(properties.storageProfile.osDisk.osType) == 'Windows'\r\n| extend WindowsId=id\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), WindowsId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct WindowsId\r\n )\r\n on WindowsId\r\n| extend LicenseType = tostring(properties.['licenseType'])\r\n| extend CheckAHBWindows = case(\r\n type == 'microsoft.compute/virtualmachines' or type =~ 'microsoft.compute/virtualMachineScaleSets', iif((properties.['licenseType'])\r\n !has 'Windows' and (properties.virtualMachineProfile.['licenseType']) !has 'Windows' , \"AHB Not Enabled\", \"AHB Enabled\"),\r\n \"Not Windows\"\r\n )\r\n) on subscriptionId \r\n| summarize count() by CheckAHBWindows", + "size": 0, + "title": "Summary of Windows VMs with or without AHB", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart" + }, + "customWidth": "50", + "name": "Summary of Windows VMs with or without AHB" + }, + { + "type": 1, + "content": { + "json": "### Consumed Licenses\r\nTotal number of Windows licenses cores consumed by all Windows virtual machines.\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Consumed Licenses" + }, + { + "type": 1, + "content": { + "json": "### Number of required Cores to enable Windows Azure Hybrid Benefit\r\nNumber of cores required to enable AHB across the entire environment.", + "style": "info" + }, + "customWidth": "50", + "name": "Number of required Cores" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"50d79765-aad4-437e-a90b-8cc7865e7081\",\"mergeType\":\"inner\",\"leftTable\":\"WindowsAHBEnabled\",\"rightTable\":\"query - Get VM vCPU\",\"leftColumn\":\"VMSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[WindowsAHBEnabled].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[WindowsAHBEnabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\">=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores per VM\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"8\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"[\\\"vCPUs\\\"]\"}}]},{\"originalName\":\"[WindowsAHBEnabled].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[WindowsAHBEnabled].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"},{\"originalName\":\"[WindowsAHBEnabled].WindowsId\"},{\"originalName\":\"[WindowsAHBEnabled].VMRG\"},{\"originalName\":\"[WindowsAHBEnabled].VMLocation\"},{\"originalName\":\"[WindowsAHBEnabled].OSType\"},{\"originalName\":\"[WindowsAHBEnabled].OsVersion\"},{\"originalName\":\"[WindowsAHBEnabled].LicenseType\"},{\"originalName\":\"[query - Get VM vCPU].Name\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\"},{\"originalName\":\"[WindowsAHBEnabled].VMSSize\"}]}", + "size": 0, + "title": "Consumed Cores per AHB Priority", + "noDataMessage": "None of your VMs have AHB enabled", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Sev4", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "Consumed Cores per VM" + ], + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Consumed Cores per AHB Priority" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"d8deb22b-a596-43ee-acc4-180849d26130\",\"mergeType\":\"inner\",\"leftTable\":\"WindowsAHBEnabled\",\"rightTable\":\"query - Get VM vCPU\",\"leftColumn\":\"VMSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"ConsumedCores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"8\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"[\\\"vCPUs\\\"]\"}}]},{\"originalName\":\"[WindowsAHBEnabled].WindowsId\",\"mergedName\":\"WindowsId\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[WindowsAHBEnabled].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[WindowsAHBEnabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[WindowsAHBEnabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[WindowsAHBEnabled].VMSSize\",\"mergedName\":\"VMSSize\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[WindowsAHBEnabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[WindowsAHBEnabled].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[WindowsAHBEnabled].OsVersion\",\"mergedName\":\"OsVersion\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[WindowsAHBEnabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[query - Get VM vCPU].Name\",\"mergedName\":\"Name\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[query - Get VM vCPU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[WindowsAHBEnabled].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[WindowsAHBEnabled].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "Consumed Cores per VM", + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "ConsumedCores", + "formatter": 0, + "formatOptions": { + "aggregation": "Sum" + } + } + ] + }, + "tileSettings": { + "titleContent": {}, + "leftContent": { + "columnMatch": "ConsumedCores", + "formatter": 12, + "formatOptions": { + "palette": "blue" + } + }, + "showBorder": false + }, + "graphSettings": { + "type": 0 + }, + "chartSettings": { + "yAxis": [ + "ConsumedCores" + ], + "group": "VMName", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Consumed Cores per VM" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"50d79765-aad4-437e-a90b-8cc7865e7081\",\"mergeType\":\"inner\",\"leftTable\":\"AHB Disabled\",\"rightTable\":\"query - Get VM vCPU\",\"leftColumn\":\"VMSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\">=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores per VM\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"8\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"[\\\"vCPUs\\\"]\"}}]},{\"originalName\":\"[query - 0].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - 0].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"},{\"originalName\":\"[AHB Disabled].WindowsId\",\"mergedName\":\"WindowsId\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].VMSSize\",\"mergedName\":\"VMSSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].OsVersion\",\"mergedName\":\"OsVersion\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].Name\",\"mergedName\":\"Name\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].QuickFix\",\"mergedName\":\"QuickFix\",\"fromId\":\"unknown\"},{\"originalName\":\"[AHB Disabled].VMIDFull\",\"mergedName\":\"VMIDFull\",\"fromId\":\"unknown\"},{\"originalName\":\"[WindowsAHBEnabled].WindowsId\"},{\"originalName\":\"[WindowsAHBEnabled].VMRG\"},{\"originalName\":\"[WindowsAHBEnabled].VMLocation\"},{\"originalName\":\"[WindowsAHBEnabled].OSType\"},{\"originalName\":\"[WindowsAHBEnabled].OsVersion\"},{\"originalName\":\"[WindowsAHBEnabled].LicenseType\"},{\"originalName\":\"[query - Get VM vCPU].Name\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\"},{\"originalName\":\"[WindowsAHBEnabled].VMSSize\"}]}", + "size": 0, + "title": "Cores not enabled per AHB Priority", + "noDataMessage": "All of your VMs have AHB enabled", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Sev4", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "Consumed Cores per VM" + ], + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Cores NOT enabled per AHB Priority" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "ae5e8765-47ef-46a6-803b-6b7124c098d2", + "version": "KqlParameterItem/1.0", + "name": "AHBEnabled", + "label": "See VMs with AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "timeContext": { + "durationMs": 86400000 + }, + "value": "Yes" + }, + { + "id": "f1ac5e53-253c-4afb-8bc5-b1ba2efea3eb", + "version": "KqlParameterItem/1.0", + "name": "AHBDisabled", + "label": "See VMs without AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "value": "Yes" + }, + { + "id": "20a00706-a89b-42aa-8dea-9c44c93e8014", + "version": "KqlParameterItem/1.0", + "name": "LastAHB", + "label": "See VMs AHB enabled in the last 7 days", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "VM AHB Enabled" + }, + { + "type": 1, + "content": { + "json": "List of Windows VMs without Hybrid Benefit groupped by Subscription.", + "style": "info" + }, + "conditionalVisibility": { + "parameterName": "AHBDisabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "List of Windows VMs without AHB" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"50d79765-aad4-437e-a90b-8cc7865e7081\",\"mergeType\":\"inner\",\"leftTable\":\"AHB Disabled\",\"rightTable\":\"query - Get VM vCPU\",\"leftColumn\":\"VMSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[query - 0].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - 0].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[AHB Disabled].VMName\",\"mergedName\":\"VM Name\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\">=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"static\",\"resultVal\":\"High Priority\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"static\",\"resultVal\":\"Low Priority\"}}]},{\"originalName\":\"[AHB Disabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].QuickFix\",\"mergedName\":\"QuickFix\",\"fromId\":\"unknown\"},{\"originalName\":\"[AHB Disabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].OsVersion\",\"mergedName\":\"OsVersion\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].Name\",\"mergedName\":\"Name\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[AHB Disabled].VMIDFull\",\"mergedName\":\"VMIDFull\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - 0].VMName\"},{\"originalName\":\"[query - 0].VMSSize\"},{\"originalName\":\"[query - Get VM vCPU].Name\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\"},{\"originalName\":\"[AHB Disabled].WindowsId\"},{\"originalName\":\"[AHB Disabled].VMSSize\"}]}", + "size": 0, + "title": "VMs without AHB", + "noDataMessage": "All of your VMs have AHB enabled", + "noDataMessageStyle": 3, + "exportedParameters": [ + { + "fieldName": "VMIDFull", + "parameterName": "WindowsID" + }, + { + "fieldName": "VMRG", + "parameterName": "ResourceGroup", + "parameterType": 1 + }, + { + "fieldName": "VM Name", + "parameterName": "VMName", + "parameterType": 1 + }, + { + "fieldName": "Prioritize AHB?", + "parameterName": "AHBPriority", + "parameterType": 1 + } + ], + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "QuickFix", + "formatter": 7, + "formatOptions": { + "linkTarget": "ArmAction", + "linkLabel": "Apply Hybrid Benefit", + "linkIsContextBlade": true, + "armActionContext": { + "path": "/{WindowsID}?api-version=2023-03-01", + "headers": [], + "params": [], + "body": "{\r\n \"properties\": {\r\n \"licenseType\": \"Windows_Server\"\r\n }\r\n}\r\n\r\n", + "httpMethod": "PATCH", + "title": "Apply Hybrid Benefit to VM {VMName}", + "description": "# Windows Hybrid Benefit Application Information: VM \"{VMName}\"\n\n\n{WindowsID}\n\n**Attention!**\n\nThis action will apply the Windows Hybrid Benefit to the virtual machine with the name **{VMName}**. Please ensure that you are applying the benefit to the correct VM.\n\n**Resource Details:**\n\n- VM Name: {VMName}\n- Resource Group: {ResourceGroup}\n- Prioritize AHB: {AHBPriority}\n\n### Required RBAC Permissions\n\nTo perform this action, you need to have **Contributor** permissions on the Resource Group where the VM is located.\n\nPlease review the information carefully before proceeding with applying the Windows Hybrid Benefit.\n", + "actionName": "Applying Hybrid benefit to VM {VMName}", + "runLabel": "Apply Hybrid Benefit to VM: \"{VMName}\"" + } + } + }, + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Sev4", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + }, + "tooltipFormat": { + "tooltip": "The virtual machines (VMs) with less than 8 cores are categorized as Low Priority, while those with 8 or more cores are classified as High Priority. " + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "WindowsId1", + "formatter": 5 + }, + { + "columnMatch": "Name", + "formatter": 5 + }, + { + "columnMatch": "HyperVGenerations", + "formatter": 5 + }, + { + "columnMatch": "vCPUsPerCore", + "formatter": 5 + }, + { + "columnMatch": "VMIDFull", + "formatter": 5 + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "VM Name", + "label": "VM Name" + }, + { + "columnId": "VMRG", + "label": "Resource Group" + }, + { + "columnId": "VMLocation", + "label": "Location" + }, + { + "columnId": "QuickFix", + "label": "Enable AHB" + }, + { + "columnId": "Prioritize AHB?", + "label": "AHB Priority" + }, + { + "columnId": "VMSize", + "label": "SKU" + }, + { + "columnId": "OSType", + "label": "OS Type" + }, + { + "columnId": "OsVersion", + "label": "OS Version" + }, + { + "columnId": "LicenseType", + "label": "License Type" + }, + { + "columnId": "subscriptionId", + "label": "Subscription Name" + }, + { + "columnId": "MemoryGB", + "label": "Memory" + }, + { + "columnId": "MaxNetworkInterfaces", + "label": "Max. NICs" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "AHBDisabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "VM+SKU+vCores" + }, + { + "type": 1, + "content": { + "json": "List of Windows VMs with Hybrid Benefit groupped by Subscription.", + "style": "info" + }, + "conditionalVisibility": { + "parameterName": "AHBEnabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "AHB By SUbscription" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"50d79765-aad4-437e-a90b-8cc7865e7081\",\"mergeType\":\"inner\",\"leftTable\":\"WindowsAHBEnabled\",\"rightTable\":\"query - Get VM vCPU\",\"leftColumn\":\"VMSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[WindowsAHBEnabled].WindowsId\",\"mergedName\":\"VM Name\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[WindowsAHBEnabled].VMRG\",\"mergedName\":\"Resource Group\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[WindowsAHBEnabled].VMSize\",\"mergedName\":\"VM SKU\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - Get VM vCPU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\">=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"static\",\"resultVal\":\"High Priority\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"static\",\"resultVal\":\"Low Priority\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores per VM\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"8\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"([\\\"vCPUs\\\"] + 7) & ~7\"}}]},{\"originalName\":\"[WindowsAHBEnabled].LicenseType\",\"mergedName\":\"License Type\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[WindowsAHBEnabled].VMLocation\",\"mergedName\":\"Location\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[WindowsAHBEnabled].OSType\",\"mergedName\":\"OS Type\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[WindowsAHBEnabled].OsVersion\",\"mergedName\":\"OS Version\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[WindowsAHBEnabled].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[WindowsAHBEnabled].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - 0].VMName\"},{\"originalName\":\"[query - 0].VMSSize\"},{\"originalName\":\"[query - Get VM vCPU].Name\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\"},{\"originalName\":\"[WindowsAHBEnabled].VMSSize\"},{\"originalName\":\"[WindowsAHBEnabled].VMName\"}]}", + "size": 0, + "title": "VMs with AHB", + "noDataMessage": "None of your VMs have AHB enabled", + "noDataMessageStyle": 4, + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "2", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "WindowsId1", + "formatter": 5 + }, + { + "columnMatch": "Subscription Name", + "formatter": 5 + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "WindowsId1", + "label": "VM ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "AHBEnabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "VM+SKU+vCores-AHB" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"d8deb22b-a596-43ee-acc4-180849d26168\",\"mergeType\":\"inner\",\"leftTable\":\"VM Latest Change Last 7 days\",\"rightTable\":\"VM+SKU+vCores-AHB\",\"leftColumn\":\"VMID\",\"rightColumn\":\"VM Name\"}],\"projectRename\":[{\"originalName\":\"[VM Latest Change Last 7 days].VMID\",\"mergedName\":\"VMID\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM Latest Change Last 7 days].NewLicense\",\"mergedName\":\"NewLicense\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM Latest Change Last 7 days].DateofChange\",\"mergedName\":\"DateofChange\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].VM Name\",\"mergedName\":\"VM Name\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].Resource Group\",\"mergedName\":\"Resource Group\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].VM SKU\",\"mergedName\":\"VM SKU\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].Prioritize AHB?\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].License Type\",\"mergedName\":\"License Type\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].Consumed Cores per VM\",\"mergedName\":\"Consumed Cores per VM\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].Location\",\"mergedName\":\"Location\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].OS Type\",\"mergedName\":\"OS Type\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].OS Version\",\"mergedName\":\"OS Version\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[VM+SKU+vCores-AHB].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "Total Cores Enabled last 7 Days", + "noDataMessage": "Windows AHB hasn't been enabled in the last 7 days", + "showRefreshButton": true, + "queryType": 7, + "visualization": "barchart", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "NewLicense", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "vCPUs", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "chartSettings": { + "xAxis": "VM Name", + "yAxis": [ + "Consumed Cores per VM" + ], + "group": null, + "createOtherGroup": 0, + "seriesLabelSettings": [ + { + "seriesName": "Consumed Cores per VM", + "color": "grayBlue" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "LastAHB", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "Total Cores Enabled last 7 Days" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"d8deb22b-a596-43ee-acc4-180849d26168\",\"mergeType\":\"inner\",\"leftTable\":\"VM Latest Change Last 7 days\",\"rightTable\":\"VM+SKU+vCores-AHB\",\"leftColumn\":\"VMID\",\"rightColumn\":\"VM Name\"}],\"projectRename\":[{\"originalName\":\"[VM+SKU+vCores-AHB].VM Name\",\"mergedName\":\"VM Name\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].Resource Group\",\"mergedName\":\"Resource Group\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM Latest Change Last 7 days].NewLicense\",\"mergedName\":\"NewLicense\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM Latest Change Last 7 days].DateofChange\",\"mergedName\":\"DateofChange\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].VM SKU\",\"mergedName\":\"VM SKU\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].Consumed Cores per VM\",\"mergedName\":\"Consumed Cores per VM\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].Prioritize AHB?\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].Location\",\"mergedName\":\"Location\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26168\"},{\"originalName\":\"[VM+SKU+vCores-AHB].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[VM+SKU+vCores-AHB].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"},{\"originalName\":\"[VM Latest Change Last 7 days].VMID\"},{\"originalName\":\"[VM+SKU+vCores-AHB].OS Type\"},{\"originalName\":\"[VM+SKU+vCores-AHB].OS Version\"},{\"originalName\":\"[VM+SKU+vCores-AHB].License Type\"}]}", + "size": 0, + "title": "Total Cores Enabled last 7 Days - Detailed view", + "noDataMessage": "No AHB has been enabled in the last 7 days", + "showExportToExcel": true, + "queryType": 7, + "visualization": "table", + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "NewLicense", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "vCPUs", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "chartSettings": { + "xAxis": "VM Name", + "yAxis": [ + "Consumed Cores per VM" + ], + "group": null, + "createOtherGroup": 0, + "seriesLabelSettings": [ + { + "seriesName": "Consumed Cores per VM", + "color": "grayBlue" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "LastAHB", + "comparison": "isEqualTo", + "value": "Yes" + }, + "showPin": false, + "name": "Total Cores Enabled last 7 Days - Details" + } + ] + }, + "name": "VM" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "VM" + }, + { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "VM" + } + ], + "name": "VM/VMSS-RGFilter" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "0211f413-9f36-4750-9ef2-d382ba30ba6c", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "SQL Server VMs", + "subTarget": "SQLVM", + "preText": "VM", + "style": "link" + }, + { + "id": "79e7a97a-1413-41e8-b4c6-ebd1d0a45e2e", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "SQL DB", + "subTarget": "SQLDB", + "style": "link" + }, + { + "id": "1f381e5b-7071-41ce-a354-c2df93445cae", + "cellValue": "SelectedSubTab", + "linkTarget": "parameter", + "linkLabel": "SQL Managed Instances", + "subTarget": "SQLMI", + "style": "link" + } + ] + }, + "name": "links - 4" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\n resources | where type =~ 'Microsoft.SqlVirtualMachine/SqlVirtualMachines' and tostring(properties.['sqlServerLicenseType']) != 'AHUB' and resourceGroup in ({ResourceGroup})\r\n | extend SQLID=id, VMName = name, VMRG = resourceGroup, VMLocation = location, LicenseType = tostring(properties.['sqlServerLicenseType']), OSType=tostring(properties.storageProfile.imageReference.offer), SQLAgentType = tostring(properties.['sqlManagement']), SQLVersion = tostring(properties.['sqlImageOffer']), SQLSKU=tostring(properties.['sqlImageSku'])\r\n ) on subscriptionId \r\n| join (\r\n resources\r\n | where type =~ 'Microsoft.Compute/virtualmachines'\r\n | project VMName = tolower(name), VMSize = tostring(properties.hardwareProfile.vmSize)\r\n ) on VMName\r\n| order by id asc \r\n| project SQLID,VMName,VMRG, VMLocation, VMSize, SQLVersion, SQLSKU, SQLAgentType, LicenseType, SubscriptionName\r\n| where SQLSKU != \"Developer\" and SQLSKU != \"Express\"\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLID\r\n )\r\n on SQLID", + "size": 0, + "title": "SQL VM AHB Disabled", + "noDataMessage": "All of your VMs have AHB enabled.", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "Get-SQL-AHB-Disabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\n resources | where type =~ 'Microsoft.SqlVirtualMachine/SqlVirtualMachines' and tostring(properties.['sqlServerLicenseType']) == 'AHUB' and resourceGroup in ({ResourceGroup})\r\n | extend SQLID=id, VMName = name, VMRG = resourceGroup, VMLocation = location, LicenseType = tostring(properties.['sqlServerLicenseType']), OSType=tostring(properties.storageProfile.imageReference.offer), SQLAgentType = tostring(properties.['sqlManagement']), SQLVersion = tostring(properties.['sqlImageOffer']), SQLSKU=tostring(properties.['sqlImageSku'])\r\n ) on subscriptionId \r\n| join (\r\n resources\r\n | where type =~ 'Microsoft.Compute/virtualmachines'\r\n | project VMName = tolower(name), VMSize = tostring(properties.hardwareProfile.vmSize)\r\n ) on VMName\r\n| order by id asc \r\n| project SQLID,VMName,VMRG, VMLocation, VMSize, SQLVersion, SQLSKU, SQLAgentType, LicenseType, SubscriptionName\r\n| where SQLSKU != \"Developer\" and SQLSKU != \"Express\"\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLID\r\n )\r\n on SQLID", + "size": 0, + "title": "SQL VM AHB Enabled", + "noDataMessage": "None of your VMs have AHB enabled.", + "noDataMessageStyle": 5, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "Get-SQL-AHB-Enabled" + }, + { + "type": 1, + "content": { + "json": "## SQL Virtual Machines Azure Hybrid Benefit (AHB) Overview" + }, + "name": "SQL Text" + }, + { + "type": 1, + "content": { + "json": "Apply to SQL Server 1 to 4 vCPUs exchange: For every 1 core of SQL Server Enterprise Edition, you get 4 vCPUs of SQL Managed Instance or Azure SQL Database general purpose and Hyperscale tiers, or 4 vCPUs of SQL Server Standard edition on Azure VMs.\r\n\r\nThe SQL virtual machines (VMs) with less than 4 cores are categorized as **Low Priority**, while those with 8 or more cores are classified as **High Priority**. In situations where there are insufficient Azure Hybrid benefit licenses to cover all the VMs in the environment, it is recommended to prioritize the High Priority VMs.", + "style": "info" + }, + "name": "SQL License Info", + "styleSettings": { + "margin": "10px", + "showBorder": true + } + }, + { + "type": 1, + "content": { + "json": "### AHB Overview\r\nSummary of all SQL on VMs with and without SQL AHB.", + "style": "info" + }, + "name": "AHB Overview21" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "loadType": "explicit", + "loadButtonText": "Load SQL Info", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\n resources | where type =~ 'Microsoft.SqlVirtualMachine/SqlVirtualMachines' and resourceGroup in ({ResourceGroup})\r\n | extend SQLID=id, VMName = name, VMRG = resourceGroup, VMLocation = location, LicenseType = tostring(properties.['sqlServerLicenseType']), OSType=tostring(properties.storageProfile.imageReference.offer), SQLAgentType = tostring(properties.['sqlManagement']), SQLVersion = tostring(properties.['sqlImageOffer']), SQLSKU=tostring(properties.['sqlImageSku'])\r\n | where SQLSKU != \"Developer\" and SQLSKU != \"Express\"\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLID\r\n )\r\n on SQLID\r\n | extend CheckSQLVMAHB = case(\r\n type =~ 'Microsoft.SqlVirtualMachine/SqlVirtualMachines', iif((properties.['sqlServerLicenseType'])\r\n !has 'AHUB', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n \"Not SQL\"\r\n )\r\n ) on subscriptionId \r\n| summarize count() by SubscriptionName, CheckSQLVMAHB", + "size": 0, + "title": "Summary of SQL on VMs with or without AHB per Subscription", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ], + "labelSettings": [ + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "CheckSQLVMAHB", + "label": "Is AHB enabled?" + }, + { + "columnId": "count_", + "label": "Number of Resources" + } + ] + }, + "tileSettings": { + "titleContent": { + "columnMatch": "CheckSQLVMAHB", + "formatter": 1 + }, + "subtitleContent": { + "columnMatch": "SubscriptionName", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": false, + "size": "auto" + }, + "chartSettings": { + "xAxis": "SubscriptionName" + } + }, + "customWidth": "50", + "name": "Summary of SQL on VMs with or without AHB" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\n resources | where type =~ 'Microsoft.SqlVirtualMachine/SqlVirtualMachines' and resourceGroup in ({ResourceGroup})\r\n | extend SQLID=id, VMName = name, VMRG = resourceGroup, VMLocation = location, LicenseType = tostring(properties.['sqlServerLicenseType']), OSType=tostring(properties.storageProfile.imageReference.offer), SQLAgentType = tostring(properties.['sqlManagement']), SQLVersion = tostring(properties.['sqlImageOffer']), SQLSKU=tostring(properties.['sqlImageSku'])\r\n | where SQLSKU != \"Developer\" and SQLSKU != \"Express\"\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLID\r\n )\r\n on SQLID\r\n | extend CheckSQLVMAHB = case(\r\n type =~ 'Microsoft.SqlVirtualMachine/SqlVirtualMachines', iif((properties.['sqlServerLicenseType'])\r\n !has 'AHUB', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n \"Not SQL\"\r\n )\r\n ) on subscriptionId \r\n| summarize count() by CheckSQLVMAHB", + "size": 0, + "title": "Summary SQL Enabled and Disabled", + "noDataMessage": "You don't have any SQL VM", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart" + }, + "customWidth": "50", + "name": "Summary SQL Enabled and Disabled" + }, + { + "type": 1, + "content": { + "json": "### Consumed Licenses\r\nTotal number of SQL licenses cores consumed by all SQL running on Virtual Machines.\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Consumed Licenses123" + }, + { + "type": 1, + "content": { + "json": "### Number of required Cores to enable SQL Azure Hybrid Benefit\r\nNumber of cores required to enable SQL AHB across the entire environment.\r\n\r\n\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Number of required Cores to enable SQL AHB" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"cd7477ac-acd6-4894-b929-53348c7640e8\",\"mergeType\":\"inner\",\"leftTable\":\"API-Get_VM_SKU\",\"rightTable\":\"Get-SQL-AHB-Enabled\",\"leftColumn\":\"Name\",\"rightColumn\":\"VMSize\"}],\"projectRename\":[{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLID\",\"mergedName\":\"SQLID\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLVersion\",\"mergedName\":\"SQLVersion\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLSKU\",\"mergedName\":\"SQLSKU\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLAgentType\",\"mergedName\":\"SQLAgentType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[API-Get_VM_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLID1\",\"mergedName\":\"SQLID1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "SQL VM AHB Consumed Cores per VM", + "noDataMessage": "None of your VMs have AHB enabled.", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "Consumed Cores" + ], + "group": "VMName", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQL+SKU AHB Enabled - per VM" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"cd7477ac-acd6-4894-b929-53348c7640e8\",\"mergeType\":\"inner\",\"leftTable\":\"API-Get_VM_SKU\",\"rightTable\":\"Get-SQL-AHB-Enabled\",\"leftColumn\":\"Name\",\"rightColumn\":\"VMSize\"}],\"projectRename\":[{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLID\",\"mergedName\":\"SQLID\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLVersion\",\"mergedName\":\"SQLVersion\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLSKU\",\"mergedName\":\"SQLSKU\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLAgentType\",\"mergedName\":\"SQLAgentType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLID1\",\"mergedName\":\"SQLID1\",\"fromId\":\"unknown\"},{\"originalName\":\"[API-Get_VM_SKU].Name\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMName\"}]}", + "size": 0, + "title": "SQL VM AHB Consumed Cores per Priority", + "noDataMessage": "None of your VMs have AHB enabled.", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "showPin": false, + "name": "Summary SQL+SKU AHB Enabled -" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"cd7477ac-acd6-4894-b929-53348c7640b5\",\"mergeType\":\"inner\",\"leftTable\":\"API-Get_VM_SKU\",\"rightTable\":\"Get-SQL-AHB-Disabled\",\"leftColumn\":\"Name\",\"rightColumn\":\"VMSize\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"([\\\"vCPUs\\\"] +3) & ~3\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[API-Get_VM_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLID\",\"mergedName\":\"SQLID\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLVersion\",\"mergedName\":\"SQLVersion\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLSKU\",\"mergedName\":\"SQLSKU\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLAgentType\",\"mergedName\":\"SQLAgentType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLID1\",\"mergedName\":\"SQLID1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "Cores not enabled per AHB Priority", + "noDataMessage": "All of your VMs have AHB enabled.", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "warning", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "sortBy": [], + "chartSettings": { + "yAxis": [ + "Consumed Cores" + ], + "showMetrics": false, + "showLegend": true + } + }, + "customWidth": "33", + "name": " Summary - SQL Cores AHB Disabled " + } + ] + }, + "name": "SQL Overview RG" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "ae5e8765-47ef-46a6-803b-6b7124c098d2", + "version": "KqlParameterItem/1.0", + "name": "SQLAVMHUBEnabled", + "label": "See SQL VMs with AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "timeContext": { + "durationMs": 86400000 + } + }, + { + "id": "f1ac5e53-253c-4afb-8bc5-b1ba2efea3eb", + "version": "KqlParameterItem/1.0", + "name": "SQLVMAHBDisabled", + "label": "See SQL VMs without AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "value": "Yes" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "SQL AHB Disabled" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"cd7477ac-acd6-4894-b929-53348c7640b5\",\"mergeType\":\"inner\",\"leftTable\":\"API-Get_VM_SKU\",\"rightTable\":\"Get-SQL-AHB-Disabled\",\"leftColumn\":\"Name\",\"rightColumn\":\"VMSize\"}],\"projectRename\":[{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLID\",\"mergedName\":\"VM Name\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLVersion\",\"mergedName\":\"SQLVersion\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLSKU\",\"mergedName\":\"SQLSKU\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLAgentType\",\"mergedName\":\"SQLAgentType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640b5\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLID1\",\"mergedName\":\"SQLID1\",\"fromId\":\"unknown\"},{\"originalName\":\"[API-Get_VM_SKU].Name\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLID\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMName\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMRG\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMLocation\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLVersion\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLSKU\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SQLAgentType\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].LicenseType\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].SubscriptionName\"},{\"originalName\":\"[Get-SQL-AHB-Disabled].VMSize\"}]}", + "size": 0, + "title": "SQL VM AHB Disabled", + "noDataMessage": "All of your VMs have AHB enabled.", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "warning", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "success", + "text": "{0}{1}" + } + ] + } + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "SubscriptionName" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "VM Name", + "label": "Name" + }, + { + "columnId": "VMRG", + "label": "Resource Group" + }, + { + "columnId": "VMLocation", + "label": "Location" + }, + { + "columnId": "VMSize", + "label": "SKU" + }, + { + "columnId": "vCPUs", + "label": "Number of vCPU" + }, + { + "columnId": "Consumed Cores", + "label": "Consumed Cores" + }, + { + "columnId": "SQLVersion", + "label": "SQL Version" + }, + { + "columnId": "SQLSKU", + "label": "SQL SKU" + }, + { + "columnId": "SQLAgentType", + "label": "SQL Agent" + }, + { + "columnId": "LicenseType", + "label": "License Type" + }, + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "SQLID1", + "label": "Resource ID" + } + ] + }, + "sortBy": [] + }, + "conditionalVisibility": { + "parameterName": "SQLVMAHBDisabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "SQL+SKU AHB Disabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"cd7477ac-acd6-4894-b929-53348c7640e8\",\"mergeType\":\"inner\",\"leftTable\":\"API-Get_VM_SKU\",\"rightTable\":\"Get-SQL-AHB-Enabled\",\"leftColumn\":\"Name\",\"rightColumn\":\"VMSize\"}],\"projectRename\":[{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLID\",\"mergedName\":\"SQLID\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLVersion\",\"mergedName\":\"SQLVersion\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLSKU\",\"mergedName\":\"SQLSKU\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLAgentType\",\"mergedName\":\"SQLAgentType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"cd7477ac-acd6-4894-b929-53348c7640e8\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].SQLID1\",\"mergedName\":\"SQLID1\",\"fromId\":\"unknown\"},{\"originalName\":\"[API-Get_VM_SKU].Name\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\"},{\"originalName\":\"[Get-SQL-AHB-Enabled].VMName\"}]}", + "size": 0, + "title": "SQL VM AHB Enabled", + "noDataMessage": "None of your VMs have AHB enabled.", + "noDataMessageStyle": 4, + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Subscription", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "SubscriptionName" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "SQLID", + "label": "Name" + }, + { + "columnId": "VMRG", + "label": "Resource Group" + }, + { + "columnId": "VMLocation", + "label": "Location" + }, + { + "columnId": "VMSize", + "label": "SKU" + }, + { + "columnId": "vCPUs", + "label": "Number of vCPU" + }, + { + "columnId": "Consumed Cores", + "label": "Consumed Cores" + }, + { + "columnId": "SQLVersion", + "label": "SQL Version" + }, + { + "columnId": "SQLSKU", + "label": "SQL SKU" + }, + { + "columnId": "SQLAgentType", + "label": "SQL Agent" + }, + { + "columnId": "LicenseType", + "label": "License Type" + }, + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "SQLID1", + "label": "Resource ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "SQLAVMHUBEnabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "SQL+SKU AHB Enabled" + } + ] + }, + "name": "SQL Detailed Info" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "SQLVM" + }, + "name": "SQL VM" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "SQL Database", + "items": [ + { + "type": 1, + "content": { + "json": "## SQL Databases Azure Hybrid Benefit (AHB) Overview" + }, + "name": "SQL Databases AHB" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "e4aa368f-dcf2-44a6-88f9-a395c04eb21f", + "cellValue": "SQLType", + "linkTarget": "parameter", + "linkLabel": "SQL Database", + "subTarget": "SQLDatabase", + "style": "link" + }, + { + "id": "a94e8dc2-34be-4d97-934d-c27e1816c4fe", + "cellValue": "SQLType", + "linkTarget": "parameter", + "linkLabel": "SQL ElasticPool", + "subTarget": "SQLElastic", + "style": "link" + } + ] + }, + "name": "links - 8" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "SQLDB" + }, + "name": "text - 0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\"\r\n| extend SubscriptionName=name | join (resources | where type =~ 'Microsoft.Sql/servers/databases' and name != 'master' and tostring(properties.['licenseType']) == 'LicenseIncluded' and kind contains 'vcore' and kind !contains \"serverless\" and tostring(sku.name) != \"ElasticPool\"\r\n| extend SQLDBID=id,SQLName = name, SQLRG = resourceGroup, SKUName=tostring(sku.name), SKUTier=tostring(sku.tier), vCores=tostring(sku.capacity), SQLLocation = location, LicenseType = tostring(properties.['licenseType']), StorageAccountType=tostring(properties.['storageAccountType'])\r\n| extend CheckSQLDBAHB = case(\r\n type =~ 'Microsoft.Sql/servers/databases', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n\"Not SQL DB\"\r\n )\r\n) on subscriptionId \r\n| project SQLDBID,SQLName,SQLRG, SKUName, SKUTier, vCores, CheckSQLDBAHB,SQLLocation, LicenseType, StorageAccountType, SubscriptionName\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLDBID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLDBID\r\n )\r\n on SQLDBID\r\n", + "size": 0, + "title": "AHB Disabled", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "SQLDB AHB Disabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\"\r\n| extend SubscriptionName=name | join (resources | where type =~ 'Microsoft.Sql/servers/databases' and name != 'master' and tostring(properties.['licenseType']) != 'LicenseIncluded' and kind contains 'vcore' and kind !contains \"serverless\" and tostring(sku.name) != \"ElasticPool\"\r\n| extend SQLDBID=id,SQLName = name, SQLRG = resourceGroup, SKUName=sku.name, SKUTier=sku.tier, SQLLocation = location, vCores=tostring(sku.capacity), LicenseType = tostring(properties.['licenseType']), StorageAccountType=tostring(properties.['storageAccountType'])) on subscriptionId \r\n| project SQLDBID,SQLName,SQLRG, SKUName, SKUTier, vCores, SQLLocation, LicenseType, StorageAccountType, SubscriptionName\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLDBID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLDBID\r\n )\r\n on SQLDBID\r\n\r\n", + "size": 0, + "title": "AHB Enabled", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "SQLDB AHB Enabled" + }, + { + "type": 1, + "content": { + "json": "Apply to SQL Server 1 to 4 vCPUs exchange: For every 1 core of SQL Server Enterprise Edition, you get 4 vCPUs of SQL Managed Instance or Azure SQL Database general purpose and Hyperscale tiers, or 4 vCPUs of SQL Server Standard edition on Azure VMs.\r\n\r\nThe SQL virtual machines (VMs) with less than 4 cores are categorized as **Low Priority**, while those with 8 or more cores are classified as **High Priority**. In situations where there are insufficient Azure Hybrid benefit licenses to cover all the VMs in the environment, it is recommended to prioritize the High Priority VMs.\r\n\r\nFor Azure SQL Database, Azure Hybrid Benefit is only available when using the provisioned compute tier of the vCore-based purchasing model. Azure Hybrid Benefit doesn't apply to DTU-based purchasing models or the serverless compute tier.", + "style": "info" + }, + "name": "Apply to SQL Server 1 to 4 vCPUs " + }, + { + "type": 1, + "content": { + "json": "### AHB Overview\r\nSummary of all SQL Databases with and without SQL AHB.", + "style": "info" + }, + "name": " AHB Overview SQL DB" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "loadType": "explicit", + "loadButtonText": "Load SQL DB Info", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\n resources | where type =~ 'Microsoft.Sql/servers/databases' and name != 'master' and kind contains 'vcore' and kind !contains \"serverless\" and tostring(sku.name) != \"ElasticPool\"\r\n | extend SQLDBID=id,SQLName = name, SQLRG = resourceGroup, SKUName=sku.name, SKUTier=sku.tier, SQLLocation = location, LicenseType = tostring(properties.['licenseType']), StorageAccountType=tostring(properties.['storageAccountType'])\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLDBID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLDBID\r\n )\r\n on SQLDBID\r\n | extend CheckSQLDBAHB = case(\r\n type =~ 'Microsoft.Sql/servers/databases', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n \"Not SQL DB\"\r\n )\r\n ) on subscriptionId \r\n| summarize count() by SubscriptionName, CheckSQLDBAHB", + "size": 0, + "title": "Summary of SQL Databases with or without AHB per Subscription", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ], + "labelSettings": [ + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "CheckSQLDBAHB", + "label": "Is AHB enabled?" + }, + { + "columnId": "count_", + "label": "Number of resources" + } + ] + }, + "tileSettings": { + "titleContent": { + "columnMatch": "CheckSQLDBAHB", + "formatter": 1 + }, + "subtitleContent": { + "columnMatch": "SubscriptionName", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": false, + "size": "auto" + }, + "chartSettings": { + "xAxis": "SubscriptionName" + } + }, + "customWidth": "50", + "name": "Summary of SQL DBs with or without AHB per subs" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\n resources | where type =~ 'Microsoft.Sql/servers/databases' and name != 'master' and kind contains 'vcore' and kind !contains \"serverless\" and tostring(sku.name) != \"ElasticPool\"\r\n | extend SQLDBID=id,SQLName = name, SQLRG = resourceGroup, SKUName=sku.name, SKUTier=sku.tier, SQLLocation = location, LicenseType = tostring(properties.['licenseType']), StorageAccountType=tostring(properties.['storageAccountType'])\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLDBID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLDBID\r\n )\r\n on SQLDBID\r\n | extend CheckSQLDBAHB = case(\r\n type =~ 'Microsoft.Sql/servers/databases', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n \"Not SQL DB\"\r\n )\r\n ) on subscriptionId \r\n| summarize count() by CheckSQLDBAHB", + "size": 0, + "title": "Summary of SQL Databases with or without AHB", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "tileSettings": { + "titleContent": { + "columnMatch": "CheckSQLDBAHB", + "formatter": 1 + }, + "subtitleContent": { + "columnMatch": "SubscriptionName", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": false, + "size": "auto" + }, + "chartSettings": { + "xAxis": "SubscriptionName" + } + }, + "customWidth": "50", + "name": "Summary of SQL DBs with or without AHB " + }, + { + "type": 1, + "content": { + "json": "### Consumed Licenses\r\nTotal number of SQL licenses cores consumed by all SQL Databases\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Total number of SQL licenses cores consumed" + }, + { + "type": 1, + "content": { + "json": "### Number of required Cores to enable SQL Azure Hybrid Benefit\r\nNumber of cores required to enable SQL AHB across the entire environment.\r\n\r\n\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Text SQL DB" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071c2\",\"mergeType\":\"table\",\"leftTable\":\"SQLDB AHB Enabled\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[SQLDB AHB Enabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].StorageAccountType\",\"mergedName\":\"StorageAccountType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "SQL DB AHB Consumed Cores per VM", + "noDataMessage": "None of your SQL DB have AHB enabled.", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "Consumed Cores" + ], + "group": "SQLName", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQLDB+SKU AHB Enabled - per VM" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071c2\",\"mergeType\":\"table\",\"leftTable\":\"SQLDB AHB Enabled\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[SQLDB AHB Enabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].StorageAccountType\",\"mergedName\":\"StorageAccountType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "SQL DB AHB Consumed Cores per Priority", + "noDataMessage": "None of your SQL DB have AHB enabled.", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "Consumed Cores" + ], + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQLDB+SKU AHB Enabled - per Priority" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071c2\",\"mergeType\":\"table\",\"leftTable\":\"SQLDB AHB Disabled\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[SQLDB AHB Disabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].CheckSQLDBAHB\",\"mergedName\":\"CheckSQLDBAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].StorageAccountType\",\"mergedName\":\"StorageAccountType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLDB AHB Disabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "SQL DB AHB Cores not enabled per AHB Priority", + "noDataMessage": "All of your SQL DB have AHB enabled.", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "Consumed Cores" + ], + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQLDB+SKU AHB Disabled - per Priority" + } + ] + }, + "name": "SQL DB Info" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "ae5e8765-47ef-46a6-803b-6b7124c098d2", + "version": "KqlParameterItem/1.0", + "name": "SQLDBHUBEnabled", + "label": "See SQL DBs with AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "timeContext": { + "durationMs": 86400000 + } + }, + { + "id": "f1ac5e53-253c-4afb-8bc5-b1ba2efea3eb", + "version": "KqlParameterItem/1.0", + "name": "SQLDBAHBDisabled", + "label": "See SQL DBs without AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "SQL DB Without AHB" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071ed\",\"mergeType\":\"table\",\"leftTable\":\"SQLDB AHB Disabled\"}],\"projectRename\":[{\"originalName\":\"[SQLDB AHB Disabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].CheckSQLDBAHB\",\"mergedName\":\"CheckSQLDBAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].StorageAccountType\",\"mergedName\":\"StorageAccountType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLDB AHB Disabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "SQL DB AHB Disabled", + "noDataMessage": "All of your SQL DBs have AHB enabled.", + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "SubscriptionName", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "SubscriptionName" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "SQLDBID", + "label": "Database Name" + }, + { + "columnId": "SQLName", + "label": "Server Name" + }, + { + "columnId": "SQLRG", + "label": "Resource Group" + }, + { + "columnId": "SKUName", + "label": "SKU" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "vCores", + "label": "Number of vCore" + }, + { + "columnId": "CheckSQLDBAHB", + "label": "Is AHB enabled?" + }, + { + "columnId": "SQLLocation", + "label": "Location" + }, + { + "columnId": "LicenseType", + "label": "License Type" + }, + { + "columnId": "StorageAccountType", + "label": "Storage Account Type" + }, + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "SQLDBID1", + "label": "Resource ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "SQLDBAHBDisabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "SQL DB Disabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071f9\",\"mergeType\":\"table\",\"leftTable\":\"SQLDB AHB Enabled\"}],\"projectRename\":[{\"originalName\":\"[SQLDB AHB Enabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLDB AHB Enabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLDB AHB Enabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLDB AHB Enabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLDB AHB Enabled].StorageAccountType\",\"mergedName\":\"StorageAccountType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLDB AHB Enabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLDB AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "SQL DB AHB Enabled", + "noDataMessage": "None of you SQL DBs have AHB enabled.", + "noDataMessageStyle": 4, + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "labelSettings": [ + { + "columnId": "SQLDBID", + "label": "Name" + }, + { + "columnId": "SQLName", + "label": "Database Name" + }, + { + "columnId": "SQLRG", + "label": "Resource Group" + }, + { + "columnId": "SKUName", + "label": "SKU" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "SQLLocation", + "label": "Location" + }, + { + "columnId": "LicenseType", + "label": "License Type" + }, + { + "columnId": "StorageAccountType", + "label": "Storage Account Type" + }, + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "vCores", + "label": "Number of vCore" + }, + { + "columnId": "SQLDBID1", + "label": "Resource ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "SQLDBHUBEnabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "SQL DB AHB Enabled" + } + ] + }, + "name": "Load SQL DB Detailed Info" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SQLType", + "comparison": "isEqualTo", + "value": "SQLDatabase" + }, + "name": "SQLDatabase" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "SQL Elastic Pool" + }, + "name": "text - 0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\"\r\n| extend SubscriptionName=name | join (resources\r\n| where type =~ 'Microsoft.Sql/servers/elasticPools' and tostring(properties.['licenseType']) == 'LicenseIncluded' and kind contains 'vcore' and kind !contains \"serverless\"\r\n| extend SQLDBID=id,SQLName = name, SQLRG = resourceGroup, SKUName=tostring(sku.name), SKUTier=tostring(sku.tier), vCores=tostring(sku.capacity), SQLLocation = location, LicenseType = tostring(properties.['licenseType'])\r\n| extend CheckSQLDBAHB = case(\r\n type =~ 'Microsoft.Sql/servers/elasticPools', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n\"Not SQL DB\"\r\n )\r\n) on subscriptionId \r\n| project SQLDBID,SQLName,SQLRG, SKUName, SKUTier, vCores, CheckSQLDBAHB,SQLLocation, LicenseType, SubscriptionName\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLDBID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLDBID\r\n )\r\n on SQLDBID\r\n", + "size": 0, + "title": "AHB Disabled", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "SQLElastic AHB Disabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\"\r\n| extend SubscriptionName=name | join (resources\r\n| where type =~ 'Microsoft.Sql/servers/elasticPools' and tostring(properties.['licenseType']) != 'LicenseIncluded' and kind contains 'vcore' and kind !contains \"serverless\"\r\n| extend SQLDBID=id,SQLName = name, SQLRG = resourceGroup, SKUName=tostring(sku.name), SKUTier=tostring(sku.tier), vCores=tostring(sku.capacity), SQLLocation = location, LicenseType = tostring(properties.['licenseType'])\r\n| extend CheckSQLDBAHB = case(\r\n type =~ 'Microsoft.Sql/servers/elasticPools', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n\"Not SQL DB\"\r\n ) \r\n ) on subscriptionId \r\n| project SQLDBID,SQLName,SQLRG, SKUName, SKUTier, vCores, SQLLocation, LicenseType, CheckSQLDBAHB, SubscriptionName\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLDBID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLDBID\r\n )\r\n on SQLDBID\r\n\r\n", + "size": 0, + "title": "AHB Enabled", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "SQLElastic AHB Enabled" + }, + { + "type": 1, + "content": { + "json": "Apply to SQL Server 1 to 4 vCPUs exchange: For every 1 core of SQL Server Enterprise Edition, you get 4 vCPUs of SQL Managed Instance or Azure SQL Database general purpose and Hyperscale tiers, or 4 vCPUs of SQL Server Standard edition on Azure VMs.\r\n\r\nThe SQL virtual machines (VMs) with less than 4 cores are categorized as **Low Priority**, while those with 8 or more cores are classified as **High Priority**. In situations where there are insufficient Azure Hybrid benefit licenses to cover all the VMs in the environment, it is recommended to prioritize the High Priority VMs.\r\n\r\nFor Azure SQL Database, Azure Hybrid Benefit is only available when using the provisioned compute tier of the vCore-based purchasing model. Azure Hybrid Benefit doesn't apply to DTU-based purchasing models or the serverless compute tier.", + "style": "info" + }, + "name": "Apply to SQL Elastic Server 1 to 4 vCPUs " + }, + { + "type": 1, + "content": { + "json": "### AHB Overview\r\nSummary of all SQL Databases with and without SQL AHB.", + "style": "info" + }, + "name": " AHB Overview SQL Elastic" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "loadType": "explicit", + "loadButtonText": "Load SQL DB Info", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\nresources\r\n| where type =~ 'Microsoft.Sql/servers/elasticPools' and kind contains 'vcore' and kind !contains \"serverless\"\r\n| extend SQLDBID=id,SQLName = name, SQLRG = resourceGroup, SKUName=tostring(sku.name), SKUTier=tostring(sku.tier), vCores=tostring(sku.capacity), SQLLocation = location, LicenseType = tostring(properties.['licenseType'])\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLDBID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLDBID\r\n )\r\n on SQLDBID\r\n | extend CheckSQLDBAHB = case(\r\n type =~ 'Microsoft.Sql/servers/elasticPools', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n \"Not SQL DB\"\r\n )\r\n ) on subscriptionId \r\n| summarize count() by SubscriptionName, CheckSQLDBAHB", + "size": 0, + "title": "Summary of SQL Databases with or without AHB per Subscription", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ], + "labelSettings": [ + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "CheckSQLDBAHB", + "label": "Is AHB enabled?" + }, + { + "columnId": "count_", + "label": "Number of resources" + } + ] + }, + "tileSettings": { + "titleContent": { + "columnMatch": "CheckSQLDBAHB", + "formatter": 1 + }, + "subtitleContent": { + "columnMatch": "SubscriptionName", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": false, + "size": "auto" + }, + "chartSettings": { + "xAxis": "SubscriptionName" + } + }, + "customWidth": "50", + "name": "Summary of SQL Elastic with or without AHB per subs" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" | extend SubscriptionName=name \r\n| join (\r\nresources\r\n| where type =~ 'Microsoft.Sql/servers/elasticPools' and kind contains 'vcore' and kind !contains \"serverless\"\r\n| extend SQLDBID=id,SQLName = name, SQLRG = resourceGroup, SKUName=tostring(sku.name), SKUTier=tostring(sku.tier), vCores=tostring(sku.capacity), SQLLocation = location, LicenseType = tostring(properties.['licenseType'])\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), SQLDBID=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct SQLDBID\r\n )\r\n on SQLDBID\r\n | extend CheckSQLDBAHB = case(\r\n type =~ 'Microsoft.Sql/servers/elasticPools', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n \"Not SQL DB\"\r\n )\r\n ) on subscriptionId \r\n| summarize count() by CheckSQLDBAHB", + "size": 0, + "title": "Summary of SQL Databases with or without AHB", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "tileSettings": { + "titleContent": { + "columnMatch": "CheckSQLDBAHB", + "formatter": 1 + }, + "subtitleContent": { + "columnMatch": "SubscriptionName", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + } + }, + "showBorder": false, + "size": "auto" + }, + "chartSettings": { + "xAxis": "SubscriptionName" + } + }, + "customWidth": "50", + "name": "Summary of SQL DBs with or without AHB " + }, + { + "type": 1, + "content": { + "json": "### Consumed Licenses\r\nTotal number of SQL licenses cores consumed by all SQL Databases\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Total number of SQL licenses cores consumed" + }, + { + "type": 1, + "content": { + "json": "### Number of required Cores to enable SQL Azure Hybrid Benefit\r\nNumber of cores required to enable SQL AHB across the entire environment.\r\n\r\n\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Text SQL DB" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071c2\",\"mergeType\":\"table\",\"leftTable\":\"SQLElastic AHB Enabled\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[SQLElastic AHB Enabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].CheckSQLDBAHB\",\"mergedName\":\"CheckSQLDBAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"}]}", + "size": 0, + "title": "SQL DB Elastic Pools AHB Consumed Cores per VM", + "noDataMessage": "None of your SQL DB Elastic Pools have AHB enabled.", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "vCores" + ], + "group": "SQLName", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQLElastic+SKU AHB Enabled - per VM" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071c2\",\"mergeType\":\"table\",\"leftTable\":\"SQLElastic AHB Enabled\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[SQLElastic AHB Enabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].CheckSQLDBAHB\",\"mergedName\":\"CheckSQLDBAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"}]}", + "size": 0, + "title": "SQL Elastic AHB Consumed Cores per Priority", + "noDataMessage": "None of your SQL DB Elastic Pools have AHB enabled.", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "vCores" + ], + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQLElastic+SKU AHB Enabled - per Priority" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071c2\",\"mergeType\":\"table\",\"leftTable\":\"SQLElastic AHB Disabled\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[SQLElastic AHB Disabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].CheckSQLDBAHB\",\"mergedName\":\"CheckSQLDBAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLElastic AHB Disabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"}]}", + "size": 0, + "title": "SQL DB AHB Cores not enabled per AHB Priority", + "noDataMessage": "All of your SQL DB have AHB enabled.", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "vCores" + ], + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQLDB+SKU AHB Disabled - per Priority" + } + ] + }, + "name": "SQL Elastic Info" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "ae5e8765-47ef-46a6-803b-6b7124c098d2", + "version": "KqlParameterItem/1.0", + "name": "SQLDBHUBEnabled", + "label": "See SQL DBs with AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "timeContext": { + "durationMs": 86400000 + } + }, + { + "id": "f1ac5e53-253c-4afb-8bc5-b1ba2efea3eb", + "version": "KqlParameterItem/1.0", + "name": "SQLDBAHBDisabled", + "label": "See SQL DBs without AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "SQL DB Without AHB" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071ed\",\"mergeType\":\"table\",\"leftTable\":\"SQLElastic AHB Disabled\"}],\"projectRename\":[{\"originalName\":\"[SQLDB AHB Disabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLElastic AHB Disabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].CheckSQLDBAHB\",\"mergedName\":\"CheckSQLDBAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLElastic AHB Disabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"}]}", + "size": 0, + "title": "SQL DB AHB Disabled", + "noDataMessage": "All of your SQL DBs have AHB enabled.", + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "SubscriptionName", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "SubscriptionName" + ], + "expandTopLevel": true + }, + "labelSettings": [ + { + "columnId": "SQLDBID", + "label": "Database Name" + }, + { + "columnId": "SQLName", + "label": "Server Name" + }, + { + "columnId": "SQLRG", + "label": "Resource Group" + }, + { + "columnId": "SKUName", + "label": "SKU" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "vCores", + "label": "Number of vCore" + }, + { + "columnId": "CheckSQLDBAHB", + "label": "Is AHB enabled?" + }, + { + "columnId": "SQLLocation", + "label": "Location" + }, + { + "columnId": "LicenseType", + "label": "License Type" + }, + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "SQLDBID1", + "label": "Resource ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "SQLDBAHBDisabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "SQL DB Disabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071f9\",\"mergeType\":\"table\",\"leftTable\":\"SQLElastic AHB Enabled\"}],\"projectRename\":[{\"originalName\":\"[SQLDB AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLDB AHB Enabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLDBID\",\"mergedName\":\"SQLDBID\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].SKUName\",\"mergedName\":\"SKUName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].SKUTier\",\"mergedName\":\"SKUTier\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].CheckSQLDBAHB\",\"mergedName\":\"CheckSQLDBAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLElastic AHB Enabled].SQLDBID1\",\"mergedName\":\"SQLDBID1\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"}]}", + "size": 0, + "title": "SQL DB AHB Enabled", + "noDataMessage": "None of you SQL DBs have AHB enabled.", + "noDataMessageStyle": 4, + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "labelSettings": [ + { + "columnId": "SQLDBID", + "label": "Name" + }, + { + "columnId": "SQLName", + "label": "Database Name" + }, + { + "columnId": "SQLRG", + "label": "Resource Group" + }, + { + "columnId": "SKUName", + "label": "SKU" + }, + { + "columnId": "SKUTier", + "label": "SKU Tier" + }, + { + "columnId": "vCores", + "label": "Number of vCore" + }, + { + "columnId": "SQLLocation", + "label": "Location" + }, + { + "columnId": "LicenseType", + "label": "License Type" + }, + { + "columnId": "SubscriptionName", + "label": "Subscription Name" + }, + { + "columnId": "SQLDBID1", + "label": "Resource ID" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "SQLDBHUBEnabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "SQL DB AHB Enabled" + } + ] + }, + "name": "Load SQL DB Detailed Info" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SQLType", + "comparison": "isEqualTo", + "value": "SQLElastic" + }, + "name": "SQLElasticPool" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "SQLDB" + }, + "name": "SQLDBGroup" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "SQL Managed Instance", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\"\r\n | extend SubscriptionName=name \r\n | join (resources | where type =~ 'Microsoft.Sql/managedInstances' and tostring(properties.['licenseType']) == 'LicenseIncluded'\r\n | extend ManagedInstance=id, SQLRG=resourceGroup, SQLLocation=location, vCores=tostring(sku.capacity),LicenseType = tostring(properties.['licenseType'])\r\n | extend CheckSQLMIAHB = case(\r\n type =~ 'Microsoft.Sql/managedInstances', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n\"Not SQL DB\"\r\n ) \r\n ) on subscriptionId \r\n | project ManagedInstance,SQLRG, SQLLocation, CheckSQLMIAHB, vCores, LicenseType, SubscriptionName\r\n | where SQLRG in ({ResourceGroup})\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), ManagedInstance=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct ManagedInstance\r\n )\r\n on ManagedInstance", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "SQLMIAHBDisabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\"\r\n | extend SubscriptionName=name \r\n | join (resources | where type =~ 'Microsoft.Sql/managedInstances' and tostring(properties.['licenseType']) != 'LicenseIncluded'\r\n | extend ManagedInstance=id, SQLName=name, SQLRG=resourceGroup, SQLLocation=location, vCores=tostring(sku.capacity),LicenseType = tostring(properties.['licenseType'])\r\n | extend CheckSQLMIAHB = case(\r\n type =~ 'Microsoft.Sql/managedInstances', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n\"Not SQL DB\"\r\n ) \r\n ) on subscriptionId \r\n | project ManagedInstance, SQLName, SQLRG, SQLLocation, CheckSQLMIAHB, vCores, LicenseType, SubscriptionName\r\n | where SQLRG in ({ResourceGroup})\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), ManagedInstance=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct ManagedInstance\r\n )\r\n on ManagedInstance\r\n ", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "SQLMIAHBEnabled" + }, + { + "type": 1, + "content": { + "json": "# SQL Managed Instances Azure Hybrid Benefit (AHB) Overview\r\n" + }, + "name": "SQL Managed Instances AHB" + }, + { + "type": 1, + "content": { + "json": "Apply to SQL Server 1 to 4 vCPUs exchange: For every 1 core of SQL Server Enterprise Edition, you get 4 vCPUs of SQL Managed Instance or Azure SQL Database general purpose and Hyperscale tiers, or 4 vCPUs of SQL Server Standard edition on Azure VMs.\r\n\r\nThe SQL virtual machines (VMs) with less than 4 cores are categorized as **Low Priority**, while those with 8 or more cores are classified as **High Priority**. In situations where there are insufficient Azure Hybrid benefit licenses to cover all the VMs in the environment, it is recommended to prioritize the High Priority VMs.", + "style": "info" + }, + "name": "Apply to SQL Server 1 to 4 vCPUs exchange" + }, + { + "type": 1, + "content": { + "json": "### AHB Overview\r\nSummary of all SQL Databases with and without SQL AHB.", + "style": "info" + }, + "name": "SQL Databases with and without SQL AHB." + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "loadType": "explicit", + "loadButtonText": "Load SQL MI Info", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\"\r\n | extend SubscriptionName=name \r\n | join (resources | where type =~ 'Microsoft.Sql/managedInstances' \r\n | extend ManagedInstance=id, SQLRG=resourceGroup, SQLLocation=location, vCores=tostring(sku.capacity),LicenseType = tostring(properties.['licenseType'])\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), ManagedInstance=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct ManagedInstance\r\n )\r\n on ManagedInstance\r\n | extend CheckSQLMIAHB = case(\r\n type =~ 'Microsoft.Sql/managedInstances', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n\"Not SQL DB\"\r\n ) \r\n ) on subscriptionId \r\n| project ManagedInstance,SQLRG, SQLLocation, CheckSQLMIAHB, vCores, LicenseType, SubscriptionName\r\n| summarize count() by SubscriptionName, CheckSQLMIAHB", + "size": 0, + "title": "Summary of SQL MI with or without AHB per Subscription", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "table", + "tileSettings": { + "titleContent": { + "columnMatch": "CheckSQLMIAHB", + "formatter": 1 + }, + "subtitleContent": { + "columnMatch": "SubscriptionName" + }, + "leftContent": { + "columnMatch": "count_", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + }, + "showBorder": false + }, + "chartSettings": { + "yAxis": [ + "count_" + ], + "group": "CheckSQLMIAHB", + "createOtherGroup": null + } + }, + "customWidth": "50", + "name": "Summary of SQL MI with or without AHB per subs" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | where tostring (properties.subscriptionPolicies.quotaId) !has \"MSDNDevTest_2014-09-01\" \r\n | extend SubscriptionName=name \r\n | join (resources | where type =~ 'Microsoft.Sql/managedInstances'\r\n | extend ManagedInstance=id, SQLRG=resourceGroup, SQLLocation=location, vCores=tostring(sku.capacity),LicenseType = tostring(properties.['licenseType'])\r\n | join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), ManagedInstance=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct ManagedInstance\r\n )\r\n on ManagedInstance\r\n | extend CheckSQLMIAHB = case(\r\n type =~ 'Microsoft.Sql/managedInstances', iif((properties.['licenseType'])\r\n has 'LicenseIncluded', \"AHB Not Enabled\", \"AHB Enabled\"),\r\n\"Not SQL DB\"\r\n ) \r\n ) on subscriptionId \r\n| project ManagedInstance,SQLRG, SQLLocation, CheckSQLMIAHB, vCores, LicenseType, SubscriptionName\r\n| summarize count() by SubscriptionName, CheckSQLMIAHB", + "size": 0, + "title": "Summary of SQL Managed Instance with or without AHB", + "showRefreshButton": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart", + "chartSettings": { + "yAxis": [ + "count_" + ], + "group": "CheckSQLMIAHB", + "createOtherGroup": null + } + }, + "customWidth": "50", + "name": "Summary of SQL MI with or without AHB " + }, + { + "type": 1, + "content": { + "json": "### Consumed Licenses\r\nTotal number of SQL licenses cores consumed by all SQL Managed Instances.\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Consumed Licenses" + }, + { + "type": 1, + "content": { + "json": "### Number of required Cores to enable SQL Azure Hybrid Benefit\r\nNumber of cores required to enable SQL AHB across the entire environment.\r\n\r\n\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Number of required Cores to enable SQL " + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071c2\",\"mergeType\":\"table\",\"leftTable\":\"SQLMIAHBEnabled\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[SQLDB AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLMIAHBEnabled].ManagedInstance\",\"mergedName\":\"ManagedInstance\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].CheckSQLMIAHB\",\"mergedName\":\"CheckSQLMIAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].ManagedInstance1\",\"mergedName\":\"ManagedInstance1\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLMIAHBEnabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "SQL Managed Instance AHB Consumed Cores per VM", + "noDataMessage": "None of your SQL MI have AHB enabled.", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "vCores" + ], + "group": "SQLName", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQLMI+SKU AHB Enabled - per VM" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071c2\",\"mergeType\":\"table\",\"leftTable\":\"SQLMIAHBEnabled\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[SQLDB AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLMIAHBEnabled].ManagedInstance\",\"mergedName\":\"ManagedInstance\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].CheckSQLMIAHB\",\"mergedName\":\"CheckSQLMIAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBEnabled].ManagedInstance1\",\"mergedName\":\"ManagedInstance1\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLMIAHBEnabled].SQLName\",\"mergedName\":\"SQLName\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "SQL Managed Instance AHB Consumed Cores per Priority", + "noDataMessage": "None of your SQL MI have AHB enabled.", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "vCores" + ], + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQLMI+SKU AHB Enabled - per Priority" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071c2\",\"mergeType\":\"table\",\"leftTable\":\"SQLMIAHBDisabled\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"4\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"round([\\\"vCPUs\\\"] / 4) * 4\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCores\",\"operator\":\"<\",\"rightValType\":\"static\",\"rightVal\":\"4\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}}]},{\"originalName\":\"[SQLMIAHBDisabled].ManagedInstance\",\"mergedName\":\"ManagedInstance\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBDisabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBDisabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBDisabled].CheckSQLMIAHB\",\"mergedName\":\"CheckSQLMIAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBDisabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBDisabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBDisabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071c2\"},{\"originalName\":\"[SQLMIAHBDisabled].ManagedInstance1\",\"mergedName\":\"ManagedInstance1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "SQL Managed Instances AHB Cores not enabled per AHB Priority", + "noDataMessage": "All of your SQL MI have AHB enabled.", + "noDataMessageStyle": 3, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low Priority", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "vCores" + ], + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Summary SQLMI+SKU AHB Disabled - per Priority" + } + ] + }, + "name": "SQL MI Info" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "ae5e8765-47ef-46a6-803b-6b7124c098d2", + "version": "KqlParameterItem/1.0", + "name": "SQLMIAHBEnabled", + "label": "See SQL MIs with AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "timeContext": { + "durationMs": 86400000 + } + }, + { + "id": "f1ac5e53-253c-4afb-8bc5-b1ba2efea3eb", + "version": "KqlParameterItem/1.0", + "name": "SQLMIAHBDisabled", + "label": "See SQL MIs without AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "SQL MI AHB Disabled" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071ed\",\"mergeType\":\"table\",\"leftTable\":\"SQLMIAHBDisabled\"}],\"projectRename\":[{\"originalName\":\"[SQLMIAHBDisabled].ManagedInstance\",\"mergedName\":\"ManagedInstance\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLMIAHBDisabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLMIAHBDisabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLMIAHBDisabled].CheckSQLMIAHB\",\"mergedName\":\"CheckSQLMIAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLMIAHBDisabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLMIAHBDisabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"},{\"originalName\":\"[SQLMIAHBDisabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071ed\"}]}", + "size": 0, + "title": "SQL Managed Instance AHB Disabled", + "noDataMessage": "All of your SQL MIs have AHB enabled.", + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "SubscriptionName", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "SubscriptionName" + ], + "expandTopLevel": true + } + } + }, + "conditionalVisibility": { + "parameterName": "SQLMIAHBDisabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "SQL MI Disabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"f65bea23-bb49-4498-b331-c20c618071f9\",\"mergeType\":\"table\",\"leftTable\":\"SQLMIAHBEnabled\"}],\"projectRename\":[{\"originalName\":\"[SQLDB AHB Enabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"unknown\"},{\"originalName\":\"[SQLMIAHBEnabled].ManagedInstance\",\"mergedName\":\"ManagedInstance\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLMIAHBEnabled].SQLRG\",\"mergedName\":\"SQLRG\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLMIAHBEnabled].SQLLocation\",\"mergedName\":\"SQLLocation\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLMIAHBEnabled].CheckSQLMIAHB\",\"mergedName\":\"CheckSQLMIAHB\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLMIAHBEnabled].vCores\",\"mergedName\":\"vCores\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLMIAHBEnabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"},{\"originalName\":\"[SQLMIAHBEnabled].SubscriptionName\",\"mergedName\":\"SubscriptionName\",\"fromId\":\"f65bea23-bb49-4498-b331-c20c618071f9\"}]}", + "size": 0, + "title": "SQL Managed Instance AHB Enabled", + "noDataMessage": "None of you SQL MIs have AHB enabled.", + "showExportToExcel": true, + "queryType": 7 + }, + "conditionalVisibility": { + "parameterName": "SQLMIAHBEnabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "SQL MI AHB Enabled" + } + ] + }, + "name": "SQL MI Detailed" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "SQLMI" + }, + "name": "SQL MI" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "SQL" + }, + "name": "SQLAHB" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "Linux Hybrid Benefit", + "loadType": "explicit", + "loadButtonText": "Load Linux Recommendations", + "items": [ + { + "type": 1, + "content": { + "json": "## Linux Azure Hybrid Benefit (AHB) Overview" + }, + "name": "Linux Text" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"path\":\"/subscriptions/{SingleSubHidden}/providers/Microsoft.Compute/skus?$filter=location eq '{Location}'\",\"urlParams\":[{\"key\":\"api-version\",\"value\":\"2021-07-01\"}],\"batchDisabled\":false,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$.*[?(@.resourceType=='virtualMachines')]\",\"columns\":[{\"path\":\"name\",\"columnid\":\"Name\"},{\"path\":\"capabilities[?(@.name=='vCPUs')].value\",\"columnid\":\"vCPUs\"},{\"path\":\"capabilities[?(@.name=='MemoryGB')].value\",\"columnid\":\"MemoryGB\"},{\"path\":\"capabilities[?(@.name=='MaxNetworkInterfaces')].value\",\"columnid\":\"MaxNetworkInterfaces\"},{\"path\":\"capabilities[?(@.name=='HyperVGenerations')].value\",\"columnid\":\"HyperVGenerations\"},{\"path\":\"capabilities[?(@.name=='vCPUsPerCore')].value\",\"columnid\":\"vCPUsPerCore\"}]}}]}", + "size": 0, + "title": "Get VM vCPU", + "exportParameterName": "ResourceSKU", + "showExportToExcel": true, + "queryType": 12, + "gridSettings": { + "rowLimit": 5000 + } + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "API-Get_VMLinux_SKU" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'microsoft.compute/virtualmachines' and (properties.storageProfile.imageReference.publisher == 'suse' or properties.storageProfile.imageReference.publisher=='RedHat')\r\n| where isnull ((properties.['licenseType']))\r\n| extend LinuxId=id, VMName=name, VMLocation=location, VMRG=resourceGroup, OSType=tostring(properties.storageProfile.imageReference.publisher), OsVersion = tostring(properties.storageProfile.imageReference.sku), VMSize=tostring (properties.hardwareProfile.vmSize), LicenseType = tostring(properties.['licenseType']), VMSSize=tostring(sku.name)\r\n| order by type asc \r\n| project LinuxId,VMName,VMRG,VMSize, VMSSize, VMLocation,OSType, OsVersion,LicenseType\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), LinuxId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct LinuxId\r\n )\r\n on LinuxId", + "size": 0, + "title": "AHB Disabled", + "noDataMessage": "None of your Linux VMs have AHB enabled.", + "noDataMessageStyle": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "LinuxAHBDisabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'microsoft.compute/virtualmachines' and (properties.storageProfile.imageReference.publisher == 'suse' or properties.storageProfile.imageReference.publisher=='RedHat')\r\n| where isnotnull ((properties.['licenseType']))\r\n| extend LinuxId=id, VMName=name, VMLocation=location, VMRG=resourceGroup, OSType=tostring(properties.storageProfile.imageReference.publisher), OsVersion = tostring(properties.storageProfile.imageReference.sku), VMSize=tostring (properties.hardwareProfile.vmSize), LicenseType = tostring(properties.['licenseType']), VMSSize=tostring(sku.name)\r\n| order by type asc \r\n| project LinuxId,VMName,VMRG,VMSize, VMSSize, VMLocation,OSType, OsVersion,LicenseType\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), LinuxId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct LinuxId\r\n )\r\n on LinuxId", + "size": 0, + "title": "AHB Enabled", + "noDataMessage": "All of your Linux VMs have AHB enabled.", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibility": { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "true" + }, + "name": "LinuxAHBRGEnabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'microsoft.compute/virtualmachines' and (properties.storageProfile.imageReference.publisher == 'suse' or properties.storageProfile.imageReference.publisher=='RedHat')\r\n| extend LicenseType = tostring(properties.['licenseType'])\r\n| extend LinuxId=id\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), LinuxId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct LinuxId\r\n )\r\n on LinuxId\r\n| extend CheckAHBLinux = case(\r\n type == 'microsoft.compute/virtualmachines' or type =~ 'microsoft.compute/virtualMachineScaleSets',\r\n iff(isnull((properties.['licenseType'])),\r\n \"AHB Not Enabled\", \"AHB Enabled\"),\r\n \"Not Linux\"\r\n )\r\n| summarize count() by CheckAHBLinux", + "size": 0, + "title": "Summary of Linux VMs with or without AHB", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "visualization": "piechart" + }, + "customWidth": "50", + "name": "Summary of Linux VMs with or without AHB" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"d8deb22b-a596-43ee-acc4-180849d26130\",\"mergeType\":\"inner\",\"leftTable\":\"LinuxAHBRGEnabled\",\"rightTable\":\"API-Get_VMLinux_SKU\",\"leftColumn\":\"VMSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"ConsumedCores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"8\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"[\\\"vCPUs\\\"]\"}}]},{\"originalName\":\"[WindowsAHBEnabled].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[WindowsAHBEnabled].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"},{\"originalName\":\"[LinuxAHBRGEnabled].LinuxId\",\"mergedName\":\"LinuxId\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMSSize\",\"mergedName\":\"VMSSize\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[LinuxAHBRGEnabled].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[LinuxAHBRGEnabled].OsVersion\",\"mergedName\":\"OsVersion\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[LinuxAHBRGEnabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[LinuxAHBRGEnabled].LinuxId1\",\"mergedName\":\"LinuxId1\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VMLinux_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VMLinux_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VMLinux_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VMLinux_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VMLinux_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VMLinux_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"}]}", + "size": 0, + "title": "Consumed Cores per VM", + "noDataMessage": "None of your Linux VM have AHB enabled", + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "ConsumedCores", + "formatter": 0, + "formatOptions": { + "aggregation": "Sum" + } + } + ] + }, + "tileSettings": { + "titleContent": {}, + "leftContent": { + "columnMatch": "ConsumedCores", + "formatter": 12, + "formatOptions": { + "palette": "blue" + } + }, + "showBorder": false + }, + "graphSettings": { + "type": 0 + }, + "chartSettings": { + "yAxis": [ + "ConsumedCores" + ], + "group": "VMName", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Linux Consumed Cores per VM" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "ae5e8765-47ef-46a6-803b-6b7124c098d2", + "version": "KqlParameterItem/1.0", + "name": "LinuxAHBEnabled", + "label": "See Linux VMs with AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "timeContext": { + "durationMs": 86400000 + } + }, + { + "id": "4c3ff9fa-d9c8-4d35-94d4-48ba3a1547fd", + "version": "KqlParameterItem/1.0", + "name": "LinuxAHBDisabled", + "label": "See Linux VMs without AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [] + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "timeContext": { + "durationMs": 86400000 + } + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "Linux VMs without AHB" + }, + { + "type": 1, + "content": { + "json": "List of Linux VMs with Hybrid Benefit groupped by Subscription." + }, + "conditionalVisibility": { + "parameterName": "LinuxAHBEnabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "Linux VMs with Hybrid Benefit" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\",\"mergeType\":\"inner\",\"leftTable\":\"LinuxAHBRGEnabled\",\"rightTable\":\"API-Get_VMLinux_SKU\",\"leftColumn\":\"VMSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[LinuxAHBRGEnabled].LinuxId\",\"mergedName\":\"VM ID\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBRGEnabled].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBRGEnabled].OsVersion\",\"mergedName\":\"OsVersion\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBRGEnabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBRGEnabled].LinuxId1\",\"mergedName\":\"LinuxId1\",\"fromId\":\"unknown\"},{\"originalName\":\"[LinuxAHBEnabled].VMName\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\"},{\"originalName\":\"[API-Get_VM_SKU].Name\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\"},{\"originalName\":\"[LinuxAHBEnabled].VMSSize\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMName\"},{\"originalName\":\"[LinuxAHBRGEnabled].VMSSize\"}]}", + "size": 0, + "title": "Linux VMs with AHB", + "noDataMessage": "None of your Linux VMs have AHB enabled", + "noDataMessageStyle": 4, + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Sev4", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + } + } + ] + }, + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "NewLicense", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "vCPUs", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "chartSettings": { + "xAxis": "VM Name", + "yAxis": [ + "Consumed Cores per VM" + ], + "group": null, + "createOtherGroup": 0, + "seriesLabelSettings": [ + { + "seriesName": "Consumed Cores per VM", + "color": "grayBlue" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "LinuxAHBEnabled", + "comparison": "isEqualTo", + "value": "yes" + }, + "name": "Linux-VM+SKU+vCores-AHB" + }, + { + "type": 1, + "content": { + "json": "List of Linux VMs without Hybrid Benefit groupped by Subscription." + }, + "conditionalVisibility": { + "parameterName": "LinuxAHBDisabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "LinuxAHBDisabled" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\",\"mergeType\":\"inner\",\"leftTable\":\"LinuxAHBDisabled\",\"rightTable\":\"API-Get_VMLinux_SKU\",\"leftColumn\":\"VMSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[LinuxAHBDisabled].LinuxId\",\"mergedName\":\"LinuxId\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBDisabled].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBDisabled].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBDisabled].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBDisabled].VMSSize\",\"mergedName\":\"VMSSize\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBDisabled].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBDisabled].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBDisabled].OsVersion\",\"mergedName\":\"OsVersion\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBDisabled].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[API-Get_VMLinux_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"8a27a7d8-5ea8-4408-ac20-2fc4e65ca095\"},{\"originalName\":\"[LinuxAHBDisabled].LinuxId1\",\"mergedName\":\"LinuxId1\",\"fromId\":\"unknown\"},{\"originalName\":\"[LinuxAHBEnabled].VMName\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\"},{\"originalName\":\"[API-Get_VM_SKU].Name\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\"},{\"originalName\":\"[LinuxAHBEnabled].VMSSize\"}]}", + "size": 0, + "title": "Linux VMs without AHB", + "noDataMessage": "None of your Linux VMs have AHB enabled", + "noDataMessageStyle": 4, + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Sev4", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + } + } + ] + }, + "tileSettings": { + "showBorder": false, + "titleContent": { + "columnMatch": "NewLicense", + "formatter": 1 + }, + "leftContent": { + "columnMatch": "vCPUs", + "formatter": 12, + "formatOptions": { + "palette": "auto" + }, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + }, + "chartSettings": { + "xAxis": "VM Name", + "yAxis": [ + "Consumed Cores per VM" + ], + "group": null, + "createOtherGroup": 0, + "seriesLabelSettings": [ + { + "seriesName": "Consumed Cores per VM", + "color": "grayBlue" + } + ] + } + }, + "conditionalVisibility": { + "parameterName": "LinuxAHBDisabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "Linux-VM+SKU+vCores-AHBDisabled" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "LinuxVM" + }, + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "VM" + } + ], + "name": "Linux" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "VMSS", + "items": [ + { + "type": 1, + "content": { + "json": "## Windows Azure Hybrid Benefit (AHB) Overview - VM Scale Set" + }, + "name": "AHB Overview - VM Scale Set" + }, + { + "type": 1, + "content": { + "json": "Each two-processor license or each set of 16-core licenses, either Datacenter or Standard editions, are entitled to two instances of up to 8 cores, or one instance of up to 16 cores.\r\n\r\nThe virtual machines (VMs) with less than 8 cores are categorized as **Low Priority**, while those with 8 or more cores are classified as **High Priority**. In situations where there are insufficient Azure Hybrid benefit licenses to cover all the VMs in the environment, it is recommended to prioritize the High Priority VMs.", + "style": "info" + }, + "name": "Each two-processor license or each set of 16-core licenses" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | extend SubscriptionName=name \r\n| join (\r\nresources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'microsoft.compute/virtualMachineScaleSets'\r\n| where tostring(properties.virtualMachineProfile.storageProfile.osDisk.osType) == 'Windows' and tostring(properties.virtualMachineProfile.licenseType) == \"Windows_Server\"\r\n| extend WindowsId=id, VMName=name, VMLocation=location, VMRG=resourceGroup, OSType=tostring(properties.virtualMachineProfile.storageProfile.osDisk.osType), OSVersion = tostring(properties.virtualMachineProfile.storageProfile.imageReference.sku), VMSize=tostring (properties.hardwareProfile.vmSize), LicenseType = tostring(properties.virtualMachineProfile.licenseType), VMSSize=tostring(sku.name)\r\n ) on subscriptionId \r\n| order by type asc \r\n| project WindowsId,VMName,VMRG,VMSize, VMSSize, VMLocation,OSType, OSVersion,LicenseType, subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), WindowsId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct WindowsId\r\n )\r\n on WindowsId", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "LoadVMSSTab", + "comparison": "isEqualTo", + "value": "Yes" + }, + { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "True" + } + ], + "name": "VMSSAHBEnabled-RG" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "ResourceContainers | where type =~ 'Microsoft.Resources/subscriptions' | extend SubscriptionName=name \r\n| join (\r\nresources \r\n| where resourceGroup in ({ResourceGroup})\r\n| where type =~ 'microsoft.compute/virtualMachineScaleSets'\r\n| where tostring(properties.storageProfile.osDisk.osType) == 'Windows' or tostring(properties.virtualMachineProfile.storageProfile.osDisk.osType) == 'Windows'\r\n| where tostring(properties.['licenseType']) !has 'Windows' and tostring(properties.virtualMachineProfile.['licenseType']) !has 'Windows'\r\n| extend WindowsId=id, VMName=name, VMLocation=location, VMRG=resourceGroup, OSType=tostring(properties.virtualMachineProfile.storageProfile.osDisk.osType), OsVersion = tostring(properties.virtualMachineProfile.storageProfile.imageReference.sku), VMSize=tostring (properties.hardwareProfile.vmSize), LicenseType = tostring(properties.virtualMachineProfile.licenseType), VMSSize=tostring(sku.name)\r\n ) on subscriptionId \r\n| order by type asc \r\n| project WindowsId,VMName,VMRG,VMSize, VMSSize, VMLocation,OSType, OsVersion,LicenseType, subscriptionId\r\n| join kind = innerunique(\r\n resources\r\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\r\n | extend replaced_tags = parse_json(replaced_tags)\r\n | mv-expand replaced_tags\r\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\r\n | extend tagValue = tostring(replaced_tags['{TagName}']), WindowsId=id\r\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\r\n | distinct WindowsId\r\n )\r\n on WindowsId\r\n", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "LoadVMSSTab", + "comparison": "isEqualTo", + "value": "Yes" + }, + { + "parameterName": "AlwaysHidden", + "comparison": "isEqualTo", + "value": "True" + } + ], + "name": "VMSSAHBDisabled-RG" + }, + { + "type": 1, + "content": { + "json": "### Consumed Licenses\r\nTotal number of Windows licenses cores consumed by all Windows virtual machines.\r\n", + "style": "info" + }, + "customWidth": "50", + "name": "Windows virtual machine" + }, + { + "type": 1, + "content": { + "json": "### Number of required Cores to enable Windows Azure Hybrid Benefit\r\nNumber of cores required to enable AHB across the entire environment.", + "style": "info" + }, + "customWidth": "50", + "name": "Number of required Cores to AHB" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "loadType": "explicit", + "loadButtonText": "Load VMSS Info", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"50d79765-aad4-437e-a90b-8cc7865e7081\",\"mergeType\":\"inner\",\"leftTable\":\"VMSSAHBEnabled-RG\",\"rightTable\":\"API-Get_VM_SKU\",\"leftColumn\":\"VMSSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\">=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores per VM\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"8\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\" ([\\\"vCPUs\\\"] + 7) & ~7\"}}]},{\"originalName\":\"[query - 0].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].WindowsId\",\"mergedName\":\"WindowsId\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMSSize\",\"mergedName\":\"VMSSize\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].OSVersion\",\"mergedName\":\"OSVersion\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[API-Get_VM_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"unknown\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"unknown\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"unknown\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"unknown\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"unknown\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"},{\"originalName\":\"[WindowsAHBEnabled].WindowsId\"},{\"originalName\":\"[WindowsAHBEnabled].VMRG\"},{\"originalName\":\"[WindowsAHBEnabled].VMLocation\"},{\"originalName\":\"[WindowsAHBEnabled].OSType\"},{\"originalName\":\"[WindowsAHBEnabled].OsVersion\"},{\"originalName\":\"[WindowsAHBEnabled].LicenseType\"},{\"originalName\":\"[query - Get VM vCPU].Name\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\"},{\"originalName\":\"[WindowsAHBEnabled].VMSSize\"}]}", + "size": 0, + "title": "Cores not enabled per AHB Priority", + "noDataMessage": "All of your VMs have AHB enabled", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Sev4", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + } + } + ] + }, + "chartSettings": { + "yAxis": [ + "Consumed Cores per VM" + ], + "group": "Prioritize AHB?", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Cores NOT enabled per AHB Priority" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"50d79765-aad4-437e-a90b-8cc7865e7081\",\"mergeType\":\"inner\",\"leftTable\":\"VMSSAHBEnabled-RG\",\"rightTable\":\"API-Get_VM_SKU\",\"leftColumn\":\"VMSSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\">=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"High Priority\\\"\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"\\\"Low Priority\\\"\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores per VM\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"8\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\" ([\\\"vCPUs\\\"] + 7) & ~7\"}}]},{\"originalName\":\"[WindowsAHBEnabled].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].WindowsId\",\"mergedName\":\"WindowsId\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMSSize\",\"mergedName\":\"VMSSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].OSVersion\",\"mergedName\":\"OSVersion\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"},{\"originalName\":\"[WindowsAHBEnabled].WindowsId\"},{\"originalName\":\"[WindowsAHBEnabled].VMRG\"},{\"originalName\":\"[WindowsAHBEnabled].VMLocation\"},{\"originalName\":\"[WindowsAHBEnabled].OSType\"},{\"originalName\":\"[WindowsAHBEnabled].OsVersion\"},{\"originalName\":\"[WindowsAHBEnabled].LicenseType\"},{\"originalName\":\"[query - Get VM vCPU].Name\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\"},{\"originalName\":\"[WindowsAHBEnabled].VMSSize\"}]}", + "size": 0, + "title": "Consumed Cores per AHB Priority", + "noDataMessage": "None of your VMs have AHB enabled", + "noDataMessageStyle": 4, + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Sev4", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + } + } + ] + } + }, + "customWidth": "33", + "name": "Consumed Cores per AHB Priority" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"d8deb22b-a596-43ee-acc4-180849d26130\",\"mergeType\":\"inner\",\"leftTable\":\"VMSSAHBEnabled-RG\",\"rightTable\":\"API-Get_VM_SKU\",\"leftColumn\":\"VMSSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[Added column]\",\"mergedName\":\"ConsumedCores\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"8\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"([\\\"vCPUs\\\"] + 7) & ~7\"}}]},{\"originalName\":\"[WindowsAHBEnabled].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[VMSSAHBEnabled-RG].WindowsId\",\"mergedName\":\"WindowsId\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMSSize\",\"mergedName\":\"VMSSize\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].OSVersion\",\"mergedName\":\"OSVersion\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VM_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"d8deb22b-a596-43ee-acc4-180849d26130\"},{\"originalName\":\"[VMSSAHBEnabled-RG].WindowsId1\",\"mergedName\":\"WindowsId1\",\"fromId\":\"unknown\"}]}", + "size": 0, + "title": "Consumed Cores per VMSS", + "showRefreshButton": true, + "queryType": 7, + "visualization": "piechart", + "gridSettings": { + "formatters": [ + { + "columnMatch": "ConsumedCores", + "formatter": 0, + "formatOptions": { + "aggregation": "Sum" + } + } + ] + }, + "tileSettings": { + "titleContent": {}, + "leftContent": { + "columnMatch": "ConsumedCores", + "formatter": 12, + "formatOptions": { + "palette": "blue" + } + }, + "showBorder": false + }, + "graphSettings": { + "type": 0 + }, + "chartSettings": { + "yAxis": [ + "ConsumedCores" + ], + "group": "VMName", + "createOtherGroup": null + } + }, + "customWidth": "33", + "name": "Consumed Cores per VMSS" + } + ] + }, + "name": "VMSS RG Overview" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "ae5e8765-47ef-46a6-803b-6b7124c098d2", + "version": "KqlParameterItem/1.0", + "name": "VMSSAHBEnabled", + "label": "See VMSS with AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n", + "timeContext": { + "durationMs": 86400000 + } + }, + { + "id": "f1ac5e53-253c-4afb-8bc5-b1ba2efea3eb", + "version": "KqlParameterItem/1.0", + "name": "VMSSAHBDisabled", + "label": "See VMSS without AHB", + "type": 2, + "isRequired": true, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n {\"value\":\"Yes\"},\r\n {\"value\":\"No\", \"selected\":true}\r\n]\r\n\r\n" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "VMSS Without AHB" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"50d79765-aad4-437e-a90b-8cc7865e7081\",\"mergeType\":\"inner\",\"leftTable\":\"VMSSAHBEnabled-RG\",\"rightTable\":\"API-Get_VM_SKU\",\"leftColumn\":\"VMSSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[WindowsAHBEnabled].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\">=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"static\",\"resultVal\":\"High Priority\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"static\",\"resultVal\":\"Low Priority\"}}]},{\"originalName\":\"[Added column]\",\"mergedName\":\"Consumed Cores per VM\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\"<=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"expression\",\"resultVal\":\"8\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"expression\",\"resultVal\":\"([\\\"vCPUs\\\"] + 7) & ~7\"}}]},{\"originalName\":\"[VMSSAHBEnabled-RG].WindowsId\",\"mergedName\":\"WindowsId\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMSSize\",\"mergedName\":\"VMSSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].OSVersion\",\"mergedName\":\"OSVersion\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBEnabled-RG].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - 0].VMName\"},{\"originalName\":\"[query - 0].VMSSize\"},{\"originalName\":\"[query - Get VM vCPU].Name\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\"},{\"originalName\":\"[WindowsAHBEnabled].VMSSize\"},{\"originalName\":\"[WindowsAHBEnabled].VMName\"},{\"originalName\":\"[VMSSAHBEnabled].VMSize\"},{\"originalName\":\"[VMSSAHBEnabled].VMName\"},{\"originalName\":\"[VMSSAHBEnabled-Tag].VMName\"},{\"originalName\":\"[VMSSAHBEnabled-Tag].VMSize\"}]}", + "size": 0, + "title": "VMSS with AHB", + "noDataMessage": "None of your VMSS have AHB enabled", + "noDataMessageStyle": 4, + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "2", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Subscription Name", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true + } + } + }, + "conditionalVisibility": { + "parameterName": "VMSSAHBEnabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "VMSS+SKU+vCores-AHB" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"Merge/1.0\",\"merges\":[{\"id\":\"50d79765-aad4-437e-a90b-8cc7865e7081\",\"mergeType\":\"inner\",\"leftTable\":\"VMSSAHBDisabled-RG\",\"rightTable\":\"API-Get_VM_SKU\",\"leftColumn\":\"VMSSize\",\"rightColumn\":\"Name\"}],\"projectRename\":[{\"originalName\":\"[query - 0].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[query - 0].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"unknown\"},{\"originalName\":\"[Added column]\",\"mergedName\":\"Prioritize AHB?\",\"fromId\":null,\"isNewItem\":true,\"newItemData\":[{\"criteriaContext\":{\"leftOperand\":\"vCPUs\",\"operator\":\">=\",\"rightValType\":\"static\",\"rightVal\":\"8\",\"resultValType\":\"static\",\"resultVal\":\"High Priority\"}},{\"criteriaContext\":{\"operator\":\"Default\",\"rightValType\":\"column\",\"resultValType\":\"static\",\"resultVal\":\"Low Priority\"}}]},{\"originalName\":\"[VMSSAHBDisabled-RG].WindowsId\",\"mergedName\":\"WindowsId\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBDisabled-RG].VMName\",\"mergedName\":\"VMName\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBDisabled-RG].VMRG\",\"mergedName\":\"VMRG\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBDisabled-RG].VMSize\",\"mergedName\":\"VMSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBDisabled-RG].VMSSize\",\"mergedName\":\"VMSSize\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBDisabled-RG].VMLocation\",\"mergedName\":\"VMLocation\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBDisabled-RG].OSType\",\"mergedName\":\"OSType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBDisabled-RG].OsVersion\",\"mergedName\":\"OsVersion\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBDisabled-RG].LicenseType\",\"mergedName\":\"LicenseType\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[VMSSAHBDisabled-RG].subscriptionId\",\"mergedName\":\"subscriptionId\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].Name\",\"mergedName\":\"Name\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUs\",\"mergedName\":\"vCPUs\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].MemoryGB\",\"mergedName\":\"MemoryGB\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].MaxNetworkInterfaces\",\"mergedName\":\"MaxNetworkInterfaces\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].HyperVGenerations\",\"mergedName\":\"HyperVGenerations\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[API-Get_VM_SKU].vCPUsPerCore\",\"mergedName\":\"vCPUsPerCore\",\"fromId\":\"50d79765-aad4-437e-a90b-8cc7865e7081\"},{\"originalName\":\"[query - 0].VMName\"},{\"originalName\":\"[query - 0].VMSSize\"},{\"originalName\":\"[query - Get VM vCPU].Name\"},{\"originalName\":\"[query - Get VM vCPU].MemoryGB\"},{\"originalName\":\"[query - Get VM vCPU].MaxNetworkInterfaces\"},{\"originalName\":\"[query - Get VM vCPU].HyperVGenerations\"},{\"originalName\":\"[query - Get VM vCPU].vCPUsPerCore\"},{\"originalName\":\"[VMSS-AHB-Disabled].VMName\"},{\"originalName\":\"[VMSS-AHB-Disabled-Tag].VMSize\"},{\"originalName\":\"[VMSS-AHB-Disabled-Tag].VMName\"}]}", + "size": 0, + "title": "VMSS without AHB", + "noDataMessage": "All of your VMSS have AHB enabled", + "noDataMessageStyle": 3, + "showExportToExcel": true, + "queryType": 7, + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Group", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "Prioritize AHB?", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High Priority", + "representation": "Sev0", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Sev4", + "text": "{0}{1}" + } + ] + }, + "numberFormat": { + "unit": 17, + "options": { + "style": "decimal" + } + } + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "subscriptionId" + ], + "expandTopLevel": true + } + } + }, + "conditionalVisibility": { + "parameterName": "VMSSAHBDisabled", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "VMSS+SKU+vCores" + } + ] + }, + "name": "VMSS RG Details" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedSubTab", + "comparison": "isEqualTo", + "value": "VMSS" + }, + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "VM" + } + ], + "name": "VMSS-RG" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "selectedRateOptimizationTab", + "comparison": "isEqualTo", + "value": "AHB" + }, + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RateOptimization" + } + ], + "name": "AHB Overview" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "RateOptimization" + }, + "name": "group - RateOptimization group" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "6b8c0a46-6867-498b-9a3e-799a2475a11a", + "cellValue": "selectedOverviewTab", + "linkTarget": "parameter", + "linkLabel": "Welcome", + "subTarget": "instructions", + "style": "link" + }, + { + "id": "da748ed1-f329-42d4-962d-9b2339baf7c4", + "cellValue": "selectedOverviewTab", + "linkTarget": "parameter", + "linkLabel": "Resources overview", + "subTarget": "resourcesMap", + "style": "link" + }, + { + "id": "a4b4de18-b90e-4212-86a2-ea5fabc4f40c", + "cellValue": "selectedOverviewTab", + "linkTarget": "parameter", + "linkLabel": "Security recommendations", + "subTarget": "securityRecommendations", + "style": "link" + }, + { + "id": "a18f24d2-3320-4c53-a86d-db32c920c8f7", + "cellValue": "selectedOverviewTab", + "linkTarget": "parameter", + "linkLabel": "Reliability recommendations", + "subTarget": "reliabilityRecommendations", + "style": "link" + } + ] + }, + "conditionalVisibility": { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "Welcome" + }, + "name": "tabs - overview tabs" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "6a9ccf8c-9f3e-4ee0-b45b-f511401f8656", + "version": "KqlParameterItem/1.0", + "name": "mapSubscriptions", + "label": "Subscriptions", + "type": 6, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "defaultValue": "value::all", + "value": [ + "value::all" + ] + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "Welcome" + }, + { + "parameterName": "selectedOverviewTab", + "comparison": "isNotEqualTo", + "value": "instructions" + } + ], + "name": "parameters - OverviewSubscriptions" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "advisorresources\r\n| where type == \"microsoft.advisor/recommendations\"\r\n| where tostring (properties.category) has \"Security\"\r\n| project AffectedResource=tostring(properties.resourceMetadata.resourceId),Impact=tostring(properties.impact),Recommendation=tostring(properties.shortDescription.problem),subscriptionId", + "size": 0, + "title": "Azure Advisor security recommendations", + "noDataMessage": "You are following all of our security recommendations for the selected subscriptions.", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{mapSubscriptions}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Impact", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High", + "representation": "red", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Medium", + "representation": "orange", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low", + "representation": "blue", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "gray", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Impact" + ] + } + } + }, + "name": "query - advisorSecurityRecommendations" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "Welcome" + }, + { + "parameterName": "selectedOverviewTab", + "comparison": "isEqualTo", + "value": "securityRecommendations" + } + ], + "name": "group - securityRecommendations" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "# Welcome to the cost optimization workbook" + }, + "name": "Welcome" + }, + { + "type": 1, + "content": { + "json": "### Reference: [Microsoft Azure Well-Architected Framework - cost optimization pillar](https://learn.microsoft.com/azure/architecture/framework/cost/overview)", + "style": "upsell" + }, + "name": "Reference" + }, + { + "type": 1, + "content": { + "json": "This workbook aims to offer a comprehensive overview of your Azure environment's resource usage, aligning with the WAF Cost Optimization pillar. It identifies recommendations to optimize efficiency, providing guidance on potential opportunities. Please note that the workbook serves as guidance to highlight optimization opportunities, and the extent of cost reduction depends on their implementation.\r\n\r\n## Overview of the cost optimization pillar\r\n\r\n* The cost optimization pillar provides principles for balancing business goals with technology needs to create a cost-effective workload while avoiding capital-intensive solutions.The workbook emphasizes the importance of reducing waste and improving operational efficiencies.\r\n\r\n* To assess your workload based on the principles outlined in the [Microsoft Azure Well-Architected Framework](https://learn.microsoft.com/azure/architecture/framework/), reference the [Microsoft Azure Well-Architected Review](https://learn.microsoft.com/assessments/?id=azure-architecture-review&mode=pre-assessment&session=20dc50e4-5b71-4f38-bc49-51cc1d9f205c) tool.\r\n\r\n\r\n\r\n\r\n" + }, + "name": "objective" + }, + { + "type": 1, + "content": { + "json": "Indicates an implemented recommendation that can result in a environment that is following the Cost Optimization & Cost Governance principles.", + "style": "success" + }, + "customWidth": "50", + "name": "Greenlight", + "styleSettings": { + "margin": "10px", + "showBorder": true + } + }, + { + "type": 1, + "content": { + "json": "## Prerequisites\r\n\r\nThis workbook requires the following least-privileged (minimum) roles on your Subscriptions:\r\n\r\n * **Reader** : allows you to import the workbook without saving it and view all of the workbook tabs.\r\n * **Workbook Contributor** : allows you to import and save the workbook\r\n\r\nThis workbook includes \"Quick Fix\" actions within certain queries. The permissions necessary to execute these actions may vary and are documented for each specific action.\r\n\r\n\r\n" + }, + "name": "Prerequisites" + }, + { + "type": 1, + "content": { + "json": "## Feedback\r\n\r\n [ Submit feedback here ](https://aka.ms/advisor_cost_wb_feedback) on your experience with workbooks at any time.\r\n\r\n\r\n\r\n [Submit any issues ](https://aka.ms/costworkbookfeedback) with the workbook template to GitHub." + }, + "name": "text - 5" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "Welcome" + }, + { + "parameterName": "selectedOverviewTab", + "comparison": "isEqualTo", + "value": "instructions" + } + ], + "name": "Welcome" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "summarize count() by location", + "size": 2, + "title": "Resource distribution per region", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{mapSubscriptions}" + ], + "visualization": "map", + "mapSettings": { + "locInfo": "AzureLoc", + "locInfoColumn": "location", + "sizeSettings": "count_", + "sizeAggregation": "Sum", + "labelSettings": "location", + "legendMetric": "count_", + "legendAggregation": "Sum", + "itemColorSettings": { + "nodeColorField": "count_", + "colorAggregation": "Sum", + "type": "heatmap", + "heatmapPalette": "greenRed" + } + } + }, + "name": "query - resourcesMap" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "selectedOverviewTab", + "comparison": "isEqualTo", + "value": "resourcesMap" + }, + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "Welcome" + } + ], + "name": "group - resourceOverview" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "advisorresources\r\n| where type == \"microsoft.advisor/recommendations\"\r\n| where tostring (properties.category) has \"HighAvailability\"\r\n| project AffectedResource=tostring(properties.resourceMetadata.resourceId),Impact=tostring(properties.impact),Recommendation=tostring(properties.shortDescription.problem),subscriptionId", + "size": 0, + "title": "Azure Advisor reliability recommendations", + "noDataMessage": "You are following all of our reliability recommendations for the selected subscriptions.", + "noDataMessageStyle": 3, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{mapSubscriptions}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Impact", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "High", + "representation": "red", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Medium", + "representation": "orange", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "Low", + "representation": "blue", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "gray", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "subscriptionId", + "formatter": 15, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + }, + { + "columnMatch": "resourceGroup", + "formatter": 14, + "formatOptions": { + "linkTarget": null, + "showIcon": true + } + } + ], + "filter": true, + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "Impact" + ] + } + } + }, + "name": "query - advisorReliabilityRecommendations" + } + ] + }, + "conditionalVisibilities": [ + { + "parameterName": "SelectedTab", + "comparison": "isEqualTo", + "value": "Welcome" + }, + { + "parameterName": "selectedOverviewTab", + "comparison": "isEqualTo", + "value": "reliabilityRecommendations" + } + ], + "name": "group - reliabilityRecommendations" + } + ], + "fallbackResourceIds": [ + "Azure Monitor" + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +}