Erstellen Sie echte Azure DevOps-Pipelines für ARM-Vorlagen

Beim Online-Suchen finden Sie verschiedene Blog-Beiträge, Dokumentationen und Tutorials zu Azure DevOps. All diese Ressourcen sind wertvoll, aber selten wird ein realistisches Szenario detailliert erläutert. Viele übergehen den Sicherheitsaspekt und lassen Passwörter im Klartext für Einfachheit oder ein Endprodukt, das letztendlich nichts tut. Das wollen wir ändern.

In diesem Artikel/Tutorial lernen Sie Schritt für Schritt, wie Sie eine echte Azure DevOps-Release-Pipeline erstellen, die die Infrastruktur automatisiert. Genauer gesagt lernen Sie, wie Sie Azure DevOps verwenden, um eine kontinuierliche Bereitstellungspipeline zur Bereitstellung von Azure-Virtual Machines zu erstellen.

Am Ende dieses Projekts haben Sie eine voll funktionsfähige Azure-Pipeline. Mit einem einzigen GitHub-Repository-Commit wird es:

  • Eine temporäre Azure-Ressourcengruppe erstellen
  • Eine Azure-VM über eine ARM-Vorlage bereitstellen
  • Die genannte ARM-Vorlage in einer CI/CD-Pipeline einrichten
  • Bei jeder Änderung an der Vorlage einen Test zur Vorlagenvalidierung starten
  • Die ARM-Vorlage in Azure bereitstellen
  • Die bereitgestellte Infrastruktur testen
  • Alle Azure-Ressourcen abbauen

Legen wir los!

Projektübersicht

Dieses Projekt wird in sechs Hauptabschnitte unterteilt. Sie sind:

Azure-Ressourcenvorbereitung

In diesem Abschnitt lernen Sie, wie Sie alle erforderlichen Ressourcen in Azure einrichten. Hier werden Sie:

  • Erstellen Sie ein Azure-Dienstkonto für verschiedene Aufgaben in der Pipeline
  • Richten Sie einen Azure Key Vault ein, der von der Pipeline verwendete Secrets enthält
  • Legen Sie geeignete Zugriffsrichtlinien für ARM-Bereitstellungen und die Verwendung der Pipeline fest

Azure DevOps-Vorbereitung

Nachdem Sie alle Azure-Ressourcen eingerichtet haben, ist es Zeit, Azure DevOps für Ihre Pipeline vorzubereiten. In diesem Abschnitt werden Sie:

  • Installieren Sie die Build-Aufgabe Pester Test Runner in Ihrer Azure DevOps-Organisation
  • Erstellen Sie Verbindungsdienste, um Azure DevOps den Zugriff auf erforderliche Ressourcen zu ermöglichen
  • Erstellen Sie eine Azure DevOps-Variablen-Gruppe, die einen Key Vault verknüpft, um auf Azure Key Vault-Secrets zuzugreifen

Übersicht über Skript/Vorlage

Es gibt verschiedene Artefakte, die zu diesem Projekt gehören, einschließlich der ARM-Vorlage zum Aufbau des Servers und der Pester-Tests. In diesem Abschnitt werden wir kurz erläutern, was die Vorlage bereitstellt und was genau Pester im Pipeline-Test überprüft.

Erstellung der Pipeline

In diesem Abschnitt beginnt der eigentliche Spaß. Sie werden damit beginnen, die eigentliche Pipeline einzurichten. Hier lernen Sie, wie Sie diese gesamte Orchestrierung über eine einzige YAML-Datei einrichten können.

Sie werden die Pipeline mithilfe der Multi-Stage Pipeline-Benutzeroberfläche erstellen. Zum Zeitpunkt dieser Aufzeichnung ist diese Funktion in der Vorschau verfügbar.

Demonstration der Pipeline

Sobald die Pipeline erstellt ist, müssen Sie sie in Aktion sehen! In diesem Abschnitt lernen Sie, wie Sie die Pipeline auslösen und einfach dabei zusehen können, wie die Magie geschieht.

Bereinigung

Und schließlich, da dies nur eine Demonstration ist, erhalten Sie Zugriff auf ein Skript, mit dem alles, was während des Tutorials erstellt wurde, entfernt werden kann.

Klingt das nach viel? Das ist es auch! Aber keine Sorge, Sie lernen schrittweise, indem Sie jede Aufgabe einzeln angehen.

Wenn Sie ein Skript mit allen Azure CLI-Befehlen möchten, die zum Erstellen dieser Pipeline verwendet werden, finden Sie es im ServerAutomationDemo-Repository auf GitHub als demo.ps1.

Voraussetzungen

Sie werden viel lernen, aber es wird auch erwartet, dass Sie einige Dinge mitbringen. Wenn Sie dem Tutorial folgen möchten, stellen Sie bitte sicher, dass Sie Folgendes haben:

ARM deployments allowed to access the key vault
  • Cloud Shell oder PowerShell 6+, wenn Sie lokal arbeiten – Die Beispiele können in Windows PowerShell funktionieren, wurden jedoch nicht getestet. Alle Beispiele werden lokal über eine PowerShell-Konsole ausgeführt, aber das Cloud Shell funktioniert genauso gut. Sie werden den Aufbau der Pipeline automatisieren.
  • Azure CLI installiert (falls lokal ausgeführt) – Sie lernen in diesem Artikel, wie Sie Aufgaben mit der Azure CLI ausführen können. Die gleichen Schritte können jedoch auch über das Azure-Portal, PowerShell oder das Azure SDK durchgeführt werden.

Warnung: Die Aktionen, die Sie gleich ausführen werden, kosten echtes Geld, es sei denn, Sie verfügen über ein Azure-Guthaben. Die kostenintensivsten Ressourcen, die Sie in Azure erstellen werden, sind virtuelle Maschinen, aber nur vorübergehend.

Vor dem Start

In diesem Tutorial werden Sie viele Konfigurationen durchführen. Bevor Sie beginnen, stellen Sie bitte sicher, dass Sie die folgenden Informationen zur Hand haben.

  • Der Name des Azure-Abonnements, auf das die Ressourcen bereitgestellt werden – Die Beispiele werden Adam the Automator verwenden.
  • Die Abonnement-ID
  • Die Azure AD Mandanten-ID
  • Der Name der DevOps-Organisation – die Beispiele verwenden adbertram.
  • Die Region, in der Sie Ressourcen platzieren – die Beispiele verwenden eastus.
  • Der Name der Azure-Ressourcengruppe, in die der temporäre Schlüsseltresor platziert wird – die Beispiele verwenden ServerAutomationDemo.
  • A password to assign to the local administrator account on a deployed VM – the examples will use “I like azure.”.
  • Die URL zum GitHub Repo – die Beispiele verwenden https://github.com/adbertram/ServerAutomationDemo.

Anmeldung mit der Azure CLI

Seien Sie bereit, in dem Artikel viel mit der Azure CLI zu arbeiten. Ich mag die Azure PowerShell-Cmdlets, aber die Azure CLI ist derzeit in der Lage, mehr DevOps-Aufgaben zu erledigen.

Ihre erste Aufgabe besteht darin, zu einer PowerShell 6+ Konsole zu gelangen. Sobald Sie in der Konsole sind, authentifizieren Sie sich bei Azure mit dem Befehl az login. Dieser Befehl öffnet ein Browserfenster und fordert Sie zur Anmeldung an Ihrem Konto auf.

Nach der Authentifizierung stellen Sie sicher, dass Ihr Abonnement als Standard festgelegt ist. Das Festlegen als Standard verhindert, dass Sie es ständig angeben müssen.

az login
az account set --subscription 'Adam the Automator'

Vorbereitung der Azure-Ressourcen

Sobald Sie mit der Azure CLI angemeldet sind, geht es ans Eingemachte. Eine Azure Pipeline hat viele verschiedene Abhängigkeiten und verschiedene Einstellungen. In diesem ersten Abschnitt erfahren Sie, wie Sie einige Vorbereitungen treffen und Ihre Umgebung für Ihre Pipeline vorbereiten.

Installation der Azure CLI DevOps-Erweiterung

Sie benötigen eine Möglichkeit, die verschiedenen Azure DevOps-Komponenten mit der Azure CLI zu erstellen. Standardmäßig ist diese Funktionalität nicht enthalten. Um Azure DevOps von der Azure CLI aus zu verwalten, müssen Sie die DevOps-Erweiterung installieren.

Zum Glück ist die Installation der Erweiterung eine einzige Zeile, wie unten gezeigt.

az extension add --name azure-devops

Sobald die Erweiterung installiert wurde, legen Sie Ihre Organisation als Standard fest, um nicht immer wieder angeben zu müssen.

az devops configure --defaults organization=https://dev.azure.com/adbertram

Erstellen der Ressourcengruppe

Obwohl die Pipeline eine temporäre Ressourcengruppe erstellen wird, sollten Sie auch eine für alle Ressourcen in dieser Demo erstellen. Genauer gesagt ist diese Ressourcengruppe der Ort, an dem Sie ein Azure Key Vault erstellen werden.

az group create --location "eastus" --name "ServerAutomationDemo"

Erstellen des Azure Service Principal

Die nächste Aufgabe besteht darin, ein Azure-Dienstprinzipal zu erstellen. Sie benötigen einen Azure-Dienstprinzipal, um sich bei Azure Key Vault anzumelden. Sie werden diesen Dienstprinzipal auch verwenden, um eine Dienstverbindung zu authentifizieren. Erstellen Sie den Dienstprinzipal sowohl für den Schlüsselspeicher als auch für die spätere ARM-Bereitstellung wie unten dargestellt.

$spIdUri = "http://ServerAutomationDemo"
$sp = az ad sp create-for-rbac --name $spIdUri | ConvertFrom-Json

An diesem Punkt wäre es eine gute Idee, den Wert von $sp.appId irgendwo zu speichern. Wenn Sie später die Pipeline erstellen, werden Sie dies benötigen!

Sie werden einige PowerShell-Befehle in den Beispielen bemerken, z.B. ConvertFrom-Json. Da die Azure CLI nur JSON-Zeichenketten zurückgibt, ist es einfacher, Eigenschaften zu referenzieren, wenn sie in ein PowerShell-Objekt konvertiert werden.

Aufbau des Schlüsselspeichers

Die Pipeline in diesem Tutorial muss auf ein paar Passwörter verweisen. Anstatt Passwörter im Klartext zu speichern, machen wir es auf die richtige Art und Weise. Alle sensiblen Informationen werden in einem Azure Key Vault gespeichert.

Verwenden Sie den Befehl az keyvault create, um den Schlüsselspeicher wie unten dargestellt zu erstellen. Dieser Befehl erstellt den Schlüsselspeicher in der zuvor erstellten Ressourcengruppe. Beachten Sie auch den Schalter enabled-for-template-deployment. Dadurch wird die Zugriffsrichtlinie des Schlüsselspeichers geändert, um zukünftigen ARM-Bereitstellungen den Zugriff auf den Schlüsselspeicher zu ermöglichen.

az keyvault create --location $region --name "ServerAutomationDemo-KV" --resource-group "ServerAutomationDemo" --enabled-for-template-deployment true
Allowing ARM to access the keyvault

Erstellen von Schlüsselspeicher-Geheimnissen

Sobald der Schlüsseltresor erstellt ist, ist es an der Zeit, die Geheimnisse zu erstellen. Erstellen Sie für diese Demo zwei Geheimnisse mit den Namen ServerAutomationDemo-AppPw und StandardVmAdminPassword. Das Passwort AppPw ist das Passwort für das Dienstprinzipal. Das VM-Passwort wird dem lokalen Administrator-Konto auf der bereitgestellten VM zugewiesen.

az keyvault secret set --name "ServerAutomationDemo-AppPw" --value $sp.password --vault-name "ServerAutomationDemo-KV"
az keyvault secret set --name StandardVmAdminPassword --value "I like azure." --vault-name "ServerAutomationDemo-KV"

Beachten Sie, dass Sie in diesem Beispiel zuvor definierte PowerShell-Variablen verwenden. Hier geben Sie das Dienstprinzipal-Passwort ($sp.password), das zuvor erhalten wurde, an.

Zulassen des Pipeline-Zugriffs auf den Schlüsseltresor

Als Nächstes benötigt die Pipeline Berechtigungen, um auf den Schlüsseltresor zugreifen zu können. Lockern Sie die Zugriffsrichtlinie des Schlüsseltresors etwas. Geben Sie dem erstellten Dienstprinzipal Berechtigungen zum Verwalten von Schlüsseltresorgeheimnissen mit get und list.

az keyvault set-policy --name "ServerAutomationDemo-KV" --spn $spIdUri --secret-permissions get list

Vorbereitung von Azure DevOps

Jetzt sind alle Vorbereitungen für die Azure-Ressourcen abgeschlossen. Es ist an der Zeit, einige Vorbereitungen in Azure DevOps durchzuführen.

Installation der Pester-Erweiterung

Die erste Aufgabe besteht darin, die Azure DevOps-Erweiterung PesterRunner zu installieren. Die Pipeline wird zwei Sätze von Pester-Tests ausführen, um sicherzustellen, dass die VM-ARM-Bereitstellung erfolgreich war. Eine der einfachsten Möglichkeiten, Pester-Tests auszuführen, besteht in der Verwendung der Erweiterung PesterRunner.

Installieren Sie die Erweiterung mit dem folgenden Befehl.

az devops extension install --extension-id PesterRunner --publisher-id Pester

Erstellen des Azure DevOps-Projekts

Es ist jetzt an der Zeit, das Projekt zu erstellen, in dem die Pipeline erstellt wird. Das Erstellen einer Azure DevOps-Pipeline ist mit der Azure CLI ein Kinderspiel. Führen Sie einfach die unten stehenden Befehle aus, um das Projekt zu erstellen und das Projekt als Standard festzulegen.

az devops project create --name "ServerAutomationDemo"
az devops configure --defaults project=ServerAutomationDemo

Erstellen der Serviceverbindungen

Ihre Pipeline muss sich bei zwei Diensten authentifizieren – ARM und Ihrem GitHub-Repository. Hierfür müssen zwei Serviceverbindungen erstellt werden.

Erstellen Sie zunächst den ARM-Serviceendpunkt. Der folgende Befehl fordert Sie zur Eingabe des Kennworts für den Dienstprinzipal auf. Stellen Sie sicher, dass Sie es zuerst in der Konsole anzeigen und in die Zwischenablage kopieren.

Achten Sie darauf, Ihre Abonnement-ID, Mandanten-ID auszufüllen und den Abonnementnamen unten zu ersetzen.

## Führen Sie $sp.password aus und kopieren Sie es in die Zwischenablage
$sp.Password

## Erstellen Sie den Serviceendpunkt
az devops service-endpoint azurerm create --azure-rm-service-principal-id $sp.appId --azure-rm-subscription-id "YOURSUBSCRIPTIONIDHERE" --azure-rm-subscription-name 'Adam the Automator' --azure-rm-tenant-id $tenantId --name 'ARM'

Erstellen Sie als Nächstes eine Serviceverbindung für GitHub. Da die Pipeline über einen Git-Commit ausgelöst wird, muss sie in der Lage sein, das Repository zu lesen.

An dieser Stelle kommt der persönliche GitHub-Zugriffstoken ins Spiel. Sie müssen auch hier das Kennwort des Dienstprinzipals erneut einfügen. Sie verwenden denselben Dienstprinzipal für beide Serviceverbindungen.

$gitHubServiceEndpoint = az devops service-endpoint github create --github-url 'https://github.com/adbertram/ServerAutomationDemo' --name 'GitHub' | ConvertFrom-Json

## Fügen Sie bei Aufforderung den GitHub-Token ein

Erstellen der Variablen-Gruppe

Die Pipeline wird auf Schlüsseltresor-Geheimnisse für zwei Passwörter verweisen. Um dies sicher zu tun, müssen Sie eine Variable Group erstellen und sie mit dem Schlüsseltresor verknüpfen.

Erstellen Sie zuerst die Variable Group wie unten gezeigt.

az pipelines variable-group create --name "ServerAutomationDemo" --authorize true --variables foo=bar

Beachten Sie die Variable foo=bar? Diese wird nicht verwendet, aber eine einzelne Variable ist erforderlich, um die Variable Group zu erstellen.

Verknüpfen der Variable Group mit einem Schlüsseltresor

An diesem Punkt müssen Sie leider zum Azure DevOps-Portal gehen. Zum Zeitpunkt des Verfassens dieses Textes gibt es keine Möglichkeit, über die Azure CLI einen Schlüsseltresor mit einer Variable Group zu verknüpfen.

Navigieren Sie zum Azure DevOps-Projekt und klicken Sie auf Bibliothek. Dort sollten Sie die Variable Group ServerAutomationDemo sehen, wie unten gezeigt. Klicken Sie auf die Variable Group ServerAutomationDemo.

Available variable group

Sobald Sie in der Variable Group sind, klicken Sie auf Link secrets from an Azure key vault as variables. Sie werden dann gewarnt, dass alle Variablen gelöscht werden und klicken Sie auf Bestätigen. Wie Sie dies tun können, sehen Sie unten. Diese Aktion ist in Ordnung, da die Variable foo sowieso nur vorübergehend war.

Linking variable group to pipeline

Nach der Bestätigung wählen Sie die ARM Serviceverbindung und den zuvor erstellten Schlüsseltresor ServerAutomationDemo-KV aus, wie unten gezeigt. Klicken Sie auf Hinzufügen.

Setting the service connection

Überprüfen Sie nun beide zuvor erstellten Geheimnisse, wie unten gezeigt, und klicken Sie auf OK und Speichern, um die Änderungen zu speichern.

Selecting keyvault secrets for the pipeline to use

Projektdateien Übersicht

Wenn Sie es bis hierhin geschafft haben, herzlichen Glückwunsch! Sie sind nun bereit, mit dem Bau der Pipeline zu beginnen. Aber warten Sie…es gibt noch mehr!

Um den Aufbau einer Azure Pipeline realitätsnah zu gestalten, wird in diesem Tutorial eine Pipeline mit „Unit“ und „Acceptance“ Tests erstellt. Dies macht das Tutorial interessanter, erfordert aber auch zusätzliche Erläuterungen, was genau passiert.

Im GitHub-Repository für dieses Tutorial finden Sie einige Dateien, wie unten dargestellt. Jetzt wäre ein guter Zeitpunkt, entweder dieses Repository zu klonen oder Ihre eigene Version aus den Dateien zu erstellen.

GitHub files list
  • azure-pipelines.yml – Die endgültige YAML-Pipeline
  • connect-azure.ps1 – PowerShell-Skript zur Authentifizierung bei einem Azure-Abonnement
  • server.infrastructure.tests.ps1 – Ein einfacher Pester-Test, um die VM-Konfiguration zu bestätigen
  • server.json – Eine Azure ARM-Vorlage zur Bereitstellung einer VM
  • server.parameters.json – Eine Azure ARM-Parameter-Vorlage, die der ARM-Vorlage Parameterwerte liefert.

Vergewissern Sie sich, dass Sie in der Datei server.parameters.json Ihre Abonnement-ID und den Namen des Schlüsseltresors für den Schlüsseltresor IT ersetzen.

  • server.templates.tests.ps1 – Pester-„Unit“-Tests zur Bestätigung der Gültigkeit der ARM-Vorlage

Sie werden gleich sehen, wie diese Dateien in der Pipeline zusammenspielen.

Erstellen der Pipeline

Angenommen, Sie haben mein GitHub-Repository geklont oder ein eigenes eingerichtet, ist es an der Zeit, die Pipeline zu erstellen! Führen Sie dazu den Befehl az pipelines create aus. Der folgende Befehl erstellt eine Pipeline namens ServerAutomationDemo und verwendet das bereitgestellte GitHub-Repository als Auslöser. Es wird den master-Zweig betrachten und die zuvor erstellte Service-Verbindung verwenden.

az pipelines create --name "ServerAutomationDemo" --repository "https://github.com/adbertram/ServerAutomationDemo" --branch master --service-connection $gitHubServiceEndpoint.id --skip-run

Je nachdem, ob Sie die Datei azure-pipelines.yml in Ihrem GitHub-Repository haben oder nicht, erhalten Sie möglicherweise ein Feedback wie unten dargestellt. In jedem Fall wird Ihre Konsole ähnlich aussehen. Stellen Sie sicher, dass Sie Ihren persönlichen Zugriffstoken für GitHub bereit haben!

Creating the Azure DevOps pipeline with the Azure CLI

Überprüfung der YAML-Pipeline

Zu diesem Zeitpunkt ist Ihre Pipeline bereit zum Ausführen, aber es ist wichtig, die YAML-Pipeline zuerst zu verstehen. Werfen Sie einen Blick auf die Datei azure-pipelines.yml. Diese Datei ist die Pipeline, wenn Sie die Funktion der mehrstufigen YAML-Pipeline verwenden.

Lassen Sie uns die verschiedenen Komponenten dieser YAML-Pipeline genauer betrachten.

Der Auslöser

Da Sie eine CI-Pipeline erstellen, die automatisch ausgeführt wird, benötigen Sie einen Auslöser. Der unten stehende Auslöser gibt an, dass die Pipeline ausgeführt werden soll, wenn ein Commit im Git-Master-Zweig erkannt wird.

Beachten Sie auch den paths-Abschnitt. Standardmäßig wird der Pipeline ausgeführt, wenn ein Commit auf einer beliebigen Datei gemacht wird, sofern Sie Dateien oder Verzeichnisse in einem CI-Build nicht explizit einschließen oder ausschließen. Da dieses Projekt vollständig auf einer ARM-Vorlage aufgebaut ist, möchten Sie die Pipeline zum Beispiel nicht ausführen, wenn Sie eine Anpassung an einem Pester-Test vorgenommen haben.

trigger:
  branches:
    include:
      - master
  paths:
    include:
      - server.json
      - server.parameters.json

Der Pool

Jeder Build benötigt einen Agenten. Jeder Build-Agent muss auf einer virtuellen Maschine ausgeführt werden. In diesem Fall wird das VM-Image ubuntu-latest verwendet. Dieses Image ist das Standardimage, das beim Erstellen des Builds ursprünglich definiert wurde. Es wurde aufgrund der „Einfachheit“ dieser Pipeline nicht geändert.

pool:
  vmImage: "ubuntu-latest"  

Variablen

Als nächstes haben wir alle Variablen und die Variablen-Gruppe. Die verschiedenen Aufgaben in dieser Pipeline erfordern das Lesen von Werten wie der Azure-Abonnement-ID, der Mandanten-ID und der Anwendungs-ID für den Dienstprinzipal usw. Anstatt statische Werte in jeder Aufgabe zu replizieren, werden sie als Variablen definiert.

Beachten Sie auch das group-Element. Dieses Element verweist auf die zuvor erstellte Variablen-Gruppe. Ersetzen Sie nun die Werte subscription_id und tenant_id.

Erinnern Sie sich daran, dass Sie im Abschnitt „Erstellen des Azure-Dienstprincipals“ daran erinnert wurden, den Wert von $sp.appId irgendwo zu speichern? Hier wird er benötigt. Weisen Sie den Wert dieser Anwendungs-ID des Dienstprinzipals der Variable application_id wie unten gezeigt zu.

variables:
    - group: ServerAutomationDemo
    - name: azure_resource_group_name
      value: "ServerProvisionTesting-$(Build.BuildId)"
    - name: subscription_id
      value: "XXXXXXXXXXXXX"
    - name: application_id
      value: "XXXXXXXXXXXXX"
    - name: tenant_id
      value: "XXXXXXXXXXXX"

Beachten Sie den Wert der Variablen azure_resource_group_name. Innerhalb dieses Wertes sehen Sie $(Build.BuildId). Dies ist eine Systemvariable, die die Build-ID des aktuellen Jobs repräsentiert. In diesem Kontext wird sie verwendet, um sicherzustellen, dass die erstellte temporäre Ressourcengruppe eindeutig ist.

PowerShell Vorbereitungsaufgaben

Die nächsten Aufgaben rufen PowerShell-Code auf. Dieses Pipeline-Beispiel verwendet PowerShell, um eine temporäre Ressourcengruppe für Testzwecke zu erstellen und zu entfernen. In diesen Bereitstellungsaufgaben sehen Sie zwei Beispiele für das Aufrufen von PowerShell-Code.

Die erste Aufgabe ruft ein Skript namens connect-azure.ps1 auf, das im GitHub-Repo vorhanden ist. Diese Aufgabe authentifiziert sich für die Azure-Abonnement für die anschließenden Azure PowerShell-Befehle.

Bei dieser Azure PowerShell-Verbindungsaufgabe wird das Skript aufgerufen und ein Key Vault-Geheimniswert (ServerAutomationDemo-AppPw) und die Pipeline-Variablen subscription_id, application_id und tenant_id übergeben.

Die zweite Aufgabe führt PowerShell-Code inline aus, was bedeutet, dass kein Skript bereits vorhanden ist. Stattdessen wird der PowerShell-Code in der Pipeline-YAML selbst definiert, wobei der Wert der Pipeline-Variablen azure_resource_group_name verwendet wird.

- task: PowerShell@2
  inputs:
    filePath: "connect-azure.ps1"
    arguments: '-ServicePrincipalPassword "$(ServerAutomationDemo-AppPw)" -SubscriptionId $(subscription_id) -ApplicationId $(application_id) -TenantId $(tenant_id)'
- task: PowerShell@2
  inputs:
    targetType: "inline"
    script: New-AzResourceGroup -Name $(azure_resource_group_name) -Location eastus -Force

Pester Template Test

Als nächstes haben wir den ersten Pester-Test. In einer CI/CD-Pipeline wie dieser ist es wichtig, mehrere verschiedene Testebenen zu haben. Wenn Sie eine Pipeline für ein Softwareprojekt erstellen würden, könnten Sie verschiedene Unit-Tests erstellen.

Da dieses Beispiel-Pipeline um eine einzelne ARM-VM-Bereitstellung herum aufgebaut ist, werden die ersten „Einheits“tests verwendet, um die Gültigkeit der JSON-Vorlage zu überprüfen. In der Datei server.templates.tests.ps1 können Sie beliebig viele verschiedene Tests für die ARM-Vorlagendatei selbst hinzufügen.

Beachten Sie unten, dass die Pipeline verschiedene Systemvariablen verwendet. Diese Variablen verweisen auf den Dateispeicherort der Dateien, sobald sie auf den Build-Agenten gelangen.

Die PesterRunner-Aufgabe sendet die Testergebnisse an eine XML-Datei, die später in der Pipeline gelesen wird.

- task: Pester@0
  inputs:
    scriptFolder: "@{Path='$(System.DefaultWorkingDirectory)/server.template.tests.ps1'; Parameters=@{ResourceGroupName='$(azure_resource_group_name)'}}"
    resultsFile: "$(System.DefaultWorkingDirectory)/server.template.tests.XML"
    usePSCore: true
    run32Bit: False

Die ARM-VM-Bereitstellung

Wir sind jetzt bei der ARM-Bereitstellung angekommen. Da die gesamte Pipeline auf der Fähigkeit basiert, eine VM bereitzustellen, ist diese Aufgabe wichtig! Diese Aufgabe bereitstellt die ARM-Vorlage und gibt alle erforderlichen Attribute an, die dafür erforderlich sind.

Beachten Sie das Attribut deploymentOutputs: arm_output. Im nächsten Schritt muss eine Aufgabe eine Verbindung zur bereitgestellten VM herstellen. Eine gute Möglichkeit, den DNS-Namen oder die IP-Adresse dieser VM zu erhalten, besteht darin, sie über die ARM-Bereitstellung zurückzugeben. Die Option deploymentOutputs erstellt eine Pipeline-Variable, auf die in anderen Aufgaben verwiesen werden kann.

- task: AzureResourceManagerTemplateDeployment@3
  inputs:
    deploymentScope: "Resource Group"
    azureResourceManagerConnection: "ARM"
    subscriptionId: "1427e7fb-a488-4ec5-be44-30ac10ca2e95"
    action: "Create Or Update Resource Group"
    resourceGroupName: $(azure_resource_group_name)
    location: "East US"
    templateLocation: "Linked artifact"
    csmFile: "server.json"
    csmParametersFile: "server.parameters.json"
    deploymentMode: "Incremental"
    deploymentOutputs: "arm_output"

Pester „Acceptance“ Test

Nachdem die VM bereitgestellt wurde, müssen Sie sicherstellen, dass sie ordnungsgemäß mit einem „Integration“ oder „Acceptance“ Test bereitgestellt wurde. Diese PesterRunner-Aufgabe ruft Pester auf und führt einen weiteren Satz von tests im Zusammenhang mit der Infrastruktur aus, um sicherzustellen, dass die VM erfolgreich bereitgestellt wurde.

Beachten Sie, dass wir den Wert der Ausgabe der ARM-Bereitstellung über den Parameter ArmDeploymentJsonOutput übergeben. Die Pester-Testskriptdatei hat einen definierten Parameter, der den Wert annimmt und den DNS-Hostname der virtuellen Maschine ausliest.

 - task: Pester@0
    inputs:
      scriptFolder: "@{Path='$(System.DefaultWorkingDirectory)/server.infrastructure.tests.ps1'; Parameters=@{ArmDeploymentJsonOutput='$(arm_output)'}}"
      resultsFile: "$(System.DefaultWorkingDirectory)/server.infrastructure.tests.XML"
      usePSCore: true
      run32Bit: False

Sie können unten sehen, wie das PowerShell-Skript server.infrastructure.tests.ps1 aussieht. Beachten Sie, dass es den DNS-Hostname der VM ausliest, um dann einen einfachen Portcheck durchzuführen.

$ArmDeploymentOutput = $ArmDeploymentJsonOutput | convertfrom-json

## Führe die Tests aus
describe 'Network Connnectivity' {
    it 'the VM has RDP/3389 open' {
        Test-Connection -TCPPort 3389 -TargetName $ArmDeploymentOutput.hostname.value -Quiet | should -Be $true
    }
}

„Acceptance“ Testbereinigung

Der einzige Grund, warum die Pipeline eine Infrastruktur bereitgestellt hat, bestand darin, die Gültigkeit der ARM-Vorlage zu testen. Da diese Infrastruktur nur vorübergehend ist, muss sie bereinigt werden. In der letzten PowerShell-Aufgabe entfernt die Pipeline die zuvor erstellte Ressourcengruppe und alles darin.

- task: PowerShell@2
  inputs:
    targetType: "inline"
    script: Get-AzResourceGroup -Name $(azure_resource_group_name) | Remove-AzResourceGroup -Force

Pester Testergebnisse veröffentlichen

Und schließlich sind wir bei den letzten Aufgaben angekommen. Azure Pipelines hat eine Aufgabe namens Testergebnisse veröffentlichen. Diese Aufgabe liest eine XML-Datei auf dem Build-Agenten und zeigt Testergebnisse in Azure DevOps an. Dies ist eine praktische Möglichkeit, um die Ergebnisse aller durchgeführten Tests einfach zu sehen.

- task: PublishTestResults@2
  inputs:
    testResultsFormat: "NUnit"
    testResultsFiles: "$(System.DefaultWorkingDirectory)/server.infrastructure.tests.XML"
    failTaskOnFailedTests: true

- task: PublishTestResults@2
  inputs:
    testResultsFormat: "NUnit"
    testResultsFiles: "$(System.DefaultWorkingDirectory)/server.template.tests.XML"
    failTaskOnFailedTests: true
The Tests section of a pipeline run

Verwendung der Azure DevOps-Pipeline

Zu guter Letzt sind wir bereit, die Pipeline auszuführen und zu sehen, wie sie funktioniert. In der Azure DevOps-Webbenutzeroberfläche stellen Sie sicher, dass Sie sich im Projekt ServerAutomationDemo befinden. Klicken Sie anschließend auf Pipelines und dort sollten Sie die ServerAutomationDemo-Pipeline sehen.

Eine Möglichkeit, die Pipeline auszuführen, besteht darin, auf die drei Punkte ganz rechts zu klicken, wie unten gezeigt. Klicken Sie dann auf Pipeline ausführen. Dadurch wird die Automatisierung gestartet.

Running a pipeline

Die Pipeline wird fortlaufend ausgeführt und jede Aufgabe gemäß den Anweisungen durchgeführt. Am Ende sollten Sie für jede Aufgabe, die vom Job ausgeführt wurde, grüne Häkchen sehen, wie unten gezeigt.

Successful job task execution

Aufräumen

Nachdem Sie mit der Pipeline herumgespielt haben und alles erreicht haben, sollten Sie aufräumen. Immerhin war dies nur ein Tutorial und keine Produktionsaufgabe!

Im Folgenden finden Sie einige Befehle zum Aufräumen aller in diesem Artikel erstellten Elemente. Dieser Code entfernt den Dienstprinzipal, die Azure AD-Anwendung, die Ressourcengruppe und alles in dieser Gruppe sowie das Azure DevOps-Projekt.

$spId = ((az ad sp list --all | ConvertFrom-Json) | ? { '<https://ServerAutomationDemo>' -in $_.serviceprincipalnames }).objectId
az ad sp delete --id $spId

## Ressourcengruppe entfernen
az group delete --name "ServerAutomationDemo" --yes --no-wait

## Projekt entfernen
$projectId = ((az devops project list | convertfrom-json).value | where { $_.name -eq 'ServerAutomationDemo' }).id
az devops project delete --id $projectId --yes

Zusammenfassung

Dieses Tutorial sollte Ihnen einen Einblick in den Aufbau einer echten Azure DevOps-Infrastrukturautomatisierungspipeline geben. Obwohl es unzählige andere Möglichkeiten gibt, solche Pipelines zu erstellen, sollten Ihnen die in diesem Tutorial erlernten Fähigkeiten bei vielen verschiedenen Konfigurationen helfen.

Jetzt legen Sie los und automatisieren Sie noch mehr!

Source:
https://adamtheautomator.com/azure-devops/