FinOps et Azure Graph


Azure, Cloud, FinOps, Scripting / mardi, mars 16th, 2021

En 2020, les données d’Azure Advisor sont devenues disponibles dans Azure Resource Graph. Mais, il n’est possible d’examiner les recommandations que pour un maximum de 60 abonnements à la fois en raison des limitations du portail Azure. Si vous avez plus de 60 abonnements Azure, il vous passer par Azure Graph.

J’ai donc créé un script qui permet de collecter via Azure Graph les informations suivantes par onglet (avec le nom des ressources, souscription, savings, …) :

  • AzureRI: Liste des instances à passer en RI
  • Diskunattached: l’ensemble des disques non attaché à une VM
  • Mysqlcapacity: les instances MySQL à passer en RI
  • PostgreSQL: les instances PSQL à passer en RI
  • Rightsizing: les VMs à resizer avec les ratio CPU/MEM
  • SQLcapacity: les instances SQL à passer en RI
  • SQLhb: les instances SQL en fonction du type de licences (utile pour l’Hybrid Benefit)
  • StoppedVM: Les VMs éteintes
  • VM: Les tailles de VMs, avec le type de licence (utile pour l’Hybrid Benefit), faites un TOP 10 pour voir vos plus gros SKU
  • VMscaleset: La liste dans VM scaleset, y compris AKS

Voici le script Powershell:

Write-Host "Lancement des queries Azure FinOps"
search-azgraph -query "resources | where type startswith 'microsoft.sql' | project name, type, sku.name, sku.tier, properties.licenseType, properties.sqlImageOffer, properties.sqlImageSku, properties.sqlServerLicenseType, location, resourceGroup, subscriptionId" -first 5000 | Export-Csv -Path .\sqlHB.csv -NoTypeInformation
Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualMachines' | project name, properties.hardwareProfile.vmSize, properties.storageProfile.osDisk.osType,properties.storageProfile.imageReference.offer,properties.storageProfile.imageReference.sku,properties.licenseType, properties.host.id,properties.extended.instanceView.powerState.displayStatus" -first 5000 | Export-Csv -Path .\vm.csv -NoTypeInformation
Search-AzGraph -Query "Resources | where type == 'microsoft.compute/virtualmachinescalesets' | project name, sku.name, sku.capacity, properties.storageProfile.osDisk.osType,  properties.virtualMachineProfile.storageProfile.imageReference.offer, properties.virtualMachineProfile.storageProfile.imageReference.sku,properties.virtualMachineProfile.licenseType, properties.hostGroup.id" -first 5000 | Export-Csv -Path .\vmscaleset.csv -NoTypeInformation
Search-AzGraph -Query "Resources | where type =~ 'microsoft.compute/disks'  | where properties.diskState =~ 'Unattached' | project name, properties.diskState, subscriptionId, resourceGroup" -first 5000 | Export-Csv -Path .\disksunattached.csv -NoTypeInformation
Search-AzGraph -Query "Resources | where type =~ 'Microsoft.Compute/virtualMachines'  | extend AllProperties = todynamic(properties.extended.instanceView.powerState)  | where AllProperties.code =~ 'PowerState/deallocated' | project name, AllProperties.code, subscriptionId, resourceGroup" -first 5000 | Export-Csv -Path .\stoppedVM.csv -NoTypeInformation
search-azgraph -query "advisorresources | where type == 'microsoft.advisor/recommendations' | where properties.category == 'Cost' | where properties.shortDescription.solution contains  'MySQL' | project properties.extendedProperties.annualSavingsAmount, properties.extendedProperties.displayQty, properties.extendedProperties.displaySKU, properties.extendedProperties.subId" -first 5000 | Export-Csv -Path .\mysqlcapacity.csv -NoTypeInformation
search-azgraph -query "advisorresources | where type == 'microsoft.advisor/recommendations' | where properties.category == 'Cost' | where properties.shortDescription.solution contains 'DB'
| project properties.extendedProperties.annualSavingsAmount, properties.extendedProperties.displayQty, properties.extendedProperties.displaySKU, properties.extendedProperties.subId" -first 5000 | Export-Csv -Path .\sqlcapacity.csv -NoTypeInformation
search-azgraph -query "advisorresources | where type == 'microsoft.advisor/recommendations' | where properties.category == 'Cost' | where properties.shortDescription.solution contains 'Postgre'
| project properties.extendedProperties.annualSavingsAmount, properties.extendedProperties.displayQty, properties.extendedProperties.displaySKU, properties.extendedProperties.subId" -first 5000 | Export-Csv -Path .\postgrecapacity.csv -NoTypeInformation
search-azgraph -query "advisorresources | where type == 'microsoft.advisor/recommendations' | where properties.category == 'Cost' | where properties.shortDescription.solution contains 'Right-size' | project properties.extendedProperties.roleName, properties.extendedProperties.currentSku , properties.extendedProperties.targetSku, properties.extendedProperties.MaxMemoryP95, properties.extendedProperties.MaxCpuP95, resourceGroup, subscriptionId" -first 5000 | Export-Csv -Path .\rightsize.csv -NoTypeInformation
search-azgraph -query "advisorresources | where type == 'microsoft.advisor/recommendations' | where properties.category == 'Cost' | where properties.shortDescription.solution contains  'virtual machine reserved' | project properties.extendedProperties.annualSavingsAmount, properties.extendedProperties.reservationType, properties.extendedProperties.vmSize, subscriptionId, properties.resourceMetadata.resourceId" -first 5000 | Export-Csv -Path .\AzureRI.csv -NoTypeInformation

Install-Module ImportExcel -scope CurrentUser
$csvs = Get-ChildItem .\* -Include *.csv
$csvCount = $csvs.Count
Write-Host "Detection des fichiers CSV suivants: ($csvCount)"
foreach ($csv in $csvs) {
    Write-Host " -"$csv.Name
}

$excelFileName = $(get-date -f ddMMyyyy) + "_" + $env:USERNAME + "_Azure_FinOps.xlsx"
Write-Host "Creation du fichier: $excelFileName"

foreach ($csv in $csvs) {
    $csvPath = ".\" + $csv.Name
    $worksheetName = $csv.Name.Replace(".csv","")
    Write-Host " - Ajout du CSV $worksheetName dans le fichier $excelFileName"
    Import-Csv -Path $csvPath | Export-Excel -Path $excelFileName -WorkSheetname $worksheetName
}

Le script va générer un fichier Excel. Libre à vous de rajouter une requête GRAPH en fonction de vos besoins.

Le fichier Excel généré intègre les onglets incluant les recommandations (non limitées à 60 souscriptions) décrites ci-dessus.

Vous avez ainsi un fichier Excel qui regroupe l’ensemble des actions FinOps à mener en tant que Quick Wins par catégorie: RightSizing, Waste, RI, …

Vous pouvez aussi en faire un Runbook pour suivre cela de près pour mener vos actions de Cost Killing. Enjoy !

Partagez si ça vous plait !
0 0 voter
Évaluation de l'article
S’abonner
Notifier de
guest
0 Commentaires
Inline Feedbacks
View all comments