[Перевод] Изменяем и удаляем Azure VMs, используя PowerShell
С помощью PowerShell инженеры и IT-администраторы успешно автоматизируют различные задачи при работе не только с on-premises, но и с облачными инфраструктурами, в частности, с Azure. Работать через PowerShell в ряде случаев гораздо удобнее и быстрее, чем через Azure portal. Благодаря кросс-платформенности PowerShell можно использовать для любых ОС.
Неважно, работаете ли вы с Ubuntu, Red Hat или Windows — PowerShell поможет контролировать облачные ресурсы. Используя модуль Azure PowerShell, к примеру, можно задавать любые свойства виртуальных машин.
В этой статье мы рассмотрим, как можно использовать PowerShell, чтобы изменить размер ВМ в облаке Azure, а также чтобы удалить ВМ и ассоциированные с ней объекты.
Важно! Не забудьте протереть руки санитайзером подготовиться к работе:
- Вам понадобится модуль 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 вы будете указывать свои значения этих параметров.)
Команда вернет примерно такой перечень:
Это все возможные варианты размеров, которые можно задать для данной виртуальной машины.
Ресайзим машину
Для примера мы сделаем ресайз на новый размер Standard_B1ls — он на первом месте в списке выше. (В реальных задачах, разумеется, вы выбираете любой нужный вам размер.)
- Сначала с помощью команды
Get-AzVM
получаем сведения о нашем объекте (виртуальной машине), сохраняя их в переменную$virtualMachine
:$virtualMachine = Get-AzVM -ResourceGroupName dev -VMName devvm01
- Затем у этого объекта берем свойство
.HardwareProfile.VmSize
и устанавливаем нужное новое значение:$virtualMachine.HardwareProfile.VmSize = "Standard_B1ls"
- И теперь просто выполняем команду обновления ВМ —
Update-AzVm
:Update-AzVM -VM devvm01 -ResourceGroupName dev
- Убеждаемся, что всё прошло успешно — для этого опять же запрашиваем информацию о нашем объекте и смотрим на свойство
$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), чтобы при неполадках с загрузкой было к чему обратиться на предмет траблшутинга. Однако при удалении ВМ этот контейнер остается продолжать свое теперь бесцельное существование. Исправим эту ситуацию.
- Сперва выясним, какому сторадж-аккаунту принадлежит этот контейнер — для этого нам нужно разыскать свойство
storageUri
в недрах объектаDiagnosticsProfile
нашей ВМ. Для этого я использую вот такое регулярное выражение:$diagSa = [regex]::match($vm.DiagnosticsProfile.bootDiagnostics.storageUri, '^http[s]?://(.+?)\\.').groups[1].value
- Теперь надо узнать имя контейнера, а для этого нужно получить 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)
- Далее получаем имя ресурсной группы, к которой принадлежит контейнер:
$diagSaRg = (Get-AzStorageAccount | where { $_.StorageAccountName -eq $diagSa }).ResourceGroupName
- И теперь у нас есть все необходимое, чтобы удалить контейнер командой
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.