Kürzlich bin ich auf ein nicht so beliebtes Biest in der DevOps-Welt gestoßen: Azure DevOps Pipelines. Ich habe sofort das Fehlen klarer Anweisungen oder Artikel zu diesem Thema gespürt. Ich weiß nicht, womit das zusammenhängt, aber Microsoft hat eindeutig etwas zu tun, um das Tool bekannter zu machen. Heute werden wir eine Pipeline für automatisierte Tests innerhalb der Azure-Cloud erstellen.
Also die Aufgabe:
Es gibt Software, die mit demselben Azure DevOps erstellt wurde und aus einem Projekt auf WIX stammt. Wenn Interesse besteht, werde ich über dieses Tool schreiben. Tatsächlich ist dies eine stärker automatisierungsoptimierte Methode zum Erstellen von Windows-Installationsprogrammen und ersetzt das Standard-InstallShield. Unsere Software ist also erfolgreich zusammengestellt und generiert ein Artefakt, eine bestimmte setup.exe, die die Anwendung auf dem Windows-System installiert. Sie müssen diese Anwendung in einer virtuellen Maschine platzieren, die einer Produktionsmaschine ähnelt, automatisierte Tests, die vom Testteam dort vorbereitet wurden, kopieren, sie ausführen und die Ergebnisse erfassen, um den Zweig vor der Zusammenführung als gut oder schlecht zu beurteilen. Alles ist wie in GitLab, nur durch….
Als Virtualisierungsumgebung, in der wir unsere Tests durchführen, verwenden wir natürlich Azure DevTest Labs, eine bestimmte Entität in Azure-Abonnements, die zu diesem Zweck erstellt wurde, um darin für angemessenes Geld allerlei Testunsinn auszuführen.
1. Integration auf der Cloud-Seite
Zuerst müssen wir unsere DevTest Labs mit Azure DevOps integrieren, wofür wir einen bestimmten Dienstprinzipal benötigen, im Wesentlichen ein Dienstkonto, das es Pipelines ermöglicht, in die Cloud zu gehen und dort Ressourcen für sich selbst zu erstellen/löschen.
Gehen Sie zum Abonnement und suchen Sie den Azure Active Directory-Dienst

Suchen Sie nach App-Registrierungen und klicken Sie auf Neue Registrierung. Dadurch wird unser Dienstprinzipal erstellt. Ich werde nicht im Detail darauf eingehen, welche Einstellungen beim Erstellen ausgewählt werden müssen; dies kann bei verschiedenen Abonnements unterschiedlich sein.

Jetzt müssen wir unserem Serviceleiter Rechte erteilen. Gehen Sie dazu auf Abonnements, Symbol mit einem Schlüssel. Wählen Sie unser Abonnement.

Klicken Sie anschließend in der Zugriffskontrolle auf Rollenzuweisung und suchen Sie mit dem soeben erstellten Namen nach diesem Konto. Wir vergeben die Rolle „Mitwirkender“, das reicht.

Als Nächstes kehren wir zu unserem Dienstprinzipal in Azure AD zurück und öffnen dessen Eigenschaften. Später benötigen wir alle dort vorhandenen IDs und speichern sie.
Damit sind unsere Portaleinstellungen abgeschlossen und wir fahren mit Azure DevOps fort.
2. Integration auf der Azure DevOps-Seite
Zunächst gehen wir zu den Projekteinstellungen und wählen Serviceverbindungen aus. Erstellen Sie ein neues Element vom Typ Azure Resource Manager.

Jetzt benötigen wir alle IDs, die wir notiert haben. Klicken Sie auf Vollversion des Dienstverbindungsdialogs verwenden. Und wir geben alle Daten ein, die wir vom Service Principal erhalten haben. Klicken Sie auf „Bestätigen“. Wenn alles in Ordnung ist, speichern Sie die Verbindung. Jetzt können unsere Pipelines damit eine Verbindung zur Cloud herstellen.

3. Erstellen einer Pipeline
Kommen wir nun zum spaßigen Teil, dem Aufbau der Pipeline selbst. Öffnen Sie das Menü Pipelines-Builds

Wir werden mit einem Menü zum Erstellen eines neuen Builds begrüßt, das standardmäßig versucht, eine YAML-Datei mit einer geeigneten Konfiguration für uns zu erstellen. Wir lehnen dies höflich ab und entscheiden uns für die klassische Variante. Es ist verständlich, dass Microsoft alles so machen möchte, wie es die Menschen tun, und die Möglichkeit bieten möchte, Pipelines so weit wie möglich über YAML anzupassen, aber die dürftige Dokumentation und einfach die praktische Inoperabilität vieler Module sagen uns, dass es noch zu früh ist, diese Funktionalität zu nutzen.

Aus der Vielfalt der Vorlagen benötigen wir eine einfache Empty Pipeline. Nach der Erstellung erwartet uns ein leeres Bearbeitungsfenster, in dem wir ziemlich viel Zeit verbringen werden.

Klicken Sie also auf + und finden Sie sich in einem bestimmten Modulspeicher wieder, von wo aus wir die folgenden Komponenten aus der Liste benötigen.

Bevor wir mit der Konfiguration der Pipeline-Aufgaben beginnen, müssen wir mehrere Dateien generieren und in das Projekt einfügen. Dies wird die ARM-Vorlage unserer virtuellen Maschine sein, die wir in Azure DevTest Labs generieren, ein Skript zum Abrufen der IP der Maschine nach ihrer Erstellung und, falls gewünscht, Skripte für unsere Tests oder das, worauf wir laufen wollen der Gastgeber.
4. Generierung der ARM-Vorlage
Um eine virtuelle Maschine zu erstellen, müssen wir zunächst eine Vorlage dafür generieren, eine JSON-Datei, die wir in den Projektcode einfügen, damit die Pipeline sie von dort lesen kann.
Wir gehen in unser Labor und suchen das Menü „Formeln“ (wiederverwendbare Basen). Klicken Sie auf „Neue erstellen“.

Wir sehen eine lange Liste mit Basis-Images, können die Maschinengröße auswählen und folgen dem gleichen Prozess wie beim Erstellen einer virtuellen Maschine. Wir gehen nicht näher auf diesen Schritt ein, sondern fahren direkt mit dem letzten Punkt in den Maschineneigenschaften fort: den Artefakten. Sie können beliebige Konfigurationen für Ihre Umgebung verwenden. Ich füge beispielsweise eine Maschine hinzu zu Domain Name Ich füge ein Dienstkonto als Administrator hinzu, damit sich die Pipeline mit diesem Konto an diesem Rechner anmelden kann. Die genaue Vorgehensweise kann variieren, aber für erfolgreiche Codetests benötigen wir ein Artefakt, das wir später genauer erläutern werden. Um sicherzustellen, dass die neueste Version der zu testenden Software auf unserem Rechner installiert ist, verwenden wir das Artefakt „Azure Pipelines-Artefakt herunterladen und Skript ausführen“. Erinnern Sie sich an den Anfang, als ich erwähnte, dass ein Build mit dem Anwendungsinstallationsprogramm irgendwo kompiliert wird? Nun müssen wir der virtuellen Maschine, genauer gesagt der Vorlage, mitteilen, dass sie dieses Artefakt herunterladen soll. Und nicht nur herunterladen, sondern auch installieren. Dazu füllen wir spezielle Felder aus, in denen wir Projekt, Build-Name und geheimen Schlüssel angeben. Der geheime Schlüssel wird, wie in allen ähnlichen Systemen, im Konto – in diesem Fall in Azure DevOps – generiert und in den Geheimnissen Ihres Labs gespeichert. Eine kleine Einschränkung gibt es hierbei: Wir speichern ihn zwar in den Geheimnissen, die Vorlage benötigt ihn jedoch nicht. Der Start erfolgt durch einen anderen Benutzer innerhalb der Pipeline, daher müssen wir den geheimen Schlüssel erneut manuell in die Vorlage eingeben.
Ein weiteres Artefakt, das enthalten sein muss, ist „Configure WinRM“; wir benötigen es für den späteren Zugriff auf die Maschine. Es gibt nur einen Parameter: Hostname. Da wir es nicht im Voraus wissen, verwenden wir die Variable %COMPUTERNAME%.

Wir haben also alle notwendigen Artefakte hinzugefügt. Kommen wir nun zu dem Grund, warum wir überhaupt hierher gekommen sind. Wir nehmen die generierte ARM-Vorlage auf der Registerkarte „Erweitert“ desselben Formelerstellungsfensters heraus.

Wir kopieren den Inhalt der Seite in die Datei VMtemplate.json und legen sie im Stammverzeichnis des Projekts ab. Wir brauchen die Cloud nicht mehr, kehren wir zur Pipeline zurück.
5. Pipeline-Konfiguration
Beginnen wir mit dem Wichtigsten und Interessantesten, der Erstellung einer virtuellen Maschine. Dafür haben wir all diese Integrationen und Vorlagen erstellt. Im Punkt Azure RM Subscription wählen wir unsere Service-Verbindung aus, die wir in Schritt 2 konfiguriert haben. Als nächstes sollte die für uns verfügbare Laborumgebung auftauchen. Dann wählen wir den von uns generierten JSON aus und definieren einige erforderliche Variablen. Der Login und das Passwort für die Maschine können entweder direkt oder über Variablen festgelegt werden, aber ich bin mir überhaupt nicht sicher, ob es funktioniert, egal was ich dort geschrieben habe, ich konnte mich mit diesen Zugangsdaten nicht an der Maschine anmelden, Hauptsache besteht darin, den Namen der Maschine so einzustellen, dass er dort möglichst immer eindeutig ist. Dazu verwende ich die Build-Umgebungsvariable.

Als nächstes legen wir einen weiteren wichtigen Punkt fest. Nachdem das Auto gestartet ist, müssen wir irgendwie seine Parameter kennen, oder besser noch, nicht für uns, sondern für die Pipeline. Dazu erstellen wir ein Skript, zum Beispiel GetLabVMParams.ps1, und legen es dort im Projekt ab. Ich habe den Skripttext von der Microsoft-Website übernommen, ihn aber leicht an meine Umgebung angepasst, weil... Er nahm PublicIP- und FQDN-Maschinen. Ich habe weder das eine noch das andere, aber ich habe eine PrivateIP, die nicht so einfach zu bekommen ist, deshalb habe ich ein Stück hinzugefügt.
Param( [string] $labVmId)
$labVmComputeId = (Get-AzureRmResource -Id $labVmId).Properties.ComputeId
# Get lab VM resource group name
$labVmRgName = (Get-AzureRmResource -Id $labVmComputeId).ResourceGroupName
# Get the lab VM Name
$labVmName = (Get-AzureRmResource -Id $labVmId).Name
# Get lab VM public IP address
# $labVMIpAddress = (Get-AzureRmPublicIpAddress -ResourceGroupName $labVmRgName -Name $labVmName).IpAddress
# Get lab VM FQDN
# $labVMFqdn = (Get-AzureRmPublicIpAddress -ResourceGroupName $labVmRgName -Name $labVmName).DnsSettings.Fqdn
# Get lab VM private IP address
$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
# Set a variable labVmRgName to store the lab VM resource group name
Write-Host "##vso[task.setvariable variable=labVmRgName;]$labVmRgName"
# Set a variable labVMIpAddress to store the lab VM Ip address
Write-Host "##vso[task.setvariable variable=labVMIpAddress;]$labVMIpAddress"
# Set a variable labVMFqdn to store the lab VM FQDN name
Write-Host "##vso[task.setvariable variable=labVMFqdn;]$labVMFqdn"
Write-Output $labVMIpAddress
Set-Item wsman:localhostclienttrustedhosts * -ForceVon allem, was das Skript liest, benötigen wir nur die Variable labVMIpAddress. Nun, das ist für mich, vielleicht brauchen Sie noch etwas anderes, deshalb habe ich nichts gelöscht und nur das Unnötige auskommentiert.
Ich erkläre auch die letzte Zeile des Skripts; sie ermöglicht unserer Build-Maschine den Zugriff auf jeden Host über WinRM.
Der nächste Schritt besteht darin, unser wunderbares Skript zu starten. Er benötigt die gleiche Verbindung zur Cloud, eine Eingabevariable mit der Maschinen-ID, die zu diesem Zeitpunkt bereits aus dem vorherigen Schritt bekannt ist. Wie? Hier müssen wir etwas Wunderbares wie Ausgabevariablen erwähnen. Jeder Schritt kann eine Liste von Variablen haben, die an die nächsten Schritte der Pipeline weitergegeben werden. Dementsprechend lautet diese Variable für unser Superskript labVMIpAddress. Vergessen Sie nicht, dies anzugeben.

Als nächstes mache ich ziemlich einfache Dinge, die zudem von Fall zu Fall variieren können. Ich führe ein Remote-Skript aus und erstelle eine Freigabe, in die ich dann meine Skripte hochlade.
New-Item “C:test" –type directory
New-SMBShare –Name “test” –Path “C:test” –FullAccess everyoneAus dem Namen der Aufgaben geht hervor, dass wir als Nächstes ein Beispielskript auf die Maschine kopieren und es in einem weiteren Schritt ausführen. Unsere Variable $(labVMIpAddress) wird uns als Adresse des Remote-Computers nützlich sein. Als nächstes verwenden wir die Aufgabe „Das Artefakt von den Bällen aufheben“ und kopieren die Ergebnisse der Skriptausführung in unsere Build-Umgebung. Anschließend verwenden wir dieselbe Standardaufgabe, um diese Dateien im Build-Artefakt zu speichern. Nachdem wir das Auto nicht mehr benötigen, besteht der letzte Schritt darin, es zu töten. Die Hauptschwierigkeit besteht, wie aus der Länge des Artikels hervorgeht, darin, die Cloud zu integrieren und Kontakt mit der von Ihnen erstellten virtuellen Maschine herzustellen. Dann können Sie so viel Spaß haben, wie Sie brauchen.
Dies ist mein erster Artikel, also urteilen Sie nicht zu hart, Kommentare sind willkommen.
Source: habr.com
