[Open data] Azure Advisor recommendation types
Are you submitting your tool or someone else's?
I'm submitting a tool that I own.
Tool ownership responsibilities (only applicable to tool owners)
- [x] I acknowledge the responsibilities of a technical lead and agree to serve in this role for the proposed tool upon its approval.
Tool name
RecommendationTypes.csv
Description
Azure Advisor doesn't expose details about the different recommendations that are available. We should include a new open data file that includes the recommendation type details to describe each recommendation made available in Azure Advisor.
Use case
Organize and provide additional context for Azure Advisor recommendations.
Services used
None
Dependencies
This information can be parsed out of Microsoft Learn docs in GitHub via a PowerShell script. There are no runtime dependencies.
Partial sample from the generated file (6 columns removed):
| RecommendationTypeId | Category | Impact | ServiceName | ResourceType | Key | Message | Version | LearnMoreLink |
|---|---|---|---|---|---|---|---|---|
| a06456ed-afb7-4d16-86fd-0054e25268ed | Performance | Medium | Virtual Machines | microsoft.compute/virtualmachines | AccelNetDisengaged | Enable Accelerated Networking to improve network performance and latency | 2.1 | https://docs.microsoft.com/azure/virtual-network/create-vm-accelerated-networking-cli#enable-accelerated-networking-on-existing-vms |
| 9c0c3708-17f6-4108-9aff-f0e052c3cd41 | OperationalExcellence | Low | Azure App Service | microsoft.subscriptions/subscriptions | AzureApplicationService | Eliminate replica staging environments and ship new versions and features with zero downtime using deployment slots | 1.0 | https://docs.microsoft.com/azure/app-service/deploy-staging-slots |
| a205074f-8049-48b3-903f-556f5e530ae3 | Cost | High | ReservedInstances | microsoft.subscriptions/subscriptions | CosmosDBReservedCapacity | Buy reserved instance | 9.1 | https://aka.ms/rirecommendations |
| 94aea435-ef39-493f-a547-8408092c22a7 | Cost | High | Virtual Machine Scale Sets | microsoft.compute/virtualmachinescalesets | LowUsageVmss | Shut down or resize your virtual machine scale sets | 9.9 | https://aka.ms/aa_lowusagerec_vmss_learnmore |
| afdf4c1a-e46b-4817-a5d6-4b9909f58e2a | Cost | Low | Azure Synapse Analytics | microsoft.synapse/workspaces | EnableSynapseSparkComputeAutoPauseGuidance | Consider enabling automatic pause feature on spark compute | 3.1 | https://aka.ms/EnableSynapseSparkComputeAutoPauseGuidance |
| ed651749-cd37-4fd5-9897-01b416926745 | HighAvailability | Medium | Site Recovery | microsoft.compute/virtualmachines | ASRUnprotectedVMs | Enable virtual machine replication | 7 | https://aka.ms/azure-site-recovery-dr-azure-vms |
@arthurclares / @helderpinto / @nteyan, I figure y'all have spent the most time looking at the Advisor recommendations. I was thinking about adding more context to our Power BI report and wasn't able to find this level of detail. I haven't fully thought thru how we'd use it but I figure y'all are the best to review the proposal. Let me know if you have any questions.
I don't think we have a central pace for these recommendations, so having this file seems to be a good idea. Hwoever, from a Hub perspective, we could simply have an ARG query that would surface these recommendations and then add it to the dashboards, wouldn't that be easier? Actually, if I'm not mistaken, Helder has done this already.
@flanakin, I didn't find any GitHub docs reference where we could parse all the recommendation types columns. Can you share the source where you got the sample table from?
The metadata Azure Advisor REST API endpoint would probably be the best source of truth for this information. However, it does not contain data for the recommendation version nor the learn more link.
Alternatively, we could use Azure Resource Graph, but it only contains metadata for recommendations that have been generated in the context of the customer, which is only a subset of all possible recommendation types.
I didn't find any GitHub docs reference where we could parse all the recommendation types columns. Can you share the source where you got the sample table from?
@helderpinto We talked about this, but sharing with others: I found the details in the MicrosoftDocs/SelfHelpContent repo. I believe the repo is private to FTEs only. This repo has self-help guidance for every Azure service used in the Azure portal.
The metadata Azure Advisor REST API endpoint would probably be the best source of truth for this information. However, it does not contain data for the recommendation version nor the learn more link.
I wasn't aware of the RecommendationMetadata API. I would agree that would be a better source for the core details. We can merge the self-help content as well.
Alternatively, we could use Azure Resource Graph, but it only contains metadata for recommendations that have been generated in the context of the customer, which is only a subset of all possible recommendation types.
This works for Power BI, but not ADX dashboards.
The question is, do we see value in providing a CSV dataset that we can ingest into Power BI and Data Explorer to improve our reports and dashboards? Power BI can call the current API, but not the self-help guidance, but I'm not sure I'd do this for the self-help guidance only. I don't know if ADX dashboards can call ARM APIs.
I see the value, use case, we're consuming advisor recommendations from Graph, into our Recomendations_Final_v1_0, I find it useful to track the values of Recommendations over time.
mapping, parsing the typeIDs into some semblance of Focus Formatting is what we're doing, but it would be nice to have a Consolidated CSV or Json with all of the Fields defined.
graph {"query": "advisorresources | where type == 'microsoft.advisor/recommendations' | where properties.category == 'Cost' | project id, tenantId, subscriptionId, properties, ['date'] = startofday(now()) "} -> daily_cost_recommendations_raw
then functions to move it into Recommendations_final_v1_0 example for orphaned disks which doesnt' have an advisor calculated Cost savings
.create function with (docstring = 'Returns daily cost recommendations for orphaned disks', folder = 'AdvisorRecommendations') daily_cost_recommendations_orphanedDisks { daily_cost_recommendations_raw | where ['date'] == startofday(now()) | extend x_properties = parse_json(properties) | extend RecommendationTypeID = tostring(x_properties.recommendationTypeId) | where RecommendationTypeID == '48eda464-1485-4dcf-a674-d0905df5054a' | extend resourceId = tostring(x_properties.resourceMetadata.resourceId) | extend ProviderName = 'Microsoft' | extend SubAccountId = strcat('/subscriptions/', subscriptionId) | extend x_ingestionTime = now() | extend x_RecommendationDate = ['date'] | extend x_RecommendationDetails = x_properties | extend x_SourceName = 'Advisor' | extend x_SourceProvider = 'Microsoft' | extend x_SourceVersion = '2025-08-15' | extend lowID = tolower(resourceId) | extend x_SourceType = 'OrphanedDiskRecommendations' | join ( Costs_final_v1_0 | where ChargePeriodStart == datetime_add('day', -1, startofday(now())) | extend lowID = tolower(ResourceId) | summarize x_EffectiveCostBefore = todecimal(sum(EffectiveCost) * 365.25) by lowID ) on lowID | extend x_EffectiveCostAfter = todecimal(0) | extend x_EffectiveCostSavings = todecimal(x_EffectiveCostBefore) | project ProviderName, SubAccountId, x_ingestionTime, x_EffectiveCostAfter, x_EffectiveCostBefore, x_EffectiveCostSavings, x_RecommendationDate, x_RecommendationDetails, x_SourceName, x_SourceProvider, x_SourceType, x_SourceVersion }