azure предлагает огромное количество опций и возможностей, в том числе и для автоматизации. В принципе, если вы планируете хостить свою работу исключительно там, то Вам даже не нужен Continuous Delivery сервер, так как всё необходимое уже есть в самом Azure. Однако, бесплатного ничего не бывает и за многое Azure вам выставит дополнительный счет.
Как известно, счет в Azure генерируется исходя из часов, в течении которых виртуальная машина была в состоянии Provisioned. Таким образом, тут есть возможность сэкономить – отключать машины и веб приложения через Портал (если выключать из машины, она всё равно будет генерить деньги) на ночь для тех окружений, которые не нужны по ночам (например, dev/QA/UAT окружения в негеографически распределенных командах).
Если у вас нет своего continuous integration/Delivery (ci/cd) сервера и вы не планируете его внедрять, то Azure предлагает Azure Automations (биллинг по минутам, 500 минут (как будет видно позже, это маловато) предоставляются бесплатно) и этот runbook. Однако, если у вас уже есть CI/CD сервер, способный выполнять powershell скрипты, то зачем генерировать излишнюю стоимость, если можно выполнять всё на этом сервере.
Скрипт для включения/выключения виртуальных машин:
#Switched Off or On set of VMs, passed as parameters #Example usage: .\SwitchVmOnOff.ps1 username password 1 1 "some subscription name" "some-vm0";"some-vm1";"some-vm2" #where #username - user with co-administrator rights on subscription #password - password for this user #1 - boolean, if machine shall be switched off #1 - is this VM v2 or no #some sbuscription name - name of subscrtion #"some-vm0";"some-vm1";"some-vm2" - machines to switch off param( [string]$userName, [string]$password, [string]$switchOffString, [string]$useResourceManagerString, [string]$subscriptionName, [string]$machineNames ) $secpasswd = ConvertTo-SecureString $password -AsPlainText -Force $cred = New-Object System.Management.automation.PSCredential ($userName, $secpasswd) Add-AzureAccount -Credential $cred Select-AzureSubscription -SubscriptionName $subscriptionName -Current #Variables settings. teamcity passes it as pure strings if ($switchOffString -eq "1") { $switchOff = $True } else { $switchOff = $False } if ($useResourceManagerString -eq "1") { $useResourceManager = $True } else { $useResourceManager = $False } if ($useResourceManager) { Switch-AzureMode AzureResourceManager } else { Switch-AzureMode AzureServiceManagement } $vmList = Get-AzureVM Write-Output "Number of virtual machines found in subscription: [$($vmList.Count)]" $separator = ";","," $option = [System.StringSplitOptions]::RemoveEmptyEntries $machineNamesArray = $machineNames.Split($separator,$option) foreach($entry in $machineNamesArray) { $vm = $vmList | where Name -eq $entry if ($switchOff) { Write-Output "Stopping VM [$($entry)]" $vm | Stop-AzureVM -Force } else { Write-Output "Starting VM [$($entry)]" $vm | Start-AzureVM } }
Интеграция с Teamcity:
Так как у меня много машин, сгрупированных по разным подпискам, то, чтобы не мучаться, я создал темплейт, состоящий из одного шага с Powershell:
(в поле Script arguments: -userName %username% -password %password% -switchOffString %switchOff% -useResourceManagerString %useResourceManager% -subscriptionName %subscriptionName% %machineNames%)
Соотвественно, для каждого события (включение и выключении машин в подписке)нужно создать два билда (Включить и выключить) с параметрами как на скриншоте:
Параметры:
- machineNames – имена машин, разделенные точкой с запятой (если есть пробелы – надо имя брать в кавычки)
- password – пароль от администратора или ко-администратора подписки
- subscriptionName – имя подписки (если есть пробелы – в кавычках)
- switchOff – 1, если надо выключать, и 0, если надо включать
- useResourceManager – если виртуалные машины развернуты в v2, то 1, если нет – то 0
- username – имя администратора или ко-администратора подписки
Скрипт для включения/выключения веб приложений:
#Switched Off or On set of VMs, passed as parameters #Example usage: .\SwitchWebAppOnOff.ps1 username password 1 "some subscription name" "some-vm0";"some-vm1";"some-vm2" #where #username - user with co-administrator rights on subscription #password - password for this user #1 - boolean, if machine shall be switched off #some sbuscription name - name of subscrtion #"some-vm0";"some-vm1";"some-vm2" - webapps to switch off param( [string]$userName, [string]$password, [string]$switchOffString, [string]$subscriptionName, [string]$webAppsNames ) $secpasswd = ConvertTo-SecureString $password -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential ($userName, $secpasswd) Add-AzureAccount -Credential $cred Select-AzureSubscription -SubscriptionName $subscriptionName -Current #Variables settings. Teamcity passes it as pure strings if ($switchOffString -eq "1") { $switchOff = $True } else { $switchOff = $False } $webAppsList = Get-AzureWebsite Write-Output "Number of Web Apps found in subscription: [$($webAppsList.Count)]" $separator = ";","," $option = [System.StringSplitOptions]::RemoveEmptyEntries $webAppsNamesArray = $webAppsNames.Split($separator,$option) foreach($entry in $webAppsNamesArray) { $webApp = $webAppsList | where Name -eq $entry if ($switchOff) { Write-Output "Stopping WebApp [$($entry)]" $webApp | Stop-AzureWebsite } else { Write-Output "Starting WebApp [$($entry)]" $webApp | Start-AzureWebsite } }
Тут тимплейт не отличается, просто поле Script Arguments содержит меньше параметров, так как нам не надо менять AzureMode:
-userName %username% -password %password% -switchOffString %switchOff% -subscriptionName %subscriptionName% %webAppsNames%
webAppsNames – строка, разделенная точками с запятой, также, как и machineNames
В качестве триггера для обоих билдов (включение/выключение) – я использую Schedule trigger по крону.
Выключение: Cron command: 0 30 21 ? * 2-6 *
Включение: Cron command: 0 30 8 ? * 2-6 *