Ịgbanwe na ihichapụ Azure VM site na iji PowerShell

С помощью PowerShell инженеры и IT-администраторы успешно автоматизируют различные задачи при работе не только с on-premises, но и с облачными инфраструктурами, в частности, с Azure. Работать через PowerShell в ряде случаев гораздо удобнее и быстрее, чем через Azure portal. Благодаря кросс-платформенности PowerShell можно использовать для любых ОС.

Неважно, работаете ли вы с Ubuntu, Red Hat или Windows — PowerShell поможет контролировать облачные ресурсы. Используя модуль Azure PowerShell, к примеру, можно задавать любые свойства виртуальных машин.

В этой статье мы рассмотрим, как можно использовать PowerShell, чтобы изменить размер ВМ в облаке Azure, а также чтобы удалить ВМ и ассоциированные с ней объекты.

Ịgbanwe na ihichapụ Azure VM site na iji PowerShell

Ihe dị mkpa! Не забудьте протереть руки санитайзером подготовиться к работе:

  • Вам понадобится модуль Azure PowerShell Module — его можно загрузить из PowerShell Gallery командой Install-Module Az.
  • Нужно аутентифицироваться в облаке Azure, где крутится виртуальная машина, выполнив команду Connect-AzAccount.

Для начала создадим скрипт, который ресайзит Azure VM. Откроем VS Code и сохраним новый PowerShell скрипт под названием Resize-AzVirtualMachine.ps1 — в него мы по ходу примера будем добавлять куски кода.

Запрашиваем имеющиеся размеры ВМ

До того, как поменять размер ВМ, нужно узнать, какие вообще имеются допустимые размеры для виртуальных машин в облаке Azure. Для этого надо выполнить команду Get-AzVMSize.

Итак, для виртуальной машины devvm01 из ресурсной группы di запрашиваем всевозможные допустимые размеры:

Get-AzVMSize -ResourceGroupName dev -VMName devvm01

(В реальных задачах, естественно, вместо ResourceGroupName=dev и VMName=devvm01 вы будете указывать свои значения этих параметров.)

Команда вернет примерно такой перечень:

Ịgbanwe na ihichapụ Azure VM site na iji PowerShell

Это все возможные варианты размеров, которые можно задать для данной виртуальной машины.

Ресайзим машину

Для примера мы сделаем ресайз на новый размер Standard_B1ls — он на первом месте в списке выше. (В реальных задачах, разумеется, вы выбираете любой нужный вам размер.)

  1. Сначала с помощью команды Get-AzVM получаем сведения о нашем объекте (виртуальной машине), сохраняя их в переменную $virtualMachine:
    $virtualMachine = Get-AzVM -ResourceGroupName dev -VMName devvm01
  2. Затем у этого объекта берем свойство .HardwareProfile.VmSize и устанавливаем нужное новое значение:
    $virtualMachine.HardwareProfile.VmSize = "Standard_B1ls"
  3. И теперь просто выполняем команду обновления ВМ — Update-AzVm:
    Update-AzVM -VM devvm01 -ResourceGroupName dev
  4. Убеждаемся, что всё прошло успешно — для этого опять же запрашиваем информацию о нашем объекте и смотрим на свойство $virtualMachine.HardwareProfile:
    $virtualMachine = Get-AzVM -ResourceGroupName dev -VMName devvm01
    $virtualMachine.HardwareProfile

Если там видим Standard_B1ls — значит, всё в порядке, размер машины изменен. Можно пойти дальше и развить успех — заресайзить сразу несколько ВМ, используя массив.

А что насчет удаления ВМ в Azure?

С удалением не всё так просто и прямолинейно, как может показаться. Ведь надо удалить еще ряд ресурсов, ассоциированных с этой машиной, в том числе:

  • Сторадж-контейнеры для диагностики загрузки (Boot diagnostics storage containers)
  • Ihe netwok
  • Публичные IP адреса
  • Системный диск и blob, где хранится его статус
  • Диски с данными (data disks)

Посему мы создадим функцию и назовем ее Remove-AzrVirtualMachine — и она будет удалять не только Azure VM, но и все вышеперечисленное.

Идём стандартным путем и сначала получаем наш объект (ВМ) с помощью команды Get-AzVm. Для примера пусть это будет машина WINSRV19 из ресурсной группы MyTestVMs.

Сохраним этот объект вместе со всеми его свойствами в переменную $vm:

$vm = Get-AzVm -Name WINSRV19 -ResourceGroupName MyTestVMs

Удаляем контейнер с файлами диагностики загрузки

При создании ВМ в Azure пользователю предлагается также создать и контейнер для хранения диагностики загрузки (boot diagnostics container), чтобы при неполадках с загрузкой было к чему обратиться на предмет траблшутинга. Однако при удалении ВМ этот контейнер остается продолжать свое теперь бесцельное существование. Исправим эту ситуацию.

  1. Сперва выясним, какому сторадж-аккаунту принадлежит этот контейнер — для этого нам нужно разыскать свойство storageUri в недрах объекта DiagnosticsProfile нашей ВМ. Для этого я использую вот такое регулярное выражение:
    $diagSa = [regex]::match($vm.DiagnosticsProfile.bootDiagnostics.storageUri, '^http[s]?://(.+?)\.').groups[1].value
  2. Теперь надо узнать имя контейнера, а для этого нужно получить VM ID с помощью команды Get-AzResource:
    
    if ($vm.Name.Length -gt 9) {
        $i = 9
    } else {
        $i = $vm.Name.Length - 1
    }
     
    $azResourceParams = @{
        'ResourceName' = WINSRV
        'ResourceType' = 'Microsoft.Compute/virtualMachines'
        'ResourceGroupName' = MyTestVMs
    }
     
    $vmResource = Get-AzResource @azResourceParams
    $vmId = $vmResource.Properties.VmId
    $diagContainerName = ('bootdiagnostics-{0}-{1}' -f $vm.Name.ToLower().Substring(0, $i), $vmId)
    
  3. Далее получаем имя ресурсной группы, к которой принадлежит контейнер:
    $diagSaRg = (Get-AzStorageAccount | where { $_.StorageAccountName -eq $diagSa }).ResourceGroupName
  4. И теперь у нас есть все необходимое, чтобы удалить контейнер командой Remove-AzStorageContainer:
    $saParams = @{
        'ResourceGroupName' = $diagSaRg
        'Name' = $diagSa
    }
     
    Get-AzStorageAccount @saParams | Get-AzStorageContainer | where { $_.Name-eq $diagContainerName } | Remove-AzStorageContainer -Force

Удаляем ВМ

Теперь удалим собственно виртуальную машину, благо мы уже создали переменную $vm для соответствующего объекта. Что ж, запустим команду Remove-AzVm:

$null = $vm | Remove-AzVM -Force

Удаляем сетевой интерфейс и публичный IP-адрес

У нашей ВМ остались один (или даже несколько) сетевых интерфейсов (NICs) — чтобы удалить их за ненужностью, пройдемся по свойству NetworkInterfaces нашего объекта VM и удалим NIC командой Remove-AzNetworkInterface. На случай, если сетевых интерфейсов более одного, используем цикл. Заодно для каждого NIC проверим свойство IpConfiguration на предмет того, есть ли у интерфейса публичный IP адрес. Буде таковой обнаружится, удалим его командой Remove-AzPublicIpAddress.

Вот пример как раз такого кода, где мы в цикле просматриваем все NICs, удаляем их, проверяем, имеется ли публичный IP. Если есть, то парсим свойство PublicIpAddress, достаем по ID имя соответствующего ресурса и удаляем его:


foreach($nicUri in $vm.NetworkProfile.NetworkInterfaces.Id) {
    $nic = Get-AzNetworkInterface -ResourceGroupName $vm.ResourceGroupName -Name $nicUri.Split('/')[-1]
    Remove-AzNetworkInterface -Name $nic.Name -ResourceGroupName $vm.ResourceGroupName -Force

    foreach($ipConfig in $nic.IpConfigurations) {
        if($ipConfig.PublicIpAddress -ne $null) {
            Remove-AzPublicIpAddress -ResourceGroupName $vm.ResourceGroupName -Name $ipConfig.PublicIpAddress.Id.Split('/')[-1] -Force
        }
    }
}

Удаляем системный диск

Диск ОС представляет собой blob, для удаления коего имеется команда Remove-AzStorageBlob — но перед тем, как ее выполнять, нужно будет задать требуемые значения ее параметрам. Для этого, в частности, нужно получить имя сторадж-контейнера, содержащего системный диск, и потом уже передать его данной команде вместе с соответствующим сторадж-аккаунтом.

$osDiskUri = $vm.StorageProfile.OSDisk.Vhd.Uri
$osDiskContainerName = $osDiskUri.Split('/')[-2]
$osDiskStorageAcct = Get-AzStorageAccount | where { $_.StorageAccountName -eq $osDiskUri.Split('/')[2].Split('.')[0] }
$osDiskStorageAcct | Remove-AzStorageBlob -Container $osDiskContainerName -Blob $osDiskUri.Split('/')[-1]

Удаляем Blob статуса системного диска

Для этого, как вы уже наверняка догадались, мы берем сторадж-контейнер, в котором хранится данный диск, и, подразумевая, что blob в конце содержит status, передаем соответствующие параметры команде удаления Remove-AzStorageBlob:

$osDiskStorageAcct | Get-AzStorageBlob -Container $osDiskContainerName -Blob "$($vm.Name)*.status" | Remove-AzStorageBlob

И, наконец, удаляем диски с данными

У нашей ВМ могли оставаться диски с данными, которые были к ней приаттачены. Если в них нет необходимости, удалим и их тоже. Сначала распарсим StorageProfile нашей ВМ и найдем свойство Uri. Если дисков несколько, организуем цикл по URI. Для каждого URI найдем соответствующий сторадж-аккаунт с помощью Get-AzStorageAccount. Затем распарсим storage URI, чтобы вытащить нужное имя blob-a и передать его команде удаления Remove-AzStorageBlob вместе со сторадж-аккаунтом. Вот как это будет выглядеть в коде:

if ($vm.DataDiskNames.Count -gt 0) {
    foreach ($uri in $vm.StorageProfile.DataDisks.Vhd.Uri) {
        $dataDiskStorageAcct = Get-AzStorageAccount -Name $uri.Split('/')[2].Split('.')[0]
        $dataDiskStorageAcct | Remove-AzStorageBlob -Container $uri.Split('/')[-2] -Blob $uri.Split('/')[-1]
    }
}

И вот “мы добрались до счастливого конца!” Теперь из всех этих фрагментов надо собрать единое целое. Добрый автор Адам Бертрам пошел навстречу пользователям и сделал это сам. Вот ссылочка на итоговый скрипт под названием Remove-AzrVirtualMachine.ps1:

GitHub

Надеюсь, что эти практические советы пригодятся вам, чтобы сэкономить силы, время и средства при работе с Azure VMs.

isi: www.habr.com

Tinye a comment