Übung: Hinzufügen einer Testphase zu Ihrer Pipeline
Das Sicherheitsteam Ihres Spielzeugunternehmens hat Sie gebeten zu überprüfen, ob auf Ihre Website nur über HTTPS zugegriffen werden kann. In dieser Übung konfigurieren Sie Ihre Pipeline, um einen Rauchtest auszuführen, der überprüft, ob die Anforderung des Sicherheitsteams erfüllt ist.
In dem Prozess gehen Sie wie folgt vor:
- Fügen Sie ein Testskript zu Ihrer Repository hinzu.
- Aktualisieren Sie Ihre Pipelinedefinition, um eine Testphase hinzuzufügen.
- Führen Sie die Pipeline aus, und beobachten Sie, ob der Test fehlschlägt.
- Korrigieren Sie die Bicep-Datei, und beobachten Sie, ob die Pipeline erfolgreich ausgeführt wurde.
Hinzufügen eines Testskripts
Zuerst fügen Sie ein Testskript hinzu, um zu überprüfen, ob auf die Website zugegriffen werden kann, wenn HTTPS verwendet wird und nicht darauf zugegriffen werden kann, wenn das nicht unsichere HTTP-Protokoll verwendet wird.
Erstellen Sie in Visual Studio Code eine neue Datei im Bereitstellungsordner . Benennen Sie die Datei Website.Tests.ps1.
Fügen Sie den folgenden Code in die Datei ein:
param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $HostName ) Describe 'Toy Website' { It 'Serves pages over HTTPS' { $request = [System.Net.WebRequest]::Create("https://$HostName/") $request.AllowAutoRedirect = $false $request.GetResponse().StatusCode | Should -Be 200 -Because "the website requires HTTPS" } It 'Does not serves pages over HTTP' { $request = [System.Net.WebRequest]::Create("http://$HostName/") $request.AllowAutoRedirect = $false $request.GetResponse().StatusCode | Should -BeGreaterOrEqual 300 -Because "HTTP is not secure" } }Dieser Code ist eine Pester-Testdatei. Hierfür ist ein Parameter mit dem Namen
$HostNameerforderlich. Es werden zwei Tests für den Hostnamen ausgeführt:- Versuchen Sie, über HTTPS eine Verbindung mit der Website herzustellen. Der Test besteht, wenn der Server mit einem HTTP-Antwortstatuscode antwortet, der zwischen 200 und 299 liegt und eine erfolgreiche Verbindung anzeigt.
- Versuchen Sie, über HTTP eine Verbindung mit der Website herzustellen. Der Test ist erfolgreich, wenn der Server mit dem HTTP-Antwortstatuscode 300 oder höher antwortet.
Für diese Übung müssen Sie die Details der Testdatei und deren Funktionsweise nicht verstehen. Wenn Sie interessiert sind, können Sie mehr erfahren, indem Sie sich die in der Modulzusammenfassung aufgeführte Ressource auschecken.
Veröffentlichung der Ausgabe Ihrer Bicep-Datei als Phasenausgabevariable
Für das Testskript, das Sie in den vorherigen Schritten erstellt haben, muss ein Hostname getestet werden. Ihre Bicep-Datei enthält bereits eine Ausgabe, aber bevor Sie sie in Ihren Feuerproben verwenden können, müssen Sie sie als Ausgabevariable für die Phase veröffentlichen.
Öffnen Sie in Visual Studio Code die Datei azure-pipelines.yml im Ordner deploy.
Aktualisieren Sie in der Stage Bereitstellen den Bereitstellungsschritt, um die Ausgaben in einer Variable zu veröffentlichen:
name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: $(ServiceConnectionName) deploymentName: $(Build.BuildNumber) location: $(deploymentDefaultLocation) resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) deploymentOutputs: deploymentOutputsIhr Bereitstellungsprozess verwendet dieselben Aufgaben wie zuvor, aber die Ausgaben der Bereitstellungen werden jetzt in einer Pipelinevariable namens
deploymentOutputsgespeichert. Die Ausgabevariable ist als JSON formatiert.Um die JSON-formatierten Ausgaben in Pipelinevariablen zu konvertieren, fügen Sie den folgenden Skriptschritt unterhalb des Bereitstellungsschritts hinzu:
echo "##vso[task.setvariable variable=appServiceAppHostName;isOutput=true]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppHostName.value')" name: SaveDeploymentOutputs displayName: Save deployment outputs into variables env: DEPLOYMENT_OUTPUTS: $(deploymentOutputs)Wenn die Bereitstellung erfolgreich abgeschlossen wurde, greift das Skript auf den Wert jeder Ausgabe aus der Bicep-Bereitstellung zu. Das Skript verwendet das Tool
jq, um auf den relevanten Teil der JSON-Ausgabe zuzugreifen. Der Wert wird anschließend in einer Stageausgabevariable mit demselben Namen wie die Bicep-Bereitstellungsausgabe veröffentlicht.Hinweis
Pester und jq sind auf von Microsoft gehosteten Agents für Azure Pipelines vorinstalliert. Sie müssen keine besonderen Vorkehrungen treffen, um diese in einem Skriptschritt zu verwenden.
Speichern Sie die Datei.
Hinzufügen einer Feuerprobenphase zu Ihrer Pipeline
Sie können jetzt eine Smoke-Test-Phase hinzufügen, in der Ihre Tests ausgeführt werden.
Fügen Sie am Ende der Datei die folgende Definition für Feuerprobe hinzu:
jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ] steps:Dieser Code definiert die Phase und einen Auftrag. Außerdem wird im Auftrag eine Variable mit dem Namen
appServiceAppHostNameerstellt. Diese Variable erhält ihren Wert aus der Ausgabevariablen, die Sie im vorherigen Abschnitt erstellt haben.Fügen Sie am Ende der Datei die folgende Schrittdefinition für die Phase Feuerprobe hinzu:
- task: PowerShell@2 name: RunSmokeTests displayName: Run smoke tests inputs: targetType: inline script: | $container = New-PesterContainer ` -Path 'deploy/Website.Tests.ps1' ` -Data @{ HostName = '$(appServiceAppHostName)' } Invoke-Pester ` -Container $container ` -CIIn diesem Schritt wird ein PowerShell-Skript ausgeführt, um das oben erstellte Testskript mit dem Testtool Pester auszuführen.
Fügen Sie am Ende der Datei die folgende Schrittdefinition für die Phase Feuerprobe hinzu:
name: PublishTestResults displayName: Publish test results condition: always() inputs: testResultsFormat: NUnit testResultsFiles: 'testResults.xml'In diesem Schritt wird die von Pester erstellte Testergebnisdatei als Pipeline-Testergebnis veröffentlicht. Sie sehen, wie die Ergebnisse in Kürze angezeigt werden.
Beachten Sie, dass die Schrittdefinition
condition: always()enthält. Mit dieser Bedingung wird Azure Pipelines mitgeteilt, dass die Testergebnisse immer veröffentlicht werden sollen, auch wenn der vorherige Schritt fehlschlägt. Diese Bedingung ist wichtig, da jeder fehlgeschlagene Test dazu führt, dass der Testschritt fehlschlägt, und normalerweise wird die Pipeline nach einem fehlgeschlagenen Schritt beendet.Speichern Sie die Datei.
Überprüfen und Committen Ihrer Pipelinedefinition
Vergewissern Sie sich, dass die Datei azure-pipelines.yml wie folgt aussieht:
trigger: batch: true branches: include: - main pool: Dafault variables: - name: deploymentDefaultLocation value: westus3 stages: - stage: Lint jobs: - job: LintCode displayName: Lint code steps: - script: | az bicep build --file deploy/main.bicep name: LintBicepCode displayName: Run Bicep linter - stage: Validate jobs: - job: ValidateBicepCode displayName: Validate Bicep code steps: - task: AzureResourceManagerTemplateDeployment@3 name: RunPreflightValidation displayName: Run preflight validation inputs: connectedServiceName: $(ServiceConnectionName) location: $(deploymentDefaultLocation) deploymentMode: Validation resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) - stage: Preview jobs: - job: PreviewAzureChanges displayName: Preview Azure changes steps: - task: AzureCLI@2 name: RunWhatIf displayName: Run what-if inputs: azureSubscription: $(ServiceConnectionName) scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: | az deployment group what-if \ --resource-group $(ResourceGroupName) \ --template-file deploy/main.bicep \ --parameters environmentType=$(EnvironmentType) - stage: Deploy jobs: - deployment: DeployWebsite displayName: Deploy website environment: Website strategy: runOnce: deploy: steps: - checkout: self - task: AzureResourceManagerTemplateDeployment@3 name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: $(ServiceConnectionName) deploymentName: $(Build.BuildNumber) location: $(deploymentDefaultLocation) resourceGroupName: $(ResourceGroupName) csmFile: deploy/main.bicep overrideParameters: > -environmentType $(EnvironmentType) deploymentOutputs: deploymentOutputs - bash: | echo "##vso[task.setvariable variable=appServiceAppHostName;isOutput=true]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppHostName.value')" name: SaveDeploymentOutputs displayName: Save deployment outputs into variables env: DEPLOYMENT_OUTPUTS: $(deploymentOutputs) - stage: SmokeTest jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ] steps: - task: PowerShell@2 name: RunSmokeTests displayName: Run smoke tests inputs: targetType: inline script: | $container = New-PesterContainer ` -Path 'deploy/Website.Tests.ps1' ` -Data @{ HostName = '$(appServiceAppHostName)' } Invoke-Pester ` -Container $container ` -CI - task: PublishTestResults@2 name: PublishTestResults displayName: Publish test results condition: always() inputs: testResultsFormat: NUnit testResultsFiles: 'testResults.xml'Wenn Die Datei nicht gleich aussieht, aktualisieren Sie sie entsprechend diesem Beispiel, und speichern Sie sie dann.
Committen und pushen Sie Ihre Änderungen in Ihr Git-Repository, indem Sie die folgenden Befehle im Visual Studio Code-Terminal ausführen:
git add . git commit -m "Add test stage" git push
Ausführen der Pipeline und Überprüfen des Testergebnisses
Wechseln Sie in Azure DevOps zu Ihrer Pipeline.
Wählen Sie die letzte Ausführung Ihrer Pipeline aus.
Warten Sie, bis die Pipeline die Phasen Lint, Überprüfen und Vorschau abgeschlossen hat. Obwohl Azure Pipelines die Seite automatisch mit dem neuesten Status aktualisiert, ist es ratsam, die Seite gelegentlich zu aktualisieren.
Wählen Sie die Schaltfläche Bewertung und dann Genehmigen aus.
Warten Sie, bis die Pipelineausführung abgeschlossen ist.
Sie sehen, dass die Phase Deploy erfolgreich abgeschlossen wurde. Die Phase SmokeTest wird mit einem Fehler abgeschlossen.
Wählen Sie die Registerkarte Tests aus.
Die Testzusammenfassung gibt an, dass zwei Tests ausgeführt wurden. Einer war erfolgreich, und einer hat Fehler verursacht. Der fehlgeschlagene Test wird als Toy Website.Does not serve pages over HTTP aufgeführt.
Dieser Text gibt an, dass die Website nicht ordnungsgemäß konfiguriert ist, um die Anforderung Ihres Sicherheitsteams zu erfüllen.
Update der Bicep-Datei
Nachdem Sie nun ermittelt haben, dass Ihre Bicep-Definition die Anforderungen Ihres Sicherheitsteams nicht erfüllt, werden Sie diese beheben.
Öffnen Sie in Visual Studio Code die Datei main.bicep im Ordner deploy.
Suchen Sie die Definition für die Azure App Service-App, und aktualisieren Sie sie so, dass sie die
httpsOnlyEigenschaft in denpropertiesAbschnitt einschließt:resource appServiceApp 'Microsoft.Web/sites@2022-03-01' = { name: appServiceAppName location: location properties: { serverFarmId: appServicePlan.id httpsOnly: true siteConfig: { appSettings: [ { name: 'APPINSIGHTS_INSTRUMENTATIONKEY' value: applicationInsights.properties.InstrumentationKey } { name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' value: applicationInsights.properties.ConnectionString } ] } } }Speichern Sie die Datei.
Committen und pushen Sie Ihre Änderungen in Ihr Git-Repository, indem Sie die folgenden Befehle im Visual Studio Code-Terminal ausführen:
git add . git commit -m "Configure HTTPS on website" git push
Erneute Ausführung der Pipeline
Wechseln Sie in Ihrem Browser zu Ihrer Pipeline.
Wählen Sie die letzte Ausführung aus.
Warten Sie, bis die Pipeline die Phasen Lint, Überprüfen und Vorschau abgeschlossen hat. Obwohl Azure Pipelines die Seite automatisch mit dem neuesten Status aktualisiert, ist es ratsam, die Seite gelegentlich zu aktualisieren.
Wählen Sie die Phase Vorschau aus, und überprüfen Sie die Was-wäre-wenn-Ergebnisse erneut.
Beachten Sie, dass der What-If-Befehl die Änderung des Eigenschaftswerts
httpsOnlyerkannt hat:Resource and property changes are indicated with these symbols: + Create ~ Modify = Nochange The deployment will update the following scope: Scope: /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/ToyWebsiteTest ~ Microsoft.Web/sites/toy-website-nbfnedv766snk [2021-01-15] + properties.siteConfig.localMySqlEnabled: false + properties.siteConfig.netFrameworkVersion: "v4.6" ~ properties.httpsOnly: false => true = Microsoft.Insights/components/toywebsite [2020-02-02] = Microsoft.Storage/storageAccounts/mystoragenbfnedv766snk [2021-04-01] = Microsoft.Web/serverfarms/toy-website [2021-01-15] Resource changes: 1 to modify, 3 no change.Wechseln Sie zurück zur Ausführung der Pipeline.
Wählen Sie die Schaltfläche " Überprüfen" und dann " Genehmigen" aus.
Warten Sie, bis die Pipelineausführung abgeschlossen ist.
Sie sehen, dass die gesamte Pipeline erfolgreich abgeschlossen wurde, einschließlich der Phase SmokeTest. Dieses Ergebnis gibt an, dass beide Tests bestanden wurden.
Bereinigen der Ressourcen
Nachdem Sie die Übung abgeschlossen haben, können Sie die Ressourcen entfernen, damit Ihnen dafür keine Gebühren berechnet werden.
Führen Sie im Visual Studio Code-Terminal den folgenden Befehl aus:
az group delete --resource-group ToyWebsiteTest --yes --no-wait
Die Ressourcengruppe wird im Hintergrund gelöscht.
Remove-AzResourceGroup -Name ToyWebsiteTest -Force

