From db5443fd8008942bc59d7d6a9dff164906899754 Mon Sep 17 00:00:00 2001 From: Seresha Date: Wed, 20 Sep 2023 11:34:19 +0530 Subject: [PATCH 1/7] Committing for service bus support under integration --- build/integration.tf | 16 +- build/template_kql/common/extend_resource.kql | 18 +- ...tegration_servicebus_resources_details.kql | 3 + ...n_servicebus_resources_details_summary.kql | 6 + build/templates/integration.tpl.json | 598 +++++++++++++++++- 5 files changed, 635 insertions(+), 6 deletions(-) create mode 100644 build/template_kql/integration/integration_servicebus_resources_details.kql create mode 100644 build/template_kql/integration/integration_servicebus_resources_details_summary.kql diff --git a/build/integration.tf b/build/integration.tf index fb579fb..e235753 100644 --- a/build/integration.tf +++ b/build/integration.tf @@ -9,8 +9,22 @@ locals { } ) workbook_integration_json = templatefile("${path.module}/templates/integration.tpl.json", { - "kql_integration_apim_resources_details" = jsonencode(local.kql_integration_apim_resources_details) + "kql_integration_apim_resources_details" = jsonencode(local.kql_integration_apim_resources_details) + "kql_integration_servicebus_resources_details" = jsonencode(local.kql_integration_servicebus_resources_details) + "kql_integration_servicebus_resources_details_summary" = jsonencode(local.kql_integration_servicebus_resources_details_summary) }) + kql_integration_servicebus_resources_details = templatefile( + "${path.module}/template_kql/integration/integration_servicebus_resources_details.kql", + { + "extend_resource" = local.kql_extend_resource + } + ) + kql_integration_servicebus_resources_details_summary = templatefile( + "${path.module}/template_kql/integration/integration_servicebus_resources_details_summary.kql", + { + "extend_resource" = local.kql_extend_resource + } + ) } resource "random_uuid" "workbook_name_integration" { keepers = { diff --git a/build/template_kql/common/extend_resource.kql b/build/template_kql/common/extend_resource.kql index 98f7a82..2ae8708 100644 --- a/build/template_kql/common/extend_resource.kql +++ b/build/template_kql/common/extend_resource.kql @@ -37,6 +37,7 @@ resources (type == 'microsoft.dbformysql/flexibleservers') or (type == 'microsoft.cache/redis') or (type == "microsoft.apimanagement/service") or + (type== 'microsoft.servicebus/namespaces') or (type == "microsoft.storage/storageaccounts" or type == "microsoft.classicstorage/storageaccounts") or (type == "microsoft.network/azurefirewalls") or (type == "microsoft.network/frontdoors") or @@ -95,6 +96,7 @@ resources type == 'microsoft.dbformysql/flexibleservers', tostring(properties.state), type == 'microsoft.cache/redis', tostring(properties.provisioningState), type == "microsoft.apimanagement/service", tostring(properties.provisioningState), + type == 'microsoft.servicebus/namespaces',tostring(properties.provisioningState), type contains "storageaccounts", tostring(properties.provisioningState), type == "microsoft.network/azurefirewalls", tostring(properties.provisioningState), type == "microsoft.network/frontdoors", tostring(properties.resourceState), @@ -119,6 +121,7 @@ resources type == 'microsoft.dbformysql/flexibleservers', tostring(sku.tier), type == 'microsoft.cache/redis', tostring(properties.sku.name), type == "microsoft.apimanagement/service", tostring(sku.name), + type == 'microsoft.servicebus/namespaces', tostring(sku.name), type contains 'storageaccounts', tostring(replace('-', '_', tostring(iff(type =~ "microsoft.storage/storageaccounts", sku.name, properties.accountType)))), type == "microsoft.network/azurefirewalls", tostring(properties.sku.name), type == "microsoft.network/frontdoors", "classic_frontdoor", @@ -151,6 +154,7 @@ resources (type == 'microsoft.dbformysql/flexibleservers'), iif(properties.haEnabled == "Enabled", 'Configured', 'Not Configured'), (type == 'microsoft.cache/redis'), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'), (type == "microsoft.apimanagement/service"), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'), + (type == 'microsoft.servicebus/namespaces'), iff(properties.zoneRedundant == 'true', 'Configured', 'Not Configured'), (type contains 'storageaccounts'), case(split(skuName, '_', 1)[0] contains "zrs", "Configured", "Not Configured"), (type == "microsoft.network/azurefirewalls"), iif(isnotnull(zones), "Configured", "Not Configured"), (type == "microsoft.network/frontdoors"), "Not Applicable", @@ -189,6 +193,7 @@ resources type == 'microsoft.dbformysql/flexibleservers', "Not Applicable", type == 'microsoft.cache/redis', "Not Applicable", type == "microsoft.apimanagement/service", "Not Applicable", + type == "microsoft.servicebus/namespaces", iif(zones in ('1', '2', '3'), "configured","not configured"), type contains "storageaccounts", "Not Applicable", type == "microsoft.network/azurefirewalls", "Not Applicable", type == "microsoft.network/frontdoors", "Not Applicable", @@ -213,6 +218,7 @@ resources type == 'microsoft.dbformysql/flexibleservers', tostring(sku.capacity), type == 'microsoft.cache/redis', strcat(properties.sku.family, properties.sku.capacity), type == "microsoft.apimanagement/service", tostring(sku.capacity), + type == "microsoft.servicebus/namespaces",iif(isnotnull(sku.capacity), tostring(sku.capacity), "Not configured"), type contains "storageaccounts", "Not Applicable", type == "microsoft.network/azurefirewalls", "Not Applicable", type == "microsoft.network/frontdoors", "Not Applicable", @@ -237,6 +243,7 @@ resources type == 'microsoft.dbformysql/flexibleservers', 'Not Applicable', type == 'microsoft.cache/redis', 'Not Applicable', type == "microsoft.apimanagement/service", "Not Applicable", + type == "microsoft.servicebus/namespaces",properties.minimumTlsVersion,//use it for tls version, renaming the column type contains "storageaccounts", "Not Applicable", type == "microsoft.network/azurefirewalls", "Not Applicable", type == "microsoft.network/frontdoors", "Not Applicable", @@ -261,6 +268,7 @@ resources type == 'microsoft.dbformysql/flexibleservers', 'Not Applicable', type == 'microsoft.cache/redis', 'Not Applicable', type == "microsoft.apimanagement/service", tostring(properties.platformVersion), //Field Override + type == "microsoft.servicebus/namespaces", "Not Applicable", type contains "storageaccounts", tostring(split(skuName, '_', 0)[0]), type == "microsoft.network/azurefirewalls", "Not Applicable", type == "microsoft.network/frontdoors", "Not Applicable", @@ -286,6 +294,7 @@ resources type == 'microsoft.dbformysql/flexibleservers', "Not Applicable", type == 'microsoft.cache/redis', 'Not Applicable', type == "microsoft.apimanagement/service", tostring(properties.additionalLocations), + (type == "microsoft.servicebus/namespaces"), "Not Applicable", type contains "storageaccounts", case( location in~ ('qatarcentral'), 'Not Applicable', split(skuName, '_', 1)[0] startswith "ra", "Configured", @@ -310,6 +319,7 @@ resources type == 'microsoft.dbformysql/flexibleservers', case(properties.haEnabled == "Enabled", "Configured", "Not Applicable"), type == 'microsoft.cache/redis', 'Not Applicable', type == "microsoft.apimanagement/service", "Not Applicable", + (type == "microsoft.servicebus/namespaces"), "Not Applicable", type contains "storageaccounts", "Not Applicable", type == "microsoft.network/azurefirewalls", "Not Applicable", type == "microsoft.network/frontdoors", "Not Applicable", @@ -327,6 +337,7 @@ resources (type == 'microsoft.documentdb/databaseaccounts' and properties.enableMultipleWriteLocations == "true"), "Enabled", (type == 'microsoft.cache/redis'), 'Not Applicable', (type == "microsoft.apimanagement/service"), "Not Applicable", + (type == "microsoft.servicebus/namespaces"), "Not Applicable", (type contains "storageaccounts"), "Not Applicable", (type == "microsoft.network/azurefirewalls"), "Not Applicable", (type == "microsoft.network/frontdoors"), "Not Applicable", @@ -344,6 +355,7 @@ resources (type == 'microsoft.dbformysql/flexibleservers'), "Not Applicable", (type == 'microsoft.cache/redis'), 'Not Applicable', (type == "microsoft.apimanagement/service"), "Not Applicable", + (type == "microsoft.servicebus/namespaces"), "Not Applicable", (type contains "storageaccounts"), "Not Applicable", (type == "microsoft.network/azurefirewalls"), "Not Applicable", (type == "microsoft.network/frontdoors"), "Not Applicable", @@ -363,6 +375,7 @@ resources (type == 'microsoft.dbformysql/flexibleservers'), iif(properties.haEnabled == "Enabled", 'Not Applicable', tostring(properties.replicationRole)), (type == 'microsoft.cache/redis'), 'Not Applicable', (type == "microsoft.apimanagement/service"), "Not Applicable", + (type == "microsoft.servicebus/namespaces"), "Not Applicable", (type contains "storageaccounts"), tostring(split(skuName, '_', 1)[0]), (type == "microsoft.network/azurefirewalls"), "Not Applicable", (type == "microsoft.network/frontdoors"), "Not Applicable", @@ -418,7 +431,4 @@ resources (Type == "microsoft.recoveryservices/vaults"), "Not Applicable", "Unknown" ) -| extend AvailabilitySet = case( - AvailabilitySet == '-', 'None', - isnotempty(AvailabilitySet), AvailabilitySet, - "Unknown") \ No newline at end of file + \ No newline at end of file diff --git a/build/template_kql/integration/integration_servicebus_resources_details.kql b/build/template_kql/integration/integration_servicebus_resources_details.kql new file mode 100644 index 0000000..2bb9f4f --- /dev/null +++ b/build/template_kql/integration/integration_servicebus_resources_details.kql @@ -0,0 +1,3 @@ +${extend_resource} +| project Type, SkuName, Kind, SubscriptionId, Name, State, Location, ResourceGroup, AvailabilityZone, Zones=AvailabilitySet, Capacity, MinTLSVersion=FaultDomain, Environment +| where Type == 'microsoft.servicebus/namespaces' \ No newline at end of file diff --git a/build/template_kql/integration/integration_servicebus_resources_details_summary.kql b/build/template_kql/integration/integration_servicebus_resources_details_summary.kql new file mode 100644 index 0000000..db6682d --- /dev/null +++ b/build/template_kql/integration/integration_servicebus_resources_details_summary.kql @@ -0,0 +1,6 @@ +${extend_resource} +| project type,zones, sku=sku.name, sku.capacity, properties.provisioningState, properties.publicNetworkAccess, +properties.status,properties.minimumTlsVersion,properties.zoneRedundant,properties.disableLocalAuth,properties.serviceBusEndpoint,GeoRedundant=properties.privateEndpointConnections +| where type =='microsoft.servicebus/namespaces' +| summarize ResourceTotal=count(Name), NotPremium=dcountif(Name, SkuName!= "Premium"), NoMultipleZones=dcountif(Name, Zones != "null"), NotSucceeded=dcountif(Name, State != "Succeeded") +,NoAVZone=dcountif(Name, AvailabilityZone==false),NoMinimumTLSVersion=dcountif(Name,MinTLSVersion!=1.2), CapacityNotConfigured=dcountif(Name, Capacity=="Not configured") \ No newline at end of file diff --git a/build/templates/integration.tpl.json b/build/templates/integration.tpl.json index 1609208..bdf07c9 100644 --- a/build/templates/integration.tpl.json +++ b/build/templates/integration.tpl.json @@ -63,7 +63,8 @@ "typeSettings": { "additionalResourceOptions": [ "value::all" - ] + ], + "showDefault": false }, "defaultValue": "value::all", "queryType": 1, @@ -136,6 +137,584 @@ }, "name": "parameters - 13" }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "0f2833bb-ccf9-4292-a3d5-8f3070f906ef", + "cellValue": "selectedTab", + "linkTarget": "parameter", + "linkLabel": "API Management", + "subTarget": "APIM", + "style": "link" + }, + { + "id": "363da150-0a6e-4601-a225-b6d59a1be19e", + "cellValue": "selectedTab", + "linkTarget": "parameter", + "linkLabel": "Service Bus", + "subTarget": "ServiceBus", + "style": "link" + } + ] + }, + "name": "links - 0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "[SLA for Service Bus](https://azure.microsoft.com/support/legal/sla/)\r\n* For Service Bus Relays, we guarantee that at least 99.9% of the time, properly configured applications will be able to establish a connection to a deployed Relay.\r\n* For Service Bus Queues and Topics, we guarantee that at least 99.9% of the time , properly configured applications will be able to send or receive messages or perform other operations on a deployed Queue or Topic.", + "style": "upsell" + }, + "conditionalVisibility": { + "parameterName": "SLA", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "text - 2 - Copy - Copy" + }, + { + "type": 1, + "content": { + "json": "* Please note the non-Premium tier is for non-production use cases and evaluations. It does not offer an SLA.\r\n* Its highly recommended to use Premium tier for Production environment as it covers High Availability, mission-critical messaging with queues and topics with Geo-Disaster Recovery and zone redundancy.\r\n\r\n", + "style": "info" + }, + "conditionalVisibility": { + "parameterName": "Help", + "comparison": "isEqualTo", + "value": "Yes" + }, + "name": "text - 3 - Copy - Copy - Copy" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\n| where resourceGroup in ({ResourceGroup})\n| extend environment = case(\n tags.Environment <> \"\", tags.Environment,\n tags.environment <> \"\", tags.environment,\n tags.Env <> \"\", tags.Env,\n tags.env <> \"\", tags.env,\n tolower(name) contains \"prod\", \"Production\",\n tolower(name) contains \"dev\", \"Development\",\n tolower(name) contains \"qa\", \"QA\",\n tolower(name) contains \"uat\", \"UAT\",\n tolower(name) contains \"sit\", \"SIT\",\n tolower(name) contains \"test\", \"Test\",\n \"Undefined\")\n| where environment in ({Environment})\n| join kind = innerunique(\n resources\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\n | extend replaced_tags = parse_json(replaced_tags)\n | mv-expand replaced_tags\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\n | extend tagValue = tostring(replaced_tags['{TagName}'])\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\n | distinct id\n )\n on id\n| where \n (type == 'microsoft.compute/virtualmachines') or \n (type == 'microsoft.classiccompute/virtualmachines') or \n (type == \"microsoft.compute/virtualmachinescalesets\" and tags.aksEngineVersion !contains \"aks-gomod\") or\n (type == 'microsoft.web/sites') or \n (type == 'microsoft.web/serverfarms') or\n (type == \"microsoft.containerservice/managedclusters\") or \n (type == 'microsoft.sql/servers/databases') or \n (type == 'microsoft.documentdb/databaseaccounts') or \n (type == 'microsoft.dbformysql/servers') or \n (type == 'microsoft.dbformysql/flexibleservers') or \n (type == 'microsoft.cache/redis') or\n (type == \"microsoft.apimanagement/service\") or \n (type== 'microsoft.servicebus/namespaces') or\n (type == \"microsoft.storage/storageaccounts\" or type == \"microsoft.classicstorage/storageaccounts\") or \n (type == \"microsoft.network/azurefirewalls\") or \n (type == \"microsoft.network/frontdoors\") or\n (type == \"microsoft.cdn/profiles\") or\n (type == \"microsoft.network/applicationgateways\") or \n (type == \"microsoft.network/loadbalancers\") or \n (type == \"microsoft.network/publicipaddresses\" or type == \"microsoft.network/publicipprefixes\") or \n (type == \"microsoft.network/virtualnetworkgateways\") or \n (type == \"microsoft.recoveryservices/vaults\")\n| join kind=leftouter (\n resources \n | where type == \"microsoft.containerservice/managedclusters\"\n // Expand per node pool to get using zone for all node pool\n | mv-expand agentPoolProfiles = properties.agentPoolProfiles\n | extend AvZones = agentPoolProfiles.availabilityZones\n | extend AksNodeResourceGroup = tolower(tostring(properties.nodeResourceGroup))\n // Get number of using zone per node pool VMSS. If it doesn't use any zone, return 0\n | extend useAvZone = case(\n array_length( AvZones ) > 0, array_length( AvZones ), 0\n )\n | join kind=leftouter(\n resources\n | where type == 'microsoft.compute/virtualmachinescalesets'\n | extend resourceGroup = tolower(tostring(resourceGroup))\n | extend VmssCapacity = sku.capacity\n | extend vmssStorageAccountType = iff(\n properties.virtualMachineProfile.storageProfile.osDisk.diffDiskSettings.option == \"Local\", \"Ephemeral\", properties.virtualMachineProfile.storageProfile.osDisk.managedDisk.storageAccountType\n )\n ) on $left.AksNodeResourceGroup == $right.resourceGroup // Match AKS and VMSS with nodeResourceGroup\n | summarize AvZones=min(useAvZone), AksMinimumNodePoolCount=min(toint(VmssCapacity)), AksNodePoolStorageAccountType=make_set(vmssStorageAccountType), FaultDomainCount=min(toint(properties1.platformFaultDomainCount)) by id, name, type, tenantId, kind, location, resourceGroup, subscriptionId, tostring(sku), tostring(plan), tostring(properties), AksNodeResourceGroup\n | extend AksNodePoolStorageAccountType = iff(\n tolower(tostring(AksNodePoolStorageAccountType)) contains \"standard_lrs\", \"standard_lrs\", tolower(tostring(strcat_array(AksNodePoolStorageAccountType, \",\")))\n )\n // If there are some node pools within AKS cluster, it returns minimum number of zones. \n // If even one node pool is not using a zone, it will be \"Not Configured\".\n | extend AvZones = iff(tostring(AvZones) == \"0\", \"Not Configured\", tostring(AvZones)), AvSets = \"Scale Sets\"\n) on id\n// Start - Azure Load Balancer additional logic\n| mv-expand LbFeIpConfig = properties.frontendIPConfigurations\n| extend LbUseAvZone = iff(array_length(LbFeIpConfig.zones ) > 0, array_length(LbFeIpConfig.zones ), 0)\n| extend LbIpType = iff(isnotnull(LbFeIpConfig.properties.publicIPAddress), \"Public\", \"Private\")\n//| summarize LbAvZones = min(LbUseAvZone) by id, name, type, tenantId, kind, location, resourceGroup, subscriptionId, tostring(sku), plan, tostring(properties)\n//| extend properties = todynamic(properties), sku = todynamic(sku), \n| summarize LbAvZones = arg_min(LbUseAvZone, *) by id\n// End - Azure Load Balancer additional logic\n| extend state = case(\n type == 'microsoft.compute/virtualmachines', tostring(properties.extended.instanceView.powerState.displayStatus),\n type == 'microsoft.classiccompute/virtualmachines', tostring(properties.instanceView.powerState),\n type == 'microsoft.compute/virtualmachinescalesets', tostring(properties.provisioningState),\n type == 'microsoft.web/sites', tostring(properties.state),\n type == 'microsoft.web/serverfarms', tostring(properties.status),\n type == 'microsoft.containerservice/managedclusters', tostring(properties.provisioningState),\n type == 'microsoft.sql/servers/databases', tostring(properties.status),\n type == 'microsoft.documentdb/databaseaccounts', tostring(properties.provisioningState),\n type == 'microsoft.dbformysql/servers', tostring(properties.userVisibleState),\n type == 'microsoft.dbformysql/flexibleservers', tostring(properties.state),\n type == 'microsoft.cache/redis', tostring(properties.provisioningState),\n type == \"microsoft.apimanagement/service\", tostring(properties.provisioningState),\n type == 'microsoft.servicebus/namespaces',tostring(properties.provisioningState),\n type contains \"storageaccounts\", tostring(properties.provisioningState),\n type == \"microsoft.network/azurefirewalls\", tostring(properties.provisioningState),\n type == \"microsoft.network/frontdoors\", tostring(properties.resourceState),\n type == \"microsoft.cdn/profiles\", tostring(properties.resourceState),\n type == \"microsoft.network/applicationgateways\", tostring(properties.operationalState),\n type == \"microsoft.network/loadbalancers\", tostring(properties.provisioningState),\n type contains \"publicip\", tostring(properties.provisioningState),\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.provisioningState),\n type == \"microsoft.recoveryservices/vaults\", tostring(properties.provisioningState),\n \"Undefined\"\n )\n| extend skuName = case(\n type == 'microsoft.compute/virtualmachines', tostring(properties.hardwareProfile.vmSize),\n type == 'microsoft.classiccompute/virtualmachines', tostring(properties.hardwareProfile.size),\n type == 'microsoft.compute/virtualmachinescalesets', tostring(sku.name),\n type == 'microsoft.web/sites', tostring(properties.sku),\n type == 'microsoft.web/serverfarms', tostring(sku.tier),\n type == 'microsoft.containerservice/managedclusters', tostring(properties.agentPoolProfiles[0].vmSize),\n type == 'microsoft.sql/servers/databases', tostring(sku.tier),\n type == 'microsoft.documentdb/databaseaccounts', tostring(properties.databaseAccountOfferType),\n type == 'microsoft.dbformysql/servers', tostring(sku.tier),\n type == 'microsoft.dbformysql/flexibleservers', tostring(sku.tier),\n type == 'microsoft.cache/redis', tostring(properties.sku.name),\n type == \"microsoft.apimanagement/service\", tostring(sku.name),\n type == 'microsoft.servicebus/namespaces', tostring(sku.name),\n type contains 'storageaccounts', tostring(replace('-', '_', tostring(iff(type =~ \"microsoft.storage/storageaccounts\", sku.name, properties.accountType)))),\n type == \"microsoft.network/azurefirewalls\", tostring(properties.sku.name),\n type == \"microsoft.network/frontdoors\", \"classic_frontdoor\",\n type == \"microsoft.cdn/profiles\", tostring(sku.name),\n type == \"microsoft.network/applicationgateways\", tostring(properties.sku.name),\n type == \"microsoft.network/loadbalancers\", iff(sku.tier == 'Global', 'Global', tostring(sku.name)),\n type contains \"publicip\", iff(sku.tier == 'Global', 'Global', tostring(sku.name)),\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.sku.name),\n type == \"microsoft.recoveryservices/vaults\", tostring(iif(isnotnull(sku.tier), sku.tier, sku.name)),\n \"Undefined\"\n )\n| extend avZones = case(\n location !in~ ('brazilsouth', 'canadacentral', 'centralus', 'eastus', 'eastus2', 'southcentralus', 'usgovvirginia', 'westus2', 'westus3', 'francecentral', 'germanywestcentral', 'northeurope', 'norwayeast', 'uksouth', 'westeurope', 'swedencentral', 'switzerlandnorth', 'polandcentral', 'qatarcentral', 'uaenorth', 'southafricanorth', 'australiaeast', 'centralindia', 'japaneast', 'koreacentral', 'southeastasia', 'eastasia', 'chinanorth3'), 'Not Applicable',\n (type == 'microsoft.compute/virtualmachines'), coalesce(tostring(zones[0]), 'Not Configured'),\n (type == 'microsoft.classiccompute/virtualmachines'), 'Not Applicable',\n (type == 'microsoft.compute/virtualmachinescalesets'), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'),\n (type == 'microsoft.containerservice/managedclusters' and AvZones <> \"\"), AvZones,\n (type == 'microsoft.containerservice/managedclusters' and isempty(AvZones)), \"Not Configured\",\n (type == 'microsoft.web/sites'), \"ASP AZ config\",\n (type == 'microsoft.web/serverfarms'), iff(properties.zoneRedundant == 'true', 'Configured', 'Not Configured'),\n (type == 'microsoft.sql/servers/databases' and sku.tier <> 'DataWarehouse'), case( //SQL AZ SKU & region availability filter\n sku.name == 'Basic' or sku.name == 'Standard' or sku.name == 'System', 'Not Applicable',\n sku.name == 'GeneralPurpose' and location !in~ ('westeurope', 'northeurope', 'westus2', 'francecentral', 'eastus', 'eastus2', 'southeastasia', 'qatarcentral', 'australiaeast', 'japaneast', 'uksouth'), 'Not Applicable',\n properties.zoneRedundant == 'true', 'Configured',\n 'Not Configured'\n ),\n (type == 'microsoft.sql/servers/databases' and sku.tier == 'DataWarehouse'), \"Not Applicable\",\n (type == 'microsoft.documentdb/databaseaccounts'), iif(properties.locations[0].isZoneRedundant == \"false\", 'Not Configured', 'Configured'), \n (type == 'microsoft.dbformysql/servers'), \"Not Applicable\",\n (type == 'microsoft.dbformysql/flexibleservers'), iif(properties.haEnabled == \"Enabled\", 'Configured', 'Not Configured'),\n (type == 'microsoft.cache/redis'), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'),\n (type == \"microsoft.apimanagement/service\"), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'),\n (type == 'microsoft.servicebus/namespaces'), iff(properties.zoneRedundant == 'true', 'Configured', 'Not Configured'),\n (type contains 'storageaccounts'), case(split(skuName, '_', 1)[0] contains \"zrs\", \"Configured\", \"Not Configured\"),\n (type == \"microsoft.network/azurefirewalls\"), iif(isnotnull(zones), \"Configured\", \"Not Configured\"),\n (type == \"microsoft.network/frontdoors\"), \"Not Applicable\",\n (type == \"microsoft.cdn/profiles\"), \"Not Applicable\",\n (type == \"microsoft.network/applicationgateways\"), iif(isnotnull(zones), \"Configured\", \"Not Configured\"),\n (type == \"microsoft.network/loadbalancers\"), case( \n skuName =~ \"Basic\" or skuName =~ \"Global\", \"Not Applicable\",\n LbIpType =~ \"Public\", \"Public IP AZ Config\",\n tostring(LbAvZones) =~ \"0\", \"Not Configured\",\n tostring(LbAvZones)\n ),\n (type contains \"publicip\"), case( \n skuName =~ \"Basic\" or skuName =~ \"Global\", \"Not Applicable\",\n coalesce(tostring(array_length(parse_json(zones))), 'Not Configured')\n ),\n (type == \"microsoft.network/virtualnetworkgateways\"), \"Public IP AZ Config\",\n (type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Undefined\"\n )\n| extend avSets = case(\n type == 'microsoft.compute/virtualmachines' and avZones in ('1', '2', '3'), \"Not Applicable\",\n type == 'microsoft.compute/virtualmachines', (coalesce(extract('/availabilitySets/(.*)', 1, tostring(properties.availabilitySet.id)), 'Not Configured')),\n type == 'microsoft.classiccompute/virtualmachines', iff(isnotnull(properties.hardwareProfile.availabilitySet), 'Configured', 'Not Configured'),\n type == 'microsoft.compute/virtualmachinescalesets' and avZones in ('1', '2', '3'), \"Not Applicable\",\n type == 'microsoft.compute/virtualmachinescalesets', 'A regional (non-zonal) scale set uses placement groups, which act as an implicit availability set with five fault domains and five update domains.',\n type == 'microsoft.web/sites', 'Not Applicable',\n type == 'microsoft.web/serverfarms', 'Not Applicable',\n type == 'microsoft.containerservice/managedclusters', case(\n AvSets == 'Scale Sets' and avZones in ('1', '2', '3'), \"Not Applicable\",\n AvSets == 'Scale Sets', \"A regional (non-zonal) scale set uses placement groups, which act as an implicit availability set with five fault domains and five update domains.\",\n \"Scale Sets Not Configured\"\n ),\n type == 'microsoft.sql/servers/databases', 'Not Applicable',\n type == 'microsoft.documentdb/databaseaccounts', 'Not Applicable',\n type == 'microsoft.dbformysql/servers', \"Not Applicable\",\n type == 'microsoft.dbformysql/flexibleservers', \"Not Applicable\",\n type == 'microsoft.cache/redis', \"Not Applicable\",\n type == \"microsoft.apimanagement/service\", \"Not Applicable\",\n type == \"microsoft.servicebus/namespaces\", iif(zones in ('1', '2', '3'), \"configured\",\"not configured\"),\n type contains \"storageaccounts\", \"Not Applicable\",\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", \"Not Applicable\",\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", tostring(properties.publicIPAddressVersion), //Field Override\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.gatewayType), //Field Override\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend Capacity = case(\n type == 'microsoft.compute/virtualmachines', \"Not Applicable\",\n type == 'microsoft.classiccompute/virtualmachines', \"Not Applicable\",\n type == 'microsoft.compute/virtualmachinescalesets', tostring(sku.capacity),\n type == 'microsoft.web/sites', \"ASP Config\",\n type == 'microsoft.web/serverfarms', tostring(sku.capacity),\n type == 'microsoft.containerservice/managedclusters', iif(isnotempty(AksMinimumNodePoolCount), tostring(AksMinimumNodePoolCount), \"0\"), // AKS with or without VMSS\n type == 'microsoft.sql/servers/databases', tostring(sku.capacity),\n type == 'microsoft.documentdb/databaseaccounts', 'Not Applicable',\n type == 'microsoft.dbformysql/servers', tostring(sku.capacity),\n type == 'microsoft.dbformysql/flexibleservers', tostring(sku.capacity),\n type == 'microsoft.cache/redis', strcat(properties.sku.family, properties.sku.capacity),\n type == \"microsoft.apimanagement/service\", tostring(sku.capacity),\n type == \"microsoft.servicebus/namespaces\",iif(isnotnull(sku.capacity), tostring(sku.capacity), \"Not configured\"),\n type contains \"storageaccounts\", \"Not Applicable\", \n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", tostring(iif(isnotempty(properties.autoscaleConfiguration), properties.autoscaleConfiguration.minCapacity, properties.sku.capacity)),\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", iif(type == \"microsoft.network/publicipprefixes\", \"PIP-prefix\", \"Single\"), //Field Override\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.sku.capacity),\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend FaultDomain = case(\n type == 'microsoft.compute/virtualmachines', \"Not Applicable\",\n type == 'microsoft.classiccompute/virtualmachines', \"Not Applicable\",\n type == 'microsoft.compute/virtualmachinescalesets', iif(isnotempty(properties.platformFaultDomainCount), properties.platformFaultDomainCount, \"0\"), // 1 - AZ, 5 - Regional VMSS\n type == 'microsoft.web/sites', \"Not Applicable\",\n type == 'microsoft.web/serverfarms', 'Not Applicable',\n type == 'microsoft.containerservice/managedclusters', iif(isnotempty(tostring(FaultDomainCount)), tostring(FaultDomainCount), \"0\"),\n type == 'microsoft.sql/servers/databases', \"Not Applicable\",\n type == 'microsoft.documentdb/databaseaccounts', 'Not Applicable',\n type == 'microsoft.dbformysql/servers', 'Not Applicable',\n type == 'microsoft.dbformysql/flexibleservers', 'Not Applicable',\n type == 'microsoft.cache/redis', 'Not Applicable',\n type == \"microsoft.apimanagement/service\", \"Not Applicable\",\n type == \"microsoft.servicebus/namespaces\",properties.minimumTlsVersion,//use it for tls version, renaming the column\n type contains \"storageaccounts\", \"Not Applicable\",\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", \"Not Applicable\",\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", \"Not Applicable\",\n type == \"microsoft.network/virtualnetworkgateways\", iff(properties.gatewayType == \"ExpressRoute\" and properties.vpnType == \"PolicyBased\", \"ErPolicyBased\", tostring(properties.vpnType)), //Field Override\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend osDisk = case(\n type == 'microsoft.compute/virtualmachines', iif(properties.storageProfile.osDisk.diffDiskSettings.option == \"Local\", \"Ephemeral\", properties.storageProfile.osDisk.managedDisk.storageAccountType),\n type == 'microsoft.classiccompute/virtualmachines', 'Classic',\n type == 'microsoft.compute/virtualmachinescalesets', iif(properties.virtualMachineProfile.storageProfile.osDisk.diffDiskSettings.option == \"Local\", \"Ephemeral\", properties.virtualMachineProfile.storageProfile.osDisk.managedDisk.storageAccountType),\n type == 'microsoft.web/sites', 'Not Applicable',\n type == 'microsoft.web/serverfarms', 'Not Applicable',\n type == 'microsoft.containerservice/managedclusters', AksNodePoolStorageAccountType,\n type == 'microsoft.sql/servers/databases', properties.storageAccountType,\n type == 'microsoft.documentdb/databaseaccounts', 'Not Applicable',\n type == 'microsoft.dbformysql/servers', 'Not Applicable',\n type == 'microsoft.dbformysql/flexibleservers', 'Not Applicable',\n type == 'microsoft.cache/redis', 'Not Applicable',\n type == \"microsoft.apimanagement/service\", tostring(properties.platformVersion), //Field Override\n type == \"microsoft.servicebus/namespaces\", \"Not Applicable\",\n type contains \"storageaccounts\", tostring(split(skuName, '_', 0)[0]),\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", \"Not Applicable\",\n type == \"microsoft.network/loadbalancers\", tostring(LbIpType), //Field Override\n type contains \"publicip\", tostring(properties.publicIPAllocationMethod), //Field Override\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.vpnGatewayGeneration), //Field Override\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n 'Not Applicable'\n )\n| extend OSDisk = case(\n isnotempty(osDisk), osDisk,\n isempty(osDisk) and (type == 'microsoft.compute/virtualmachines') and state <> 'VM running', 'Unknown, start VM to get disk information.',\n isempty(osDisk) and (type == 'microsoft.compute/virtualmachines') and isnotempty(properties.storageProfile.osDisk.vhd.uri), 'Unmanaged',\n \"Unknown\")\n| extend ReadReplica = case (\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters'), \"Not Applicable\",\n (type == 'microsoft.sql/servers/databases' and sku.tier <> 'DataWarehouse'), tostring(properties.readReplicaCount), // SQL DB\n (type == 'microsoft.sql/servers/databases' and sku.tier == 'DataWarehouse'), \"Not Applicable\", // Synapse\n type == 'microsoft.documentdb/databaseaccounts', tostring(array_length(parse_json(properties.readLocations))),\n type == 'microsoft.dbformysql/servers', \"Not Applicable\",\n type == 'microsoft.dbformysql/flexibleservers', \"Not Applicable\",\n type == 'microsoft.cache/redis', 'Not Applicable',\n type == \"microsoft.apimanagement/service\", tostring(properties.additionalLocations),\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n type contains \"storageaccounts\", case(\n location in~ ('qatarcentral'), 'Not Applicable',\n split(skuName, '_', 1)[0] startswith \"ra\", \"Configured\",\n \"Not Configured\"\n ),\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", \"Not Applicable\",\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", \"Not Applicable\",\n type == \"microsoft.network/virtualnetworkgateways\", iff(properties.gatewayType == \"ExpressRoute\", \"Not Applicable\", tostring(properties.activeActive)), //Field Override,\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend AutomaticFailover = case(\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters', 'microsoft.sql/servers/databases'), \"Not Applicable\",\n (type == 'microsoft.documentdb/databaseaccounts' and properties.enableAutomaticFailover == \"false\" and properties.enableMultipleWriteLocations == \"false\" and toint(ReadReplica) > 1), \"Not Configured\",\n (type == 'microsoft.documentdb/databaseaccounts' and properties.enableAutomaticFailover == \"true\"), \"Configured\",\n (type == 'microsoft.documentdb/databaseaccounts'), \"Not Applicable\",\n type == 'microsoft.dbformysql/servers', \"Not Applicable\",\n type == 'microsoft.dbformysql/flexibleservers', case(properties.haEnabled == \"Enabled\", \"Configured\", \"Not Applicable\"),\n type == 'microsoft.cache/redis', 'Not Applicable',\n type == \"microsoft.apimanagement/service\", \"Not Applicable\",\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n type contains \"storageaccounts\", \"Not Applicable\",\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", iif(isnotempty(properties.autoscaleConfiguration), \"Configured\", \"Not Configured\"),\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", \"Not Applicable\",\n type == \"microsoft.network/virtualnetworkgateways\", \"Not Applicable\",\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend MultipleWriteLocations = case(\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters', 'microsoft.sql/servers/databases', 'microsoft.dbformysql/servers', 'microsoft.dbformysql/flexibleservers'), \"Not Applicable\",\n (type == 'microsoft.documentdb/databaseaccounts' and properties.enableMultipleWriteLocations == \"false\"), \"Not Enabled\",\n (type == 'microsoft.documentdb/databaseaccounts' and properties.enableMultipleWriteLocations == \"true\"), \"Enabled\",\n (type == 'microsoft.cache/redis'), 'Not Applicable',\n (type == \"microsoft.apimanagement/service\"), \"Not Applicable\",\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n (type contains \"storageaccounts\"), \"Not Applicable\",\n (type == \"microsoft.network/azurefirewalls\"), \"Not Applicable\",\n (type == \"microsoft.network/frontdoors\"), \"Not Applicable\",\n (type == \"microsoft.cdn/profiles\"), \"Not Applicable\",\n (type == \"microsoft.network/applicationgateways\"), \"Not Applicable\",\n (type == \"microsoft.network/loadbalancers\"), \"Not Applicable\",\n (type contains \"publicip\"), \"Not Applicable\",\n (type == \"microsoft.network/virtualnetworkgateways\"), \"Not Applicable\",\n (type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Undefined\"\n )\n| extend StorageAutogrow = case(\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters', 'microsoft.sql/servers/databases', 'microsoft.documentdb/databaseaccounts'), \"Not Applicable\",\n (type == 'microsoft.dbformysql/servers'), tostring(properties.storageProfile.storageAutogrow),\n (type == 'microsoft.dbformysql/flexibleservers'), \"Not Applicable\",\n (type == 'microsoft.cache/redis'), 'Not Applicable',\n (type == \"microsoft.apimanagement/service\"), \"Not Applicable\",\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n (type contains \"storageaccounts\"), \"Not Applicable\",\n (type == \"microsoft.network/azurefirewalls\"), \"Not Applicable\",\n (type == \"microsoft.network/frontdoors\"), \"Not Applicable\",\n (type == \"microsoft.cdn/profiles\"), \"Not Applicable\",\n (type == \"microsoft.network/applicationgateways\"), \"Not Applicable\",\n (type == \"microsoft.network/loadbalancers\"), \"Not Applicable\",\n (type contains \"publicip\"), \"Not Applicable\",\n (type == \"microsoft.network/virtualnetworkgateways\"), \"Not Applicable\",\n (type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Undefined\"\n )\n| extend ReplicationRole = case(\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters', 'microsoft.documentdb/databaseaccounts'), \"Not Applicable\",\n (type == 'microsoft.sql/servers/databases' and sku.tier <> 'DataWarehouse'), iif(isnotempty(properties.secondaryType), \"replica\", \"master\"),\n (type == 'microsoft.sql/servers/databases' and sku.tier == 'DataWarehouse'), \"Not Applicable\",\n (type == 'microsoft.dbformysql/servers'), tostring(properties.replicationRole),\n (type == 'microsoft.dbformysql/flexibleservers'), iif(properties.haEnabled == \"Enabled\", 'Not Applicable', tostring(properties.replicationRole)),\n (type == 'microsoft.cache/redis'), 'Not Applicable',\n (type == \"microsoft.apimanagement/service\"), \"Not Applicable\",\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n (type contains \"storageaccounts\"), tostring(split(skuName, '_', 1)[0]),\n (type == \"microsoft.network/azurefirewalls\"), \"Not Applicable\",\n (type == \"microsoft.network/frontdoors\"), \"Not Applicable\",\n (type == \"microsoft.cdn/profiles\"), \"Not Applicable\",\n (type == \"microsoft.network/applicationgateways\"), \"Not Applicable\",\n (type == \"microsoft.network/loadbalancers\"), \"Not Applicable\",\n (type contains \"publicip\"), \"Not Applicable\",\n (type == \"microsoft.network/virtualnetworkgateways\"), \"Not Applicable\",\n (type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Undefined\"\n )\n| project \n Type = tolower(type),\n SkuName = tolower(skuName),\n Kind = tolower(kind),\n SubscriptionId = subscriptionId,\n Name = tolower(tostring(id)),\n State = tolower(state),\n Location = tolower(location),\n ResourceGroup = resourceGroup,\n Zones = tolower(tostring(zones)),\n AvailabilityZone = tolower(avZones),\n AvailabilitySet = tolower(avSets),\n Capacity = tolower(Capacity),\n FaultDomain = tolower(FaultDomain),\n OSDisk = tolower(OSDisk),\n ReadReplica = tolower(ReadReplica), \n AutomaticFailover = tolower(AutomaticFailover),\n MultipleWriteLocations = tolower(MultipleWriteLocations),\n StorageAutogrow = tolower(StorageAutogrow),\n ReplicationRole = tolower(ReplicationRole),\n Environment = environment,\n properties\n| join kind = leftouter (\n recoveryservicesresources\n | where name startswith \"VM;\"\n | project Name = tolower(tostring(properties.dataSourceInfo.resourceID)), Backup = tostring(properties.protectionStatus)\n )\n on Name\n| extend Backup = case(\n Backup == \"Healthy\" or Backup == \"Unhealthy\", Backup,\n \"Unknown\")\n| extend Backup = case(\n (Type == 'microsoft.compute/virtualmachines'), iif(Backup == \"Unknown\", \"Not Configured\", Backup),\n (Type == 'microsoft.classiccompute/virtualmachines'), iif(Backup == \"Unknown\", \"Not Configured\", Backup),\n (Type == \"microsoft.compute/virtualmachinescalesets\"), \"Not Applicable\", \n (Type == \"microsoft.containerservice/managedclusters\"), \"Not Applicable\",\n (Type == 'microsoft.sql/servers/databases'), \"Not Applicable\", \n (Type == 'microsoft.documentdb/databaseaccounts'), iif(properties.backupPolicy.periodicModeProperties.backupStorageRedundancy == \"Geo\", \"Healthy\", \"Unhealthy\"),\n (Type == 'microsoft.dbformysql/servers'), iif(properties.storageProfile.geoRedundantBackup == \"Enabled\", \"Healthy\", \"Unhealthy\"),\n (Type contains \"storageaccounts\"), \"Not Applicable\",\n (Type == \"microsoft.network/azurefirewalls\"), \"Not Applicable\",\n (Type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Unknown\"\n )\n| project Type, SkuName, Kind, Name, State, Location, ResourceGroup, AvailabilityZone, Zones=AvailabilitySet, Capacity, MinTLSVersion=FaultDomain, Environment\n| where Type == 'microsoft.servicebus/namespaces'\n| summarize ResourceTotal=count(Name), NotPremium=dcountif(Name, SkuName!= \"Premium\"), NoMultipleZones=dcountif(Name, Zones != \"null\"), NotSucceeded=dcountif(Name, State != \"Succeeded\")\n,NoAVZone=dcountif(Name, AvailabilityZone==false),NoMinimumTLSVersion=dcountif(Name,MinTLSVersion!=1.2), CapacityNotConfigured=dcountif(Name, Capacity==\"Not configured\")", + "size": 3, + "title": "Service Bus - Recommendation Summary", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "value::all" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "Type", + "formatter": 5 + }, + { + "columnMatch": "Kind", + "formatter": 5 + }, + { + "columnMatch": "SubscriptionId", + "formatter": 5 + }, + { + "columnMatch": "Name", + "formatter": 5 + }, + { + "columnMatch": "Location", + "formatter": 17 + }, + { + "columnMatch": "AvailabilityZone", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "not applicable", + "representation": "more", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "not configured", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "1", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "2", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "3", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "configured", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "Unknown", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Environment", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "contains", + "thresholdValue": "prod", + "representation": "redBright", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "Prod", + "representation": "redBright", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "OSDisk", + "formatter": 5 + }, + { + "columnMatch": "ReadReplica", + "formatter": 5 + }, + { + "columnMatch": "AutomaticFailover", + "formatter": 5 + }, + { + "columnMatch": "MultipleWriteLocations", + "formatter": 5 + }, + { + "columnMatch": "StorageAutogrow", + "formatter": 5 + }, + { + "columnMatch": "ReplicationRole", + "formatter": 5 + }, + { + "columnMatch": "properties", + "formatter": 5 + }, + { + "columnMatch": "Backup", + "formatter": 5 + }, + { + "columnMatch": "SubscriptionName", + "formatter": 5 + }, + { + "columnMatch": "Tier", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "Premium", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "2", + "text": "{0}{1}" + } + ] + } + } + ] + }, + "sortBy": [] + }, + "name": "kql_integration_servicebus_resources_details_summary" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources\n| where resourceGroup in ({ResourceGroup})\n| extend environment = case(\n tags.Environment <> \"\", tags.Environment,\n tags.environment <> \"\", tags.environment,\n tags.Env <> \"\", tags.Env,\n tags.env <> \"\", tags.env,\n tolower(name) contains \"prod\", \"Production\",\n tolower(name) contains \"dev\", \"Development\",\n tolower(name) contains \"qa\", \"QA\",\n tolower(name) contains \"uat\", \"UAT\",\n tolower(name) contains \"sit\", \"SIT\",\n tolower(name) contains \"test\", \"Test\",\n \"Undefined\")\n| where environment in ({Environment})\n| join kind = innerunique(\n resources\n | extend replaced_tags = replace('{}', 'null', tostring(tags))\n | extend replaced_tags = parse_json(replaced_tags)\n | mv-expand replaced_tags\n | extend tagName = tostring(bag_keys(replaced_tags)[0])\n | extend tagValue = tostring(replaced_tags['{TagName}'])\n | where tagName has '{TagName}' and tagValue has '{TagValue}'\n | distinct id\n )\n on id\n| where \n (type == 'microsoft.compute/virtualmachines') or \n (type == 'microsoft.classiccompute/virtualmachines') or \n (type == \"microsoft.compute/virtualmachinescalesets\" and tags.aksEngineVersion !contains \"aks-gomod\") or\n (type == 'microsoft.web/sites') or \n (type == 'microsoft.web/serverfarms') or\n (type == \"microsoft.containerservice/managedclusters\") or \n (type == 'microsoft.sql/servers/databases') or \n (type == 'microsoft.documentdb/databaseaccounts') or \n (type == 'microsoft.dbformysql/servers') or \n (type == 'microsoft.dbformysql/flexibleservers') or \n (type == 'microsoft.cache/redis') or\n (type == \"microsoft.apimanagement/service\") or \n (type== 'microsoft.servicebus/namespaces') or\n (type == \"microsoft.storage/storageaccounts\" or type == \"microsoft.classicstorage/storageaccounts\") or \n (type == \"microsoft.network/azurefirewalls\") or \n (type == \"microsoft.network/frontdoors\") or\n (type == \"microsoft.cdn/profiles\") or\n (type == \"microsoft.network/applicationgateways\") or \n (type == \"microsoft.network/loadbalancers\") or \n (type == \"microsoft.network/publicipaddresses\" or type == \"microsoft.network/publicipprefixes\") or \n (type == \"microsoft.network/virtualnetworkgateways\") or \n (type == \"microsoft.recoveryservices/vaults\")\n| join kind=leftouter (\n resources \n | where type == \"microsoft.containerservice/managedclusters\"\n // Expand per node pool to get using zone for all node pool\n | mv-expand agentPoolProfiles = properties.agentPoolProfiles\n | extend AvZones = agentPoolProfiles.availabilityZones\n | extend AksNodeResourceGroup = tolower(tostring(properties.nodeResourceGroup))\n // Get number of using zone per node pool VMSS. If it doesn't use any zone, return 0\n | extend useAvZone = case(\n array_length( AvZones ) > 0, array_length( AvZones ), 0\n )\n | join kind=leftouter(\n resources\n | where type == 'microsoft.compute/virtualmachinescalesets'\n | extend resourceGroup = tolower(tostring(resourceGroup))\n | extend VmssCapacity = sku.capacity\n | extend vmssStorageAccountType = iff(\n properties.virtualMachineProfile.storageProfile.osDisk.diffDiskSettings.option == \"Local\", \"Ephemeral\", properties.virtualMachineProfile.storageProfile.osDisk.managedDisk.storageAccountType\n )\n ) on $left.AksNodeResourceGroup == $right.resourceGroup // Match AKS and VMSS with nodeResourceGroup\n | summarize AvZones=min(useAvZone), AksMinimumNodePoolCount=min(toint(VmssCapacity)), AksNodePoolStorageAccountType=make_set(vmssStorageAccountType), FaultDomainCount=min(toint(properties1.platformFaultDomainCount)) by id, name, type, tenantId, kind, location, resourceGroup, subscriptionId, tostring(sku), tostring(plan), tostring(properties), AksNodeResourceGroup\n | extend AksNodePoolStorageAccountType = iff(\n tolower(tostring(AksNodePoolStorageAccountType)) contains \"standard_lrs\", \"standard_lrs\", tolower(tostring(strcat_array(AksNodePoolStorageAccountType, \",\")))\n )\n // If there are some node pools within AKS cluster, it returns minimum number of zones. \n // If even one node pool is not using a zone, it will be \"Not Configured\".\n | extend AvZones = iff(tostring(AvZones) == \"0\", \"Not Configured\", tostring(AvZones)), AvSets = \"Scale Sets\"\n) on id\n// Start - Azure Load Balancer additional logic\n| mv-expand LbFeIpConfig = properties.frontendIPConfigurations\n| extend LbUseAvZone = iff(array_length(LbFeIpConfig.zones ) > 0, array_length(LbFeIpConfig.zones ), 0)\n| extend LbIpType = iff(isnotnull(LbFeIpConfig.properties.publicIPAddress), \"Public\", \"Private\")\n//| summarize LbAvZones = min(LbUseAvZone) by id, name, type, tenantId, kind, location, resourceGroup, subscriptionId, tostring(sku), plan, tostring(properties)\n//| extend properties = todynamic(properties), sku = todynamic(sku), \n| summarize LbAvZones = arg_min(LbUseAvZone, *) by id\n// End - Azure Load Balancer additional logic\n| extend state = case(\n type == 'microsoft.compute/virtualmachines', tostring(properties.extended.instanceView.powerState.displayStatus),\n type == 'microsoft.classiccompute/virtualmachines', tostring(properties.instanceView.powerState),\n type == 'microsoft.compute/virtualmachinescalesets', tostring(properties.provisioningState),\n type == 'microsoft.web/sites', tostring(properties.state),\n type == 'microsoft.web/serverfarms', tostring(properties.status),\n type == 'microsoft.containerservice/managedclusters', tostring(properties.provisioningState),\n type == 'microsoft.sql/servers/databases', tostring(properties.status),\n type == 'microsoft.documentdb/databaseaccounts', tostring(properties.provisioningState),\n type == 'microsoft.dbformysql/servers', tostring(properties.userVisibleState),\n type == 'microsoft.dbformysql/flexibleservers', tostring(properties.state),\n type == 'microsoft.cache/redis', tostring(properties.provisioningState),\n type == \"microsoft.apimanagement/service\", tostring(properties.provisioningState),\n type == 'microsoft.servicebus/namespaces',tostring(properties.provisioningState),\n type contains \"storageaccounts\", tostring(properties.provisioningState),\n type == \"microsoft.network/azurefirewalls\", tostring(properties.provisioningState),\n type == \"microsoft.network/frontdoors\", tostring(properties.resourceState),\n type == \"microsoft.cdn/profiles\", tostring(properties.resourceState),\n type == \"microsoft.network/applicationgateways\", tostring(properties.operationalState),\n type == \"microsoft.network/loadbalancers\", tostring(properties.provisioningState),\n type contains \"publicip\", tostring(properties.provisioningState),\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.provisioningState),\n type == \"microsoft.recoveryservices/vaults\", tostring(properties.provisioningState),\n \"Undefined\"\n )\n| extend skuName = case(\n type == 'microsoft.compute/virtualmachines', tostring(properties.hardwareProfile.vmSize),\n type == 'microsoft.classiccompute/virtualmachines', tostring(properties.hardwareProfile.size),\n type == 'microsoft.compute/virtualmachinescalesets', tostring(sku.name),\n type == 'microsoft.web/sites', tostring(properties.sku),\n type == 'microsoft.web/serverfarms', tostring(sku.tier),\n type == 'microsoft.containerservice/managedclusters', tostring(properties.agentPoolProfiles[0].vmSize),\n type == 'microsoft.sql/servers/databases', tostring(sku.tier),\n type == 'microsoft.documentdb/databaseaccounts', tostring(properties.databaseAccountOfferType),\n type == 'microsoft.dbformysql/servers', tostring(sku.tier),\n type == 'microsoft.dbformysql/flexibleservers', tostring(sku.tier),\n type == 'microsoft.cache/redis', tostring(properties.sku.name),\n type == \"microsoft.apimanagement/service\", tostring(sku.name),\n type == 'microsoft.servicebus/namespaces', tostring(sku.name),\n type contains 'storageaccounts', tostring(replace('-', '_', tostring(iff(type =~ \"microsoft.storage/storageaccounts\", sku.name, properties.accountType)))),\n type == \"microsoft.network/azurefirewalls\", tostring(properties.sku.name),\n type == \"microsoft.network/frontdoors\", \"classic_frontdoor\",\n type == \"microsoft.cdn/profiles\", tostring(sku.name),\n type == \"microsoft.network/applicationgateways\", tostring(properties.sku.name),\n type == \"microsoft.network/loadbalancers\", iff(sku.tier == 'Global', 'Global', tostring(sku.name)),\n type contains \"publicip\", iff(sku.tier == 'Global', 'Global', tostring(sku.name)),\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.sku.name),\n type == \"microsoft.recoveryservices/vaults\", tostring(iif(isnotnull(sku.tier), sku.tier, sku.name)),\n \"Undefined\"\n )\n| extend avZones = case(\n location !in~ ('brazilsouth', 'canadacentral', 'centralus', 'eastus', 'eastus2', 'southcentralus', 'usgovvirginia', 'westus2', 'westus3', 'francecentral', 'germanywestcentral', 'northeurope', 'norwayeast', 'uksouth', 'westeurope', 'swedencentral', 'switzerlandnorth', 'polandcentral', 'qatarcentral', 'uaenorth', 'southafricanorth', 'australiaeast', 'centralindia', 'japaneast', 'koreacentral', 'southeastasia', 'eastasia', 'chinanorth3'), 'Not Applicable',\n (type == 'microsoft.compute/virtualmachines'), coalesce(tostring(zones[0]), 'Not Configured'),\n (type == 'microsoft.classiccompute/virtualmachines'), 'Not Applicable',\n (type == 'microsoft.compute/virtualmachinescalesets'), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'),\n (type == 'microsoft.containerservice/managedclusters' and AvZones <> \"\"), AvZones,\n (type == 'microsoft.containerservice/managedclusters' and isempty(AvZones)), \"Not Configured\",\n (type == 'microsoft.web/sites'), \"ASP AZ config\",\n (type == 'microsoft.web/serverfarms'), iff(properties.zoneRedundant == 'true', 'Configured', 'Not Configured'),\n (type == 'microsoft.sql/servers/databases' and sku.tier <> 'DataWarehouse'), case( //SQL AZ SKU & region availability filter\n sku.name == 'Basic' or sku.name == 'Standard' or sku.name == 'System', 'Not Applicable',\n sku.name == 'GeneralPurpose' and location !in~ ('westeurope', 'northeurope', 'westus2', 'francecentral', 'eastus', 'eastus2', 'southeastasia', 'qatarcentral', 'australiaeast', 'japaneast', 'uksouth'), 'Not Applicable',\n properties.zoneRedundant == 'true', 'Configured',\n 'Not Configured'\n ),\n (type == 'microsoft.sql/servers/databases' and sku.tier == 'DataWarehouse'), \"Not Applicable\",\n (type == 'microsoft.documentdb/databaseaccounts'), iif(properties.locations[0].isZoneRedundant == \"false\", 'Not Configured', 'Configured'), \n (type == 'microsoft.dbformysql/servers'), \"Not Applicable\",\n (type == 'microsoft.dbformysql/flexibleservers'), iif(properties.haEnabled == \"Enabled\", 'Configured', 'Not Configured'),\n (type == 'microsoft.cache/redis'), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'),\n (type == \"microsoft.apimanagement/service\"), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'),\n (type == 'microsoft.servicebus/namespaces'), iff(properties.zoneRedundant == 'true', 'Configured', 'Not Configured'),\n (type contains 'storageaccounts'), case(split(skuName, '_', 1)[0] contains \"zrs\", \"Configured\", \"Not Configured\"),\n (type == \"microsoft.network/azurefirewalls\"), iif(isnotnull(zones), \"Configured\", \"Not Configured\"),\n (type == \"microsoft.network/frontdoors\"), \"Not Applicable\",\n (type == \"microsoft.cdn/profiles\"), \"Not Applicable\",\n (type == \"microsoft.network/applicationgateways\"), iif(isnotnull(zones), \"Configured\", \"Not Configured\"),\n (type == \"microsoft.network/loadbalancers\"), case( \n skuName =~ \"Basic\" or skuName =~ \"Global\", \"Not Applicable\",\n LbIpType =~ \"Public\", \"Public IP AZ Config\",\n tostring(LbAvZones) =~ \"0\", \"Not Configured\",\n tostring(LbAvZones)\n ),\n (type contains \"publicip\"), case( \n skuName =~ \"Basic\" or skuName =~ \"Global\", \"Not Applicable\",\n coalesce(tostring(array_length(parse_json(zones))), 'Not Configured')\n ),\n (type == \"microsoft.network/virtualnetworkgateways\"), \"Public IP AZ Config\",\n (type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Undefined\"\n )\n| extend avSets = case(\n type == 'microsoft.compute/virtualmachines' and avZones in ('1', '2', '3'), \"Not Applicable\",\n type == 'microsoft.compute/virtualmachines', (coalesce(extract('/availabilitySets/(.*)', 1, tostring(properties.availabilitySet.id)), 'Not Configured')),\n type == 'microsoft.classiccompute/virtualmachines', iff(isnotnull(properties.hardwareProfile.availabilitySet), 'Configured', 'Not Configured'),\n type == 'microsoft.compute/virtualmachinescalesets' and avZones in ('1', '2', '3'), \"Not Applicable\",\n type == 'microsoft.compute/virtualmachinescalesets', 'A regional (non-zonal) scale set uses placement groups, which act as an implicit availability set with five fault domains and five update domains.',\n type == 'microsoft.web/sites', 'Not Applicable',\n type == 'microsoft.web/serverfarms', 'Not Applicable',\n type == 'microsoft.containerservice/managedclusters', case(\n AvSets == 'Scale Sets' and avZones in ('1', '2', '3'), \"Not Applicable\",\n AvSets == 'Scale Sets', \"A regional (non-zonal) scale set uses placement groups, which act as an implicit availability set with five fault domains and five update domains.\",\n \"Scale Sets Not Configured\"\n ),\n type == 'microsoft.sql/servers/databases', 'Not Applicable',\n type == 'microsoft.documentdb/databaseaccounts', 'Not Applicable',\n type == 'microsoft.dbformysql/servers', \"Not Applicable\",\n type == 'microsoft.dbformysql/flexibleservers', \"Not Applicable\",\n type == 'microsoft.cache/redis', \"Not Applicable\",\n type == \"microsoft.apimanagement/service\", \"Not Applicable\",\n type == \"microsoft.servicebus/namespaces\", iif(zones in ('1', '2', '3'), \"configured\",\"not configured\"),\n type contains \"storageaccounts\", \"Not Applicable\",\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", \"Not Applicable\",\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", tostring(properties.publicIPAddressVersion), //Field Override\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.gatewayType), //Field Override\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend Capacity = case(\n type == 'microsoft.compute/virtualmachines', \"Not Applicable\",\n type == 'microsoft.classiccompute/virtualmachines', \"Not Applicable\",\n type == 'microsoft.compute/virtualmachinescalesets', tostring(sku.capacity),\n type == 'microsoft.web/sites', \"ASP Config\",\n type == 'microsoft.web/serverfarms', tostring(sku.capacity),\n type == 'microsoft.containerservice/managedclusters', iif(isnotempty(AksMinimumNodePoolCount), tostring(AksMinimumNodePoolCount), \"0\"), // AKS with or without VMSS\n type == 'microsoft.sql/servers/databases', tostring(sku.capacity),\n type == 'microsoft.documentdb/databaseaccounts', 'Not Applicable',\n type == 'microsoft.dbformysql/servers', tostring(sku.capacity),\n type == 'microsoft.dbformysql/flexibleservers', tostring(sku.capacity),\n type == 'microsoft.cache/redis', strcat(properties.sku.family, properties.sku.capacity),\n type == \"microsoft.apimanagement/service\", tostring(sku.capacity),\n type == \"microsoft.servicebus/namespaces\",iif(isnotnull(sku.capacity), tostring(sku.capacity), \"Not configured\"),\n type contains \"storageaccounts\", \"Not Applicable\", \n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", tostring(iif(isnotempty(properties.autoscaleConfiguration), properties.autoscaleConfiguration.minCapacity, properties.sku.capacity)),\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", iif(type == \"microsoft.network/publicipprefixes\", \"PIP-prefix\", \"Single\"), //Field Override\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.sku.capacity),\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend FaultDomain = case(\n type == 'microsoft.compute/virtualmachines', \"Not Applicable\",\n type == 'microsoft.classiccompute/virtualmachines', \"Not Applicable\",\n type == 'microsoft.compute/virtualmachinescalesets', iif(isnotempty(properties.platformFaultDomainCount), properties.platformFaultDomainCount, \"0\"), // 1 - AZ, 5 - Regional VMSS\n type == 'microsoft.web/sites', \"Not Applicable\",\n type == 'microsoft.web/serverfarms', 'Not Applicable',\n type == 'microsoft.containerservice/managedclusters', iif(isnotempty(tostring(FaultDomainCount)), tostring(FaultDomainCount), \"0\"),\n type == 'microsoft.sql/servers/databases', \"Not Applicable\",\n type == 'microsoft.documentdb/databaseaccounts', 'Not Applicable',\n type == 'microsoft.dbformysql/servers', 'Not Applicable',\n type == 'microsoft.dbformysql/flexibleservers', 'Not Applicable',\n type == 'microsoft.cache/redis', 'Not Applicable',\n type == \"microsoft.apimanagement/service\", \"Not Applicable\",\n type == \"microsoft.servicebus/namespaces\",properties.minimumTlsVersion,//use it for tls version, renaming the column\n type contains \"storageaccounts\", \"Not Applicable\",\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", \"Not Applicable\",\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", \"Not Applicable\",\n type == \"microsoft.network/virtualnetworkgateways\", iff(properties.gatewayType == \"ExpressRoute\" and properties.vpnType == \"PolicyBased\", \"ErPolicyBased\", tostring(properties.vpnType)), //Field Override\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend osDisk = case(\n type == 'microsoft.compute/virtualmachines', iif(properties.storageProfile.osDisk.diffDiskSettings.option == \"Local\", \"Ephemeral\", properties.storageProfile.osDisk.managedDisk.storageAccountType),\n type == 'microsoft.classiccompute/virtualmachines', 'Classic',\n type == 'microsoft.compute/virtualmachinescalesets', iif(properties.virtualMachineProfile.storageProfile.osDisk.diffDiskSettings.option == \"Local\", \"Ephemeral\", properties.virtualMachineProfile.storageProfile.osDisk.managedDisk.storageAccountType),\n type == 'microsoft.web/sites', 'Not Applicable',\n type == 'microsoft.web/serverfarms', 'Not Applicable',\n type == 'microsoft.containerservice/managedclusters', AksNodePoolStorageAccountType,\n type == 'microsoft.sql/servers/databases', properties.storageAccountType,\n type == 'microsoft.documentdb/databaseaccounts', 'Not Applicable',\n type == 'microsoft.dbformysql/servers', 'Not Applicable',\n type == 'microsoft.dbformysql/flexibleservers', 'Not Applicable',\n type == 'microsoft.cache/redis', 'Not Applicable',\n type == \"microsoft.apimanagement/service\", tostring(properties.platformVersion), //Field Override\n type == \"microsoft.servicebus/namespaces\", \"Not Applicable\",\n type contains \"storageaccounts\", tostring(split(skuName, '_', 0)[0]),\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", \"Not Applicable\",\n type == \"microsoft.network/loadbalancers\", tostring(LbIpType), //Field Override\n type contains \"publicip\", tostring(properties.publicIPAllocationMethod), //Field Override\n type == \"microsoft.network/virtualnetworkgateways\", tostring(properties.vpnGatewayGeneration), //Field Override\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n 'Not Applicable'\n )\n| extend OSDisk = case(\n isnotempty(osDisk), osDisk,\n isempty(osDisk) and (type == 'microsoft.compute/virtualmachines') and state <> 'VM running', 'Unknown, start VM to get disk information.',\n isempty(osDisk) and (type == 'microsoft.compute/virtualmachines') and isnotempty(properties.storageProfile.osDisk.vhd.uri), 'Unmanaged',\n \"Unknown\")\n| extend ReadReplica = case (\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters'), \"Not Applicable\",\n (type == 'microsoft.sql/servers/databases' and sku.tier <> 'DataWarehouse'), tostring(properties.readReplicaCount), // SQL DB\n (type == 'microsoft.sql/servers/databases' and sku.tier == 'DataWarehouse'), \"Not Applicable\", // Synapse\n type == 'microsoft.documentdb/databaseaccounts', tostring(array_length(parse_json(properties.readLocations))),\n type == 'microsoft.dbformysql/servers', \"Not Applicable\",\n type == 'microsoft.dbformysql/flexibleservers', \"Not Applicable\",\n type == 'microsoft.cache/redis', 'Not Applicable',\n type == \"microsoft.apimanagement/service\", tostring(properties.additionalLocations),\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n type contains \"storageaccounts\", case(\n location in~ ('qatarcentral'), 'Not Applicable',\n split(skuName, '_', 1)[0] startswith \"ra\", \"Configured\",\n \"Not Configured\"\n ),\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", \"Not Applicable\",\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", \"Not Applicable\",\n type == \"microsoft.network/virtualnetworkgateways\", iff(properties.gatewayType == \"ExpressRoute\", \"Not Applicable\", tostring(properties.activeActive)), //Field Override,\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend AutomaticFailover = case(\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters', 'microsoft.sql/servers/databases'), \"Not Applicable\",\n (type == 'microsoft.documentdb/databaseaccounts' and properties.enableAutomaticFailover == \"false\" and properties.enableMultipleWriteLocations == \"false\" and toint(ReadReplica) > 1), \"Not Configured\",\n (type == 'microsoft.documentdb/databaseaccounts' and properties.enableAutomaticFailover == \"true\"), \"Configured\",\n (type == 'microsoft.documentdb/databaseaccounts'), \"Not Applicable\",\n type == 'microsoft.dbformysql/servers', \"Not Applicable\",\n type == 'microsoft.dbformysql/flexibleservers', case(properties.haEnabled == \"Enabled\", \"Configured\", \"Not Applicable\"),\n type == 'microsoft.cache/redis', 'Not Applicable',\n type == \"microsoft.apimanagement/service\", \"Not Applicable\",\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n type contains \"storageaccounts\", \"Not Applicable\",\n type == \"microsoft.network/azurefirewalls\", \"Not Applicable\",\n type == \"microsoft.network/frontdoors\", \"Not Applicable\",\n type == \"microsoft.cdn/profiles\", \"Not Applicable\",\n type == \"microsoft.network/applicationgateways\", iif(isnotempty(properties.autoscaleConfiguration), \"Configured\", \"Not Configured\"),\n type == \"microsoft.network/loadbalancers\", \"Not Applicable\",\n type contains \"publicip\", \"Not Applicable\",\n type == \"microsoft.network/virtualnetworkgateways\", \"Not Applicable\",\n type == \"microsoft.recoveryservices/vaults\", \"Not Applicable\",\n \"Undefined\"\n )\n| extend MultipleWriteLocations = case(\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters', 'microsoft.sql/servers/databases', 'microsoft.dbformysql/servers', 'microsoft.dbformysql/flexibleservers'), \"Not Applicable\",\n (type == 'microsoft.documentdb/databaseaccounts' and properties.enableMultipleWriteLocations == \"false\"), \"Not Enabled\",\n (type == 'microsoft.documentdb/databaseaccounts' and properties.enableMultipleWriteLocations == \"true\"), \"Enabled\",\n (type == 'microsoft.cache/redis'), 'Not Applicable',\n (type == \"microsoft.apimanagement/service\"), \"Not Applicable\",\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n (type contains \"storageaccounts\"), \"Not Applicable\",\n (type == \"microsoft.network/azurefirewalls\"), \"Not Applicable\",\n (type == \"microsoft.network/frontdoors\"), \"Not Applicable\",\n (type == \"microsoft.cdn/profiles\"), \"Not Applicable\",\n (type == \"microsoft.network/applicationgateways\"), \"Not Applicable\",\n (type == \"microsoft.network/loadbalancers\"), \"Not Applicable\",\n (type contains \"publicip\"), \"Not Applicable\",\n (type == \"microsoft.network/virtualnetworkgateways\"), \"Not Applicable\",\n (type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Undefined\"\n )\n| extend StorageAutogrow = case(\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters', 'microsoft.sql/servers/databases', 'microsoft.documentdb/databaseaccounts'), \"Not Applicable\",\n (type == 'microsoft.dbformysql/servers'), tostring(properties.storageProfile.storageAutogrow),\n (type == 'microsoft.dbformysql/flexibleservers'), \"Not Applicable\",\n (type == 'microsoft.cache/redis'), 'Not Applicable',\n (type == \"microsoft.apimanagement/service\"), \"Not Applicable\",\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n (type contains \"storageaccounts\"), \"Not Applicable\",\n (type == \"microsoft.network/azurefirewalls\"), \"Not Applicable\",\n (type == \"microsoft.network/frontdoors\"), \"Not Applicable\",\n (type == \"microsoft.cdn/profiles\"), \"Not Applicable\",\n (type == \"microsoft.network/applicationgateways\"), \"Not Applicable\",\n (type == \"microsoft.network/loadbalancers\"), \"Not Applicable\",\n (type contains \"publicip\"), \"Not Applicable\",\n (type == \"microsoft.network/virtualnetworkgateways\"), \"Not Applicable\",\n (type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Undefined\"\n )\n| extend ReplicationRole = case(\n type in ('microsoft.compute/virtualmachines', 'microsoft.classiccompute/virtualmachines', 'microsoft.compute/virtualmachinescalesets', 'microsoft.web/sites', 'microsoft.web/serverfarms', 'microsoft.containerservice/managedclusters', 'microsoft.documentdb/databaseaccounts'), \"Not Applicable\",\n (type == 'microsoft.sql/servers/databases' and sku.tier <> 'DataWarehouse'), iif(isnotempty(properties.secondaryType), \"replica\", \"master\"),\n (type == 'microsoft.sql/servers/databases' and sku.tier == 'DataWarehouse'), \"Not Applicable\",\n (type == 'microsoft.dbformysql/servers'), tostring(properties.replicationRole),\n (type == 'microsoft.dbformysql/flexibleservers'), iif(properties.haEnabled == \"Enabled\", 'Not Applicable', tostring(properties.replicationRole)),\n (type == 'microsoft.cache/redis'), 'Not Applicable',\n (type == \"microsoft.apimanagement/service\"), \"Not Applicable\",\n (type == \"microsoft.servicebus/namespaces\"), \"Not Applicable\",\n (type contains \"storageaccounts\"), tostring(split(skuName, '_', 1)[0]),\n (type == \"microsoft.network/azurefirewalls\"), \"Not Applicable\",\n (type == \"microsoft.network/frontdoors\"), \"Not Applicable\",\n (type == \"microsoft.cdn/profiles\"), \"Not Applicable\",\n (type == \"microsoft.network/applicationgateways\"), \"Not Applicable\",\n (type == \"microsoft.network/loadbalancers\"), \"Not Applicable\",\n (type contains \"publicip\"), \"Not Applicable\",\n (type == \"microsoft.network/virtualnetworkgateways\"), \"Not Applicable\",\n (type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Undefined\"\n )\n| project \n Type = tolower(type),\n SkuName = tolower(skuName),\n Kind = tolower(kind),\n SubscriptionId = subscriptionId,\n Name = tolower(tostring(id)),\n State = tolower(state),\n Location = tolower(location),\n ResourceGroup = resourceGroup,\n Zones = tolower(tostring(zones)),\n AvailabilityZone = tolower(avZones),\n AvailabilitySet = tolower(avSets),\n Capacity = tolower(Capacity),\n FaultDomain = tolower(FaultDomain),\n OSDisk = tolower(OSDisk),\n ReadReplica = tolower(ReadReplica), \n AutomaticFailover = tolower(AutomaticFailover),\n MultipleWriteLocations = tolower(MultipleWriteLocations),\n StorageAutogrow = tolower(StorageAutogrow),\n ReplicationRole = tolower(ReplicationRole),\n Environment = environment,\n properties\n| join kind = leftouter (\n recoveryservicesresources\n | where name startswith \"VM;\"\n | project Name = tolower(tostring(properties.dataSourceInfo.resourceID)), Backup = tostring(properties.protectionStatus)\n )\n on Name\n| extend Backup = case(\n Backup == \"Healthy\" or Backup == \"Unhealthy\", Backup,\n \"Unknown\")\n| extend Backup = case(\n (Type == 'microsoft.compute/virtualmachines'), iif(Backup == \"Unknown\", \"Not Configured\", Backup),\n (Type == 'microsoft.classiccompute/virtualmachines'), iif(Backup == \"Unknown\", \"Not Configured\", Backup),\n (Type == \"microsoft.compute/virtualmachinescalesets\"), \"Not Applicable\", \n (Type == \"microsoft.containerservice/managedclusters\"), \"Not Applicable\",\n (Type == 'microsoft.sql/servers/databases'), \"Not Applicable\", \n (Type == 'microsoft.documentdb/databaseaccounts'), iif(properties.backupPolicy.periodicModeProperties.backupStorageRedundancy == \"Geo\", \"Healthy\", \"Unhealthy\"),\n (Type == 'microsoft.dbformysql/servers'), iif(properties.storageProfile.geoRedundantBackup == \"Enabled\", \"Healthy\", \"Unhealthy\"),\n (Type contains \"storageaccounts\"), \"Not Applicable\",\n (Type == \"microsoft.network/azurefirewalls\"), \"Not Applicable\",\n (Type == \"microsoft.recoveryservices/vaults\"), \"Not Applicable\",\n \"Unknown\"\n )\n| project Type, SkuName, Kind, SubscriptionId, Name, State, Location, ResourceGroup, AvailabilityZone, Zones=AvailabilitySet, Capacity, MinTLSVersion=FaultDomain, Environment\n| where Type == 'microsoft.servicebus/namespaces'", + "size": 3, + "title": "Service Bus", + "showExportToExcel": true, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscriptions}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "$gen_group", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Type", + "formatter": 5 + }, + { + "columnMatch": "SkuName", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "developer", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "basic", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "standard", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "premium", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "isolated", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Kind", + "formatter": 5 + }, + { + "columnMatch": "SubscriptionId", + "formatter": 5 + }, + { + "columnMatch": "Name", + "formatter": 5 + }, + { + "columnMatch": "State", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "succeeded", + "representation": "green", + "text": "{0}{1}" + }, + { + "operator": "!=", + "thresholdValue": "succeeded", + "representation": "orange", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Location", + "formatter": 17 + }, + { + "columnMatch": "AvailabilityZone", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "not configured", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "not applicable", + "representation": "more", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "configured", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "undefined", + "representation": "unknown", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "more", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Zones", + "formatter": 5 + }, + { + "columnMatch": "Capacity", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": ">", + "thresholdValue": "1", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "MinTLSVersion", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1.2", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "!=", + "thresholdValue": "1.2", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "more", + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "Environment", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "colors", + "thresholdsGrid": [ + { + "operator": "contains", + "thresholdValue": "Prod", + "representation": "redBright", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "prod", + "representation": "redBright", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "text": "{0}{1}" + } + ] + } + }, + { + "columnMatch": "OSDisk", + "formatter": 5 + }, + { + "columnMatch": "ReadReplica", + "formatter": 5 + }, + { + "columnMatch": "AutomaticFailover", + "formatter": 5 + }, + { + "columnMatch": "MultipleWriteLocations", + "formatter": 5 + }, + { + "columnMatch": "StorageAutogrow", + "formatter": 5 + }, + { + "columnMatch": "ReplicationRole", + "formatter": 5 + }, + { + "columnMatch": "Backup", + "formatter": 5 + }, + { + "columnMatch": "SubscriptionName", + "formatter": 5 + }, + { + "columnMatch": "Tier", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "Premium", + "representation": "success", + "text": "{0}{1}" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "2", + "text": "{0}{1}" + } + ] + } + } + ], + "hierarchySettings": { + "treeType": 1, + "groupBy": [ + "SubscriptionId" + ], + "expandTopLevel": false, + "finalBy": "Name" + }, + "labelSettings": [ + { + "columnId": "SkuName", + "label": "SKU" + }, + { + "columnId": "SubscriptionId", + "label": "Subscription" + }, + { + "columnId": "ResourceGroup", + "label": "Resource Group" + } + ] + }, + "sortBy": [] + }, + "name": "kql_integration_servicebus_resources_details" + } + ] + }, + "conditionalVisibility": { + "parameterName": "selectedTab", + "comparison": "isEqualTo", + "value": "ServiceBus" + }, + "name": "Service Bus" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ { "type": 1, "content": { @@ -507,4 +1086,21 @@ "name": "kql_integration_apim_resources_details" } ] + }, + "conditionalVisibility": { + "parameterName": "selectedTab", + "comparison": "isEqualTo", + "value": "APIM" + }, + "name": "API Management" + } + ] + }, + "name": "Integration" + } + ], + "fallbackResourceIds": [ + "Azure Monitor" + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" } \ No newline at end of file From 495e976a8845832473de413747585c16ee9c16d8 Mon Sep 17 00:00:00 2001 From: Tsubasa Nomura Date: Tue, 21 May 2024 12:02:18 +0900 Subject: [PATCH 2/7] Add Service Bus part --- build/template_kql/common/summarize_score.kql | 3 ++- .../integration_servicebus_resources_details.kql | 4 ++-- .../integration_servicebus_resources_details_summary.kql | 9 ++++----- ...summary_reliability_score_by_resource_environment.kql | 2 +- .../summary/summary_workbook_reliability_score.kql | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/template_kql/common/summarize_score.kql b/build/template_kql/common/summarize_score.kql index 3f45362..ee831a6 100644 --- a/build/template_kql/common/summarize_score.kql +++ b/build/template_kql/common/summarize_score.kql @@ -84,4 +84,5 @@ summarize NAGen2VnetGwCount=dcountif(Name, OSDisk == "none" and Type == 'microsoft.network/virtualnetworkgateways'), ActiveActiveVnetGwCount=dcountif(Name, ReadReplica == "true" and Type == 'microsoft.network/virtualnetworkgateways'), NAActiveActiveVnetGwCount=dcountif(Name, ReadReplica == "not applicable" and Type == 'microsoft.network/virtualnetworkgateways'), - Stv2ApimCount=dcountif(Name, OSDisk == "stv2" and Type == 'microsoft.apimanagement/service') + Stv2ApimCount=dcountif(Name, OSDisk == "stv2" and Type == 'microsoft.apimanagement/service'), + NoMeetMinTLSVersion=dcountif(Name, todouble(MinTLSVersion) < 1.2) diff --git a/build/template_kql/integration/integration_servicebus_resources_details.kql b/build/template_kql/integration/integration_servicebus_resources_details.kql index 2bb9f4f..5dd686a 100644 --- a/build/template_kql/integration/integration_servicebus_resources_details.kql +++ b/build/template_kql/integration/integration_servicebus_resources_details.kql @@ -1,3 +1,3 @@ ${extend_resource} -| project Type, SkuName, Kind, SubscriptionId, Name, State, Location, ResourceGroup, AvailabilityZone, Zones=AvailabilitySet, Capacity, MinTLSVersion=FaultDomain, Environment -| where Type == 'microsoft.servicebus/namespaces' \ No newline at end of file +| project Type, SkuName, Kind, SubscriptionId, Name, State, Location, ResourceGroup, AvailabilityZone, toint(Capacity), MinTLSVersion, Environment +| where Type == 'microsoft.servicebus/namespaces' diff --git a/build/template_kql/integration/integration_servicebus_resources_details_summary.kql b/build/template_kql/integration/integration_servicebus_resources_details_summary.kql index db6682d..77a9ea3 100644 --- a/build/template_kql/integration/integration_servicebus_resources_details_summary.kql +++ b/build/template_kql/integration/integration_servicebus_resources_details_summary.kql @@ -1,6 +1,5 @@ ${extend_resource} -| project type,zones, sku=sku.name, sku.capacity, properties.provisioningState, properties.publicNetworkAccess, -properties.status,properties.minimumTlsVersion,properties.zoneRedundant,properties.disableLocalAuth,properties.serviceBusEndpoint,GeoRedundant=properties.privateEndpointConnections -| where type =='microsoft.servicebus/namespaces' -| summarize ResourceTotal=count(Name), NotPremium=dcountif(Name, SkuName!= "Premium"), NoMultipleZones=dcountif(Name, Zones != "null"), NotSucceeded=dcountif(Name, State != "Succeeded") -,NoAVZone=dcountif(Name, AvailabilityZone==false),NoMinimumTLSVersion=dcountif(Name,MinTLSVersion!=1.2), CapacityNotConfigured=dcountif(Name, Capacity=="Not configured") \ No newline at end of file +| project Type, Name, Zones, SkuName, State, AvailabilityZone, MinTLSVersion, Capacity +| where Type =='microsoft.servicebus/namespaces' +| summarize ResourceTotal=count(Name), NotSucceeded=dcountif(Name, State != "succeeded"), NotPremium=dcountif(Name, SkuName!= "premium"), NoMultipleZones=dcountif(Name, AvailabilityZone == "not configured") +,NoMinimumTLSVersion=dcountif(Name,todouble(MinTLSVersion)<1.2), CapacityNotConfigured=dcountif(Name, toint(Capacity)<2) diff --git a/build/template_kql/summary/summary_reliability_score_by_resource_environment.kql b/build/template_kql/summary/summary_reliability_score_by_resource_environment.kql index 166513d..d057045 100644 --- a/build/template_kql/summary/summary_reliability_score_by_resource_environment.kql +++ b/build/template_kql/summary/summary_reliability_score_by_resource_environment.kql @@ -1,5 +1,5 @@ ${extend_resource} -| project Type, SkuName, Kind, SubscriptionId, Name, State, Location, ResourceGroup, Zones, AvailabilityZone, AvailabilitySet, Capacity, FaultDomain, OSDisk, ReadReplica, AutomaticFailover, MultipleWriteLocations, StorageAutogrow, ReplicationRole, Backup = tolower(Backup), Environment, +| project Type, SkuName, Kind, SubscriptionId, Name, State, Location, ResourceGroup, Zones, AvailabilityZone, AvailabilitySet, Capacity, FaultDomain, OSDisk, ReadReplica, AutomaticFailover, MultipleWriteLocations, StorageAutogrow, ReplicationRole, Backup = tolower(Backup), MinTLSVersion, Environment, vmId, replicationHealth, failoverHealth, protectionStateDescription, isReplicationAgentUpdateRequired // This is for calculating the score for ASRs | ${summarize_score} by Name, Type, Environment diff --git a/build/template_kql/summary/summary_workbook_reliability_score.kql b/build/template_kql/summary/summary_workbook_reliability_score.kql index a8356a8..0f87234 100644 --- a/build/template_kql/summary/summary_workbook_reliability_score.kql +++ b/build/template_kql/summary/summary_workbook_reliability_score.kql @@ -1,5 +1,5 @@ ${extend_resource} -| project Type, SkuName, Kind, SubscriptionId, Name, State, Location, ResourceGroup, Zones, AvailabilityZone, AvailabilitySet, Capacity, FaultDomain, OSDisk, ReadReplica, AutomaticFailover, MultipleWriteLocations, StorageAutogrow, ReplicationRole, Backup = tolower(Backup), Environment, +| project Type, SkuName, Kind, SubscriptionId, Name, State, Location, ResourceGroup, Zones, AvailabilityZone, AvailabilitySet, Capacity, FaultDomain, OSDisk, ReadReplica, AutomaticFailover, MultipleWriteLocations, StorageAutogrow, ReplicationRole, Backup = tolower(Backup), MinTLSVersion, Environment, vmId, replicationHealth, failoverHealth, protectionStateDescription, isReplicationAgentUpdateRequired // This is for calculating the score for ASRs | ${summarize_score} by Type, Environment From a59f075da1242420ab9302339703fdaaaba6ce8e Mon Sep 17 00:00:00 2001 From: Tsubasa Nomura Date: Tue, 21 May 2024 15:24:09 +0900 Subject: [PATCH 3/7] Updated calculation score for Service Bus --- build/template_kql/common/calculate_score.kql | 2 ++ build/template_kql/common/summarize_score.kql | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/build/template_kql/common/calculate_score.kql b/build/template_kql/common/calculate_score.kql index 310c604..9c05891 100644 --- a/build/template_kql/common/calculate_score.kql +++ b/build/template_kql/common/calculate_score.kql @@ -45,4 +45,6 @@ extend ReliabilityScore = case( // ASRs contain multiple VM resources that are configured for replication and therefore maintain status in each of them. If none of the VMs are replicated, both the OK status and the NG status will be null. This means that if the OK status is calculated in the same way as other resources, by adding the OK statuses, the score will be zero. // So, for ASR, if even one VM has an NG status, that status is treated as 0 and the score is calculated by subtracting the status of that status from 1. Type == 'microsoft.recoveryservices/vaults', ((1-NoAsrSucceededState) + (1-NoAsrSucceededReplHealth) + (1-NoAsrSucceededFailoverHealth) + (1-NoAsrSucceededProtectionStateDesc) + (1-NoAsrSucceededReplicationAgentUpdate)) * 100 / (5 * UniqueResourceTotal), + // Service Bus - 5 checks // score = (Failed Status + Non-Premium SKU + No Availability Zone + Outdated TLS version + Capacity < 2) + Type == 'microsoft.servicebus/namespaces', (SucceededStateCount + PremiumSkuCount + AvZoneCount + NAAvZoneCount + MeetMinTLSVersionCount + Gt1CapacityCount) * 100 / (5 * ResourceTotal), 0) diff --git a/build/template_kql/common/summarize_score.kql b/build/template_kql/common/summarize_score.kql index ee831a6..41f66a6 100644 --- a/build/template_kql/common/summarize_score.kql +++ b/build/template_kql/common/summarize_score.kql @@ -85,4 +85,5 @@ summarize ActiveActiveVnetGwCount=dcountif(Name, ReadReplica == "true" and Type == 'microsoft.network/virtualnetworkgateways'), NAActiveActiveVnetGwCount=dcountif(Name, ReadReplica == "not applicable" and Type == 'microsoft.network/virtualnetworkgateways'), Stv2ApimCount=dcountif(Name, OSDisk == "stv2" and Type == 'microsoft.apimanagement/service'), - NoMeetMinTLSVersion=dcountif(Name, todouble(MinTLSVersion) < 1.2) + MeetMinTLSVersionCount=dcountif(Name, todouble(MinTLSVersion) >= 1.2), + NoMeetMinTLSVersionCount=dcountif(Name, todouble(MinTLSVersion) < 1.2) From 26b23766a0915a10acd1bb65b426d9fdfd897ce8 Mon Sep 17 00:00:00 2001 From: Tsubasa Nomura Date: Tue, 21 May 2024 23:33:16 +0900 Subject: [PATCH 4/7] Minor fix --- build/template_kql/common/extend_resource.kql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/template_kql/common/extend_resource.kql b/build/template_kql/common/extend_resource.kql index fcaadf2..987060a 100644 --- a/build/template_kql/common/extend_resource.kql +++ b/build/template_kql/common/extend_resource.kql @@ -170,7 +170,7 @@ on id ), (type == 'microsoft.cache/redis'), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'), (type == "microsoft.apimanagement/service"), coalesce(tostring(array_length(parse_json(zones))), 'Not Configured'), - (type == 'microsoft.servicebus/namespaces'), iff(properties.zoneRedundant == 'true', 'Configured', 'Not Configured'), + (type == 'microsoft.servicebus/namespaces'), iff(properties.zoneRedundant == 'true', 'Configured', 'Not Configured'), (type contains 'storageaccounts'), case(split(skuName, '_', 1)[0] contains "zrs", "Configured", "Not Configured"), (type == "microsoft.network/azurefirewalls"), iif(isnotnull(zones), "Configured", "Not Configured"), (type == "microsoft.network/frontdoors"), "Not Applicable", @@ -211,7 +211,7 @@ on id type == 'microsoft.dbforpostgresql/flexibleservers', "Not Applicable", type == 'microsoft.cache/redis', "Not Applicable", type == "microsoft.apimanagement/service", "Not Applicable", - type == "microsoft.servicebus/namespaces",tostring(iif(isempty(sku.capacity), "Not Applicable", sku.capacity)), + type == "microsoft.servicebus/namespaces", "Not Applicable", type contains "storageaccounts", "Not Applicable", type == "microsoft.network/azurefirewalls", "Not Applicable", type == "microsoft.network/frontdoors", "Not Applicable", From f92b962b730cf24c595d1d2f0a8abe0cb1863d83 Mon Sep 17 00:00:00 2001 From: Tsubasa Nomura Date: Sat, 25 May 2024 03:34:36 +0000 Subject: [PATCH 5/7] Fixed #154 --- build/templates/databases.tpl.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build/templates/databases.tpl.json b/build/templates/databases.tpl.json index 8d66cee..b120327 100644 --- a/build/templates/databases.tpl.json +++ b/build/templates/databases.tpl.json @@ -3788,11 +3788,6 @@ "json": "Important\r\n\r\n* Azure Database for PostgreSQL - Single Server is on the retirement path. We strongly recommend for you to upgrade to Azure Database for PostgreSQL - Flexible Server. \r\n\r\n> For more information about migrating to Azure Database for PostgreSQL - Flexible Server, see [What's happening to Azure Database for PostgreSQL Single Server](https://learn.microsoft.com/en-us/azure/postgresql/single-server/whats-happening-to-postgresql-single-server)?", "style": "warning" }, - "conditionalVisibility": { - "parameterName": "Help", - "comparison": "isEqualTo", - "value": "Yes" - }, "name": "postgresql-single-retirement" }, { From 9b0ad3585a10acb034a0109822b3c34fa42f81f1 Mon Sep 17 00:00:00 2001 From: Tsubasa Nomura Date: Mon, 27 May 2024 08:29:31 +0000 Subject: [PATCH 6/7] chore: Update compute template to use redBright representation for stopped VMs Fixed #140 --- build/templates/compute.tpl.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build/templates/compute.tpl.json b/build/templates/compute.tpl.json index 33d0efc..aa1d038 100644 --- a/build/templates/compute.tpl.json +++ b/build/templates/compute.tpl.json @@ -351,13 +351,14 @@ }, { "operator": "==", - "thresholdValue": "vm deallocated", - "representation": "gray", + "thresholdValue": "vm stopped", + "representation": "redBright", "text": "{0}{1}" }, { "operator": "Default", "thresholdValue": null, + "representation": "gray", "text": "{0}{1}" } ] From 04e33fa428813637fd163171c92a788feef96f24 Mon Sep 17 00:00:00 2001 From: Tsubasa Nomura Date: Mon, 27 May 2024 09:45:14 +0000 Subject: [PATCH 7/7] Fix #151 --- build/templates/databases.tpl.json | 178 ++++++++++++++--------------- 1 file changed, 88 insertions(+), 90 deletions(-) diff --git a/build/templates/databases.tpl.json b/build/templates/databases.tpl.json index b120327..0e23719 100644 --- a/build/templates/databases.tpl.json +++ b/build/templates/databases.tpl.json @@ -3499,50 +3499,31 @@ "showIcon": true } }, - { - "columnMatch": "Subscription", - "formatter": 13, - "formatOptions": { - "linkTarget": "Resource", - "showIcon": true - } - }, { "columnMatch": "Type", "formatter": 5 }, - - { - "columnMatch": "SubscriptionId", - "formatter": 5 - }, - { - "columnMatch": "Name", - "formatter": 5 - }, - { - "columnMatch": "location", - "formatter": 17 - }, - { - "columnMatch": "Zones", - "formatter": 5 - }, { - "columnMatch": "Status", + "columnMatch": "SkuName", "formatter": 18, "formatOptions": { "thresholdsOptions": "colors", "thresholdsGrid": [ { - "operator": "contains", - "thresholdValue": "Stopped", + "operator": "==", + "thresholdValue": "burstable", "representation": "orange", "text": "{0}{1}" }, { - "operator": "contains", - "thresholdValue": "Available", + "operator": "==", + "thresholdValue": "memoryoptimized", + "representation": "green", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "generalpurpose", "representation": "green", "text": "{0}{1}" }, @@ -3554,6 +3535,14 @@ ] } }, + { + "columnMatch": "SubscriptionId", + "formatter": 5 + }, + { + "columnMatch": "Name", + "formatter": 5 + }, { "columnMatch": "State", "formatter": 18, @@ -3582,27 +3571,35 @@ } }, { - "columnMatch": "SkuName", + "columnMatch": "Location", + "formatter": 17 + }, + { + "columnMatch": "Zones", + "formatter": 5 + }, + { + "columnMatch": "AvailabilityZone", "formatter": 18, "formatOptions": { - "thresholdsOptions": "colors", + "thresholdsOptions": "icons", "thresholdsGrid": [ { "operator": "==", - "thresholdValue": "burstable", - "representation": "orange", + "thresholdValue": "not applicable", + "representation": "more", "text": "{0}{1}" }, { "operator": "==", - "thresholdValue": "memoryoptimized", - "representation": "green", - "text": "{0}{1}" + "thresholdValue": "not configured", + "representation": "2", + "text": "not configured" }, { "operator": "==", - "thresholdValue": "generalpurpose", - "representation": "green", + "thresholdValue": "configured", + "representation": "success", "text": "{0}{1}" }, { @@ -3614,53 +3611,66 @@ } }, { - "columnMatch": "AvailabilityZone", + "columnMatch": "AutomaticFailover", "formatter": 18, "formatOptions": { "thresholdsOptions": "icons", "thresholdsGrid": [ { "operator": "==", - "thresholdValue": "not applicable", - "representation": "more", + "thresholdValue": "not configured", + "representation": "2", "text": "{0}{1}" }, { "operator": "==", - "thresholdValue": "not configured", - "representation": "2", - "text": "not configured" + "thresholdValue": "same zone", + "representation": "success", + "text": "{0}{1}" }, { "operator": "==", - "thresholdValue": "configured", + "thresholdValue": "not applicable", + "representation": "more", + "text": "{0}{1}" + }, + { + "operator": "==", + "thresholdValue": "zone redundant", "representation": "success", "text": "{0}{1}" }, { "operator": "Default", "thresholdValue": null, + "representation": null, "text": "{0}{1}" } ] } }, { - "columnMatch": "Environment", + "columnMatch": "GeoBackup", "formatter": 18, "formatOptions": { - "thresholdsOptions": "colors", + "thresholdsOptions": "icons", "thresholdsGrid": [ { "operator": "contains", - "thresholdValue": "prod", - "representation": "redBright", + "thresholdValue": "enabled", + "representation": "success", "text": "{0}{1}" }, { "operator": "contains", - "thresholdValue": "Prod", - "representation": "redBright", + "thresholdValue": "disabled", + "representation": "2", + "text": "{0}{1}" + }, + { + "operator": "contains", + "thresholdValue": "not applicable", + "representation": "more", "text": "{0}{1}" }, { @@ -3672,66 +3682,55 @@ } }, { - "columnMatch": "AutomaticFailover", + "columnMatch": "Environment", "formatter": 18, "formatOptions": { - "thresholdsOptions": "icons", + "thresholdsOptions": "colors", "thresholdsGrid": [ { - "operator": "==", - "thresholdValue": "not configured", - "representation": "2", - "text": "{0}{1}" - }, - { - "operator": "==", - "thresholdValue": "same zone", - "representation": "success", - "text": "{0}{1}" - }, - { - "operator": "==", - "thresholdValue": "not applicable", - "representation": "more", + "operator": "contains", + "thresholdValue": "prod", + "representation": "redBright", "text": "{0}{1}" }, { - "operator": "==", - "thresholdValue": "zone redundant", - "representation": "success", + "operator": "contains", + "thresholdValue": "Prod", + "representation": "redBright", "text": "{0}{1}" }, { "operator": "Default", "thresholdValue": null, - "representation": null, "text": "{0}{1}" } ] } }, { - "columnMatch": "GeoBackup", + "columnMatch": "Subscription", + "formatter": 13, + "formatOptions": { + "linkTarget": "Resource", + "showIcon": true + } + }, + { + "columnMatch": "Status", "formatter": 18, "formatOptions": { - "thresholdsOptions": "icons", + "thresholdsOptions": "colors", "thresholdsGrid": [ { "operator": "contains", - "thresholdValue": "enabled", - "representation": "success", - "text": "{0}{1}" - }, - { - "operator": "contains", - "thresholdValue": "disabled", - "representation": "2", + "thresholdValue": "Stopped", + "representation": "orange", "text": "{0}{1}" }, { "operator": "contains", - "thresholdValue": "not applicable", - "representation": "more", + "thresholdValue": "Available", + "representation": "green", "text": "{0}{1}" }, { @@ -3760,6 +3759,10 @@ "columnId": "SubscriptionId", "label": "Subscription" }, + { + "columnId": "State", + "label": "Status" + }, { "columnId": "ResourceGroup", "label": "Resource Group" @@ -3768,15 +3771,10 @@ "columnId": "AutomaticFailover", "label": "High Availability" }, - { - "columnId": "State", - "label": "Status" - }, { "columnId": "ReplicationRole", "label": "Replication Role" } - ] } },