Получение рекомендаций Azure Advisor

Опубликовано: 10.02.2021
Автор: Виталий Бочкарев
Поддержать автора статьи по этой ссылке

В облачном сервисе Microsoft Azure есть специальный сервис для анализа использования виртуальных машин, который показывает, мощности каких машины не соответствуют выставленным параметрам серверов, расходы на которые можно уменьшить, снизив параметры серверов -  Azure Advisor, раздел Cost. Через PowerShell-скрипт можно запросить необходимую информацию, чтобы потом использовать ее в своих проектах автоматизации облачной инфраструктуры.

# ------------------------------------------------------------------------------------------------
# Defining variables
 
# ------------------------------------------------------------------------------------------------
# Functions
 
Function Write-ScriptLog {
  Param(
    [CmdletBinding()] 
    [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
    [String]$Message,
    [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
    [String]$LogFile
  )
  Process {
    $LogMessage = Get-Date -uformat "%d.%m.%Y %H:%M:%S"
    $LogMessage += "`t"
    $LogMessage += $Message
    $LogMessage | Out-File -FilePath $LogFile -Append
  }
}#End Function
 
# ------------------------------------------------------------------------------------------------
# Получение пути к скрипту
$ScriptFolder = $MyInvocation.MyCommand.Path.SubString(0,($MyInvocation.MyCommand.Path.Length - $MyInvocation.MyCommand.Name.Length))
# Формирование пути к лог-файлу
$LogFile = $ScriptFolder + $MyInvocation.MyCommand.Name.SubString(0,($MyInvocation.MyCommand.Name.Length - 4)) + ".log"
$JsonFile = $ScriptFolder + $MyInvocation.MyCommand.Name.SubString(0,($MyInvocation.MyCommand.Name.Length - 4)) + ".json"
# Создание лог-файла
Out-File -FilePath $LogFile
Write-ScriptLog -LogFile $LogFile -Message ($MyInvocation.MyCommand.Name + " started")
# Чтение аргументов из командной строки
Write-ScriptLog -LogFile $LogFile -Message "Reading input arguments"
If ($args.length -ne 3) {
  Write-ScriptLog -LogFile $LogFile -Message "Wrong number of agruments"
  Write-ScriptLog -LogFile $LogFile -Message "Using default values"
  $AZU_TENANT_ID = 'abcdefjh-1234-abcd-1234-abcdefjhigkl'
  $AZU_CLIENT_ID = 'hjfedcba-4321-dcba-4321-lkgihjfedcba'
  $AZU_SECRET_KEY = '123.abc.1234567.abcdefj.123456789'
} else {
  $AZU_TENANT_ID = $args[0]
  $AZU_CLIENT_ID = $args[1]
  $AZU_SECRET_KEY = $args[2]
}
Write-ScriptLog -LogFile $LogFile -Message "  azu_tenant_id is $AZU_TENANT_ID"
Write-ScriptLog -LogFile $LogFile -Message "  azu_client_id is $AZU_CLIENT_ID"
Write-ScriptLog -LogFile $LogFile -Message "  aqzu_secret_key is $AZU_SECRET_KEY"
Write-ScriptLog -LogFile $LogFile -Message "  output json-file is $JsonFile"
# вход в Azure
Write-ScriptLog -LogFile $LogFile -Message "Logging in to Azure"
$AZU_SECRET_KEY_SEC = ConvertTo-SecureString $AZU_SECRET_KEY -AsPlainText -Force
$pscredential = New-Object -TypeName System.Management.Automation.PSCredential($AZU_CLIENT_ID, $AZU_SECRET_KEY_SEC)
Disconnect-AzAccount
Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $AZU_TENANT_ID  | Out-Null
# создание пустого списка свойств резервного копирования серверов
$data = New-Object System.Collections.Generic.List[System.Object]
# получение всех рекомендаций
Write-ScriptLog -LogFile $LogFile -Message "Reading recommendations"
$recommendations_list = Get-AzAdvisorRecommendation -Category Cost
Write-ScriptLog -LogFile $LogFile -Message ($vault_list.length.ToString() + " recommendations found")
ForEach ($recommendation_item in $recommendations_list) {
  If ($recommendation_item.ImpactedField -eq "Microsoft.Compute/virtualMachines") {
    $id = $recommendation_item.ImpactedValue.ToLower()
    $name = $recommendation_item.ImpactedValue
    if ($recommendation_item.ShortDescription.Problem.ToLower() -eq ("Right-size or shutdown underutilized virtual machines").ToLower()) {
      $status = 'over_provisioned'
    } else {
      $status = 'see in the portal'
    }
    $type_current = $recommendation_item.ExtendedProperties.currentSku
    $type_recommended = $recommendation_item.ExtendedProperties.targetSku
    $utilization_cpu = 'Maximum: ' + $recommendation_item.ExtendedProperties.MaxCpuP95
    $utilization_ram = 'Maximum: ' + $recommendation_item.ExtendedProperties.MaxMemoryP95
     # составление словаря свойств резервного копирования сервера
     $recommendation_properties = New-Object System.Object
     $recommendation_properties | Add-member -MemberType NoteProperty -Name id -Value $id
     $recommendation_properties | Add-member -MemberType NoteProperty -Name name -Value $name
     $recommendation_properties | Add-member -MemberType NoteProperty -Name status -Value $status
     $recommendation_properties | Add-member -MemberType NoteProperty -Name type_current -Value $type_current
     $recommendation_properties | Add-member -MemberType NoteProperty -Name type_recommended -Value $type_recommended
     $recommendation_properties | Add-member -MemberType NoteProperty -Name utilization_cpu -Value $utilization_cpu
     $recommendation_properties | Add-member -MemberType NoteProperty -Name utilization_ram -Value $utilization_ram
     # доабвление полученных свойств в список свойств резервного копирования серверов
     $data.Add($recommendation_properties)
   }
}
Write-ScriptLog -LogFile $LogFile -Message "Reading data from Azure is complete"
Write-ScriptLog -LogFile $LogFile -Message "Deleteing the output file if it exists"
If (Test-Path $JsonFile) { Remove-Item -Path $JsonFile }
If ($data -ne '') {
  Write-ScriptLog -LogFile $LogFile -Message ("Saving json-file " + $JsonFile)
  $data | ConvertTo-Json | Out-File -FilePath $JsonFile -Encoding "utf8"
}
# ------------------------------------------------------------------------------------------------ 
Write-ScriptLog -LogFile $LogFile -Message "----- The script finished -----"

 

Результат работы скрипта - json-файл с рекомендациями по оптимизации виртуальных машин

[
    {
        "id":  "rhaaa001",
        "name":  "rhAAA001",
        "status":  "over_provisioned",
        "type_current":  "Standard_D4s_v3",
        "type_recommended":  "Standard_B4ms",
        "utilization_cpu":  "Maximum: 4",
        "utilization_ram":  "Maximum: 47"
    },
    {
        "id":  "rhaaa003",
        "name":  "rhAAA003",
        "status":  "over_provisioned",
        "type_current":  "Standard_D16s_v3",
        "type_recommended":  "Standard_B16ms",
        "utilization_cpu":  "Maximum: 1",
        "utilization_ram":  "Maximum: 76"
    }
]