Змінюємо та видаляємо Azure VMs, використовуючи PowerShell

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

Неважливо, чи працюєте ви з Ubuntu, Red Hat або Windows - PowerShell допоможе контролювати хмарні ресурси. Використовуючи модуль Azure PowerShell, наприклад, можна задавати будь-які властивості віртуальних машин.

У цій статті ми розглянемо, як можна використовувати PowerShell, щоб змінити розмір ВМ у хмарі Azure, а також видалити ВМ та об'єкти, що з ними асоціюються.

Змінюємо та видаляємо Azure VMs, використовуючи PowerShell

Важливо! Не забудьте протерти руки санітайзером підготуватися до роботи:

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

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

Запитуємо наявні розміри ВМ

До того, як змінити розмір ВМ, необхідно дізнатися, які взагалі є допустимі розміри для віртуальних машин у хмарі Azure. Для цього треба виконати команду Get-AzVMSize.

Отже, для віртуальної машини devvm01 із ресурсної групи DEV запитуємо всілякі допустимі розміри:

Get-AzVMSize -ResourceGroupName dev -VMName devvm01

(У реальних завданнях, природно, замість ResourceGroupName=dev и VMName=devvm01 ви вказуватимете свої значення цих параметрів.)

Команда поверне приблизно такий перелік:

Змінюємо та видаляємо Azure VMs, використовуючи 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)
  • Мережеві інтерфейси
  • Публічні 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.

Джерело: habr.com

Додати коментар або відгук