Наскоро се сблъсках с не толкова популярно още животно в света на DevOps - пайплайните на Azure DevOps. Веднага усетих липсата на ясни инструкции или статии по темата. Не знам с какво е свързано, но Microsoft определено има какво да подобри в популяризирането на инструмента. Днес ще изградим пайплайн за автоматизирано тестване в облака Azure.
И така, задачата:
Имаме софтуер, който се билдва с помощта на същия Azure DevOps, събран от проект на WIX. Ако има интерес, ще напиша и за този инструмент. Всъщност, това е по-оптимизиран за автоматизация начин за сглобяване на Windows инсталатори, заместващ стандартния InstallShield. И така, нашият софтуер успешно се събира и генерира артефакт, нещо като setup.exe, който инсталира приложението в системата Windows. Необходимо е това приложение да бъде инсталирано в виртуална машина, прилична на продукционна, да копираме автоматизирани тестове, подготвени от екипа по тестване, да ги стартираме и да вземем резултатите, за да оценим дали клонът е добър или лош, преди да извършим сливането. Всичко е като в GitLab, само че през ж...
Като среда за виртуализация, в която ще изпълняваме нашите тестове, използваме, очевидно, Azure DevTest Labs - нещо в подписките на Azure, което е създадено да стартира всякакви тестови неща на разумни цени.
1. Интеграция на страната на облака
Първо, ще трябва да интегрираме нашите DevTest Labs с Azure DevOps, за което ни е необходим Service Principal - всъщност, сервисна сметка, която позволява на пайплайния да достъпи облака и да създава/изтрива ресурси за себе си.
Отиваме в подписката и намираме услугата Azure Active Directory

Намираме App Registrations и кликваме на New Registration, за да създадем нашия service principal. Няма да разглеждам подробно какви настройки да изберем при създаването, тъй като те могат да се различават в зависимост от подписките.

Сега трябва да предоставим права на нашия сервисен директор. За това отиваме в подписките, на иконата с ключа. Избираме нашата подписка.

След това в Access Control натискаме Role Assignment и търсим в търсачката по името на създадената току-що сметка. Даваме роля Contributor, достатъчно е.

След това се връщаме към нашия Service Principal в Azure AD и отваряме неговите свойства. По-късно, ще ни трябват всички ID-та, които там се намират, запазваме ги.
С това приключваме настройките на портала и преминаваме към Azure DevOps.
2. Интеграция в Azure DevOps
Първо, влизаме в настройките на проекта и избираме Service Connections. Създаваме нов елемент от типа Azure Resource Manager.

Сега ще ни трябват всички ID, които записахме. Кликваме на use the full version of the service connection dialog. Въвеждаме всички данни, които получихме от Service Principal. Натискаме verify и ако всичко е наред, запазваме връзката. Сега нашите пайплайни могат да я използват за свързване с облака.

3. Създаване на пайплайн
Сега преминаваме към най-интересното, изграждането на самия пайплайн. Отваряме менюто Pipelines-Builds

Срещаме менюто за създаване на нов билд, което по подразбиране ще се опита да създаде YAML файл с подходяща конфигурация. Ние учтиво отказваме това и избираме класическия вариант. Ясно е желанието на Microsoft да направи всичко, както хората, и да даде възможност за максимално персонализиране на пайплайните чрез YAML, но оскъдната документация и просто практически неработоспособността на много от модулите ни показват, че е още рано да се ползва тази функционалност.

От многообразието от шаблони ще ни трябва прост Empty Pipeline. След създаването му, ни посреща празен прозорец за редактиране, в който ще прекараме доста време.

И така, натискаме на + и попадаме в некакъв магазин за модули, от който по списък ще ни трябват следните компоненти.

Преди да започнем с конфигурацията на задачите в пайплайна, трябва да създадем и сложим в проекта няколко файла. Това ще бъдат ARM Template на нашата виртуална машина, който ще генерираме в Azure DevTest Labs, скрипт за извличане на IP адреса на машината след като е създадена, и по желание, скриптове за нашите тестове или каквото искаме да стартираме на хоста.
4. Генерация на ARM Template
За да създадем виртуална машина, първо трябва да генерираме темплейт за нея, json файл, който ще сложим в кода на проекта, за да може пайплайнът да го прочете оттам.
Отиваме в нашата лаборатория и намираме менюто Formulas (reusable bases), натискаме създаване на ново.

Ще се срещнем с дълъг списък от имиджи за базата, избор на размер на машината, всичко същото както при създаване на виртуална машина. На този етап няма да се спираме, а направо ще преминем към последната точка от свойствата на машината, а именно артефактите. Можете да използвате всякакви конфигурации, от които имате нужда за вашата среда. Например, добавям машина в домейн и добавям на нея сервисен акаунт като администратор, за да може пайплайнът след това да се свързва с тази машина с тази учетна запис. Всичко това може да варира, но за успешното тестване на кода ни е нужен един артефакт, върху който ще се спрем по-подробно. За да стане последната версия на тествания от нас софтуер на нашата машина, ще използваме артефакт „Download Azure Pipelines Artifact and Run Script“. Помните ли в началото, че споменах, че на някъде се генерира билд с инсталатора на приложението? Сега трябва да кажем на виртуалката, а точно на шаблона, да отиде и да вземе този артефакт. И не просто да го вземе, а също така да го инсталира, за което попълваме специални полета с указание на проекта, името на билда и секретния ключ. Секретния ключ, както и в повечето системи от този тип, се генерира в акаунта, в този случай в Azure DevOps и се съхранява в Secrets във вашата лаборатория. Тук има малка уговорка, в Secrets ще го запазим, но на шаблона това не му помага, той ще се стартира от друг потребител в рамките на пайплайна, затова секретният ключ трябва да въведем отново ръчно в шаблона.
Още един артефакт, който е необходимо да включим, е „Configure WinRM“, той ще ни е нужен за последващ достъп до машината. Има само един параметър, hostname. Тъй като не знаем предварително този параметър, ще се възползваме от променливата %COMPUTERNAME%.

И така, добавихме всички нужни артефакти, преминаваме към причината, поради която сме тук. Извличаме генерирания ARM Template на раздела Advanced в същия прозорец за създаване на формула.

Копираме съдържанието на страницата в файл VMtemplate.json и го поставяме в корена на проекта. Вече не ни трябва облака, връщаме се в пайплайна.
5. Конфигурация на пайплайна
Да започнем с най-важното и интересно, създаването на виртуална машина. Заради това направихме всички тези интеграции и шаблони. В раздела Azure RM Subscription избираме нашата Service connection, която конфигурирахме в точка 2. След това трябва да се появи наличната лабораторна среда. След това избираме json, който генерирахме, и определяме някои задължителни променливи. Логинът и паролата за машината могат да се зададат директно или чрез променливи, но не съм сигурен, че работи, понеже каквото и да пиша, не успявах да вляза на машината с тези креденциали. Важно е да зададете име на машината, така че да бъде уникално, доколкото е възможно. За това използвам променлива на средата на билд.

Следващата важна стъпка е настройката на нещо не по-малко важно. След като машината стартира, трябва по някакъв начин да знаем нейните параметри, а е по-добре не ние, а пайплайнът. Затова правим скрипт, например GetLabVMParams.ps1, и го поставяме в проекта. Текста на скрипта взех от сайта на Microsoft, но го подправих малко за моята среда, тъй като той взимаше PublicIP и FQDN на машината. Нито едното, нито другото го нямам, но имам PrivateIP, който не е толкова лесен за получаване, затова добавих малко код.
Param( [string] $labVmId)
$labVmComputeId = (Get-AzureRmResource -Id $labVmId).Properties.ComputeId
# Вземете името на ресурсната група на лабораторната VM
$labVmRgName = (Get-AzureRmResource -Id $labVmComputeId).ResourceGroupName
# Вземете името на лабораторната VM
$labVmName = (Get-AzureRmResource -Id $labVmId).Name
# Вземете публичния IP адрес на лабораторната VM
# $labVMIpAddress = (Get-AzureRmPublicIpAddress -ResourceGroupName $labVmRgName -Name $labVmName).IpAddress
# Вземете лабораторната VM FQDN
# $labVMFqdn = (Get-AzureRmPublicIpAddress -ResourceGroupName $labVmRgName -Name $labVmName).DnsSettings.Fqdn
# Вземете частния IP адрес на лабораторната VM
$VmNetworkdetails= (((Get-AzureRmVM -ResourceGroupName $labVmRgName -Name $labVmName).NetworkProfile).NetworkInterfaces).Id
$nicname = $VmNetworkdetails.substring($VmNetworkdetails.LastIndexOf("/")+1)
$labVMnetwork = (Get-AzureRmNetworkInterface -Name $nicname -ResourceGroupName $labVmRgName)|Select-Object -ExpandProperty IPConfigurations
$labVMIpAddress = $labVMnetwork.PrivateIpAddress
# Задайте променлива labVmRgName, за да запазите името на ресурсната група на лабораторната VM
Write-Host "##vso[task.setvariable variable=labVmRgName;]$labVmRgName"
# Задайте променлива labVMIpAddress, за да запазите IP адреса на лабораторната VM
Write-Host "##vso[task.setvariable variable=labVMIpAddress;]$labVMIpAddress"
# Задайте променлива labVMFqdn, за да запазите името на FQDN на лабораторната VM
Write-Host "##vso[task.setvariable variable=labVMFqdn;]$labVMFqdn"
Write-Output $labVMIpAddress
Set-Item wsman:localhostclienttrustedhosts * -ForceОт всичко, което скриптът извлича, ни трябва само променливата labVMIpAddress. Може да ви е необходима още нещо, но затова не съм изтривал нищо, а просто съм коментирал излишното.
Също така ще обясня последния ред на скрипта, той позволява на нашата билд машина достъп до всякакви хостове чрез WinRM.
На следващия етап стартираме нашия чудесен скрипт. Той ще се нуждае от същото свързване с облака, входна променлива с ID на машината, която до момента вече ще е известна от предишната стъпка. Как? Тук е необходимо да споменем за едно чудесно нещо, наречено Изходни Променливи. Всеки етап може да има списък с променливи, които се предават нататък на следващите стъпки в пайплайна. Съответно за нашия супер скрипт такава променлива ще бъде labVMIpAddress, не забравяйте да я посочите.

След това извършвам доста прости действия, които също могат да варират от случай до случай. Изпълнявам отдалечен скрипт за създаване на споделена папка, в която след това ще качвам моите скриптове.
New-Item “C:test" –type directory
New-SMBShare –Name “test” –Path “C:test” –FullAccess everyoneОт името на задачите е ясно, че след това копираме определен sample script на машината и в още един етап го изпълняваме. Както адрес на отдалечената машина ще ни е нужна нашата променлива $(labVMIpAddress). След това използваме задачата „вземи артефакт от споделянето“ и копираме резултатите от изпълнението на скрипта в нашата билд среда, след което същата стандартна задача запазваме тези файлове в артефакта на билда. След като машината вече не ни е нужна, на последния етап я унищожаваме. Основната трудност, както личи от обема на статията, е да се интегрираме с облака и да установим контакт с виртуалната машина, която сте създали, след което вече можете да се развлекате колкото желаете.
Това е моята първа статия, така че не съдите строго, приветстват се забележки.
Източник: habr.com
