Ü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 für die Ausführung einer Feuerprobe, welche die Anforderungen des Sicherheitsteams überprüft.
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
Hier fügen Sie ein Testskript hinzu, um zu überprüfen, ob die Website aufgerufen werden kann, wenn HTTPS verwendet wird, und nicht aufgerufen werden kann, wenn das weniger sichere HTTP verwendet wird.
Erstellen Sie in Visual Studio Code eine neue Datei im Ordner Bereitstellen mit dem Namen 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
$HostName
erforderlich. Es werden zwei Tests für den Hostnamen ausgeführt:- Versuchen Sie, über HTTPS eine Verbindung mit der Website herzustellen. Der Test ist erfolgreich, wenn der Server mit einem HTTP-Antwortstatuscode zwischen 200 und 299 antwortet, was auf eine erfolgreiche Verbindung hinweist.
- 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 ist es nicht wichtig, dass Sie die Details der Testdatei und ihre Funktionsweise verstehen. Über die Links in der Zusammenfassung erhalten Sie weitere Informationen.
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 Bereitstellen.
Aktualisieren Sie in der Stage Bereitstellen den Bereitstellungsschritt, um die Ausgaben in einer Variable zu veröffentlichen:
- 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
Ihr Bereitstellungsprozess verwendet dieselben Aufgaben wie zuvor, aber die Ausgaben der Bereitstellungen werden in einer Pipelinevariable namens
deploymentOutputs
gespeichert. 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:
- 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)
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. Anschließend wird der Wert 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
Nun können Sie eine Feuerprobenphase hinzufügen, in der Ihre Tests ausgeführt werden.
Fügen Sie am Ende der Datei die folgende Definition für Feuerprobe hinzu:
- stage: SmokeTest jobs: - job: SmokeTest displayName: Smoke test variables: appServiceAppHostName: $[ stageDependencies.Deploy.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ]
Dieser Code definiert die Phase und einen Auftrag. Außerdem wird im Auftrag eine Variable mit dem Namen
appServiceAppHostName
erstellt. 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:
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
In 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:
- task: PublishTestResults@2 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 besonders wichtig, da jeder fehlgeschlagene Test dazu führt, dass der Testschritt scheitert, und die Pipeline normalerweise nach einem fehlgeschlagenen Schritt nicht mehr ausgeführt wird.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: vmImage: ubuntu-latest 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'
Falls nicht, aktualisieren Sie sie entsprechend diesem Beispiel, und speichern Sie sie.
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 Ihrem Browser 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 aktuellen Status aktualisiert, sollten Sie die Seite gelegentlich auch manuell 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 ist fehlgeschlagen. Der fehlgeschlagene Test wird als Toy Website.Does not serve pages over HTTP aufgeführt.
Dieser Text weist darauf hin, dass die Website nicht ordnungsgemäß konfiguriert wurde, um die Anforderungen 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 Bereitstellen.
Suchen Sie die Definition für die App Service-App, und aktualisieren Sie sie so, dass sie die Eigenschaft
httpsOnly
im Bereichproperties
enthält: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 aktuellen Status aktualisiert, sollten Sie die Seite gelegentlich auch manuell 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
httpsOnly
erkannt hat:Resource and property changes are indicated with these symbols: + Create ~ Modify = Nochange The deployment will update the following scope: Scope: /subscriptions/f0750bbe-ea75-4ae5-b24d-a92ca601da2c/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.
Klicken Sie auf die Schaltfläche Bewertung und dann auf Genehmigen.
Warten Sie, bis die Pipelineausführung abgeschlossen ist.
Sie sehen, dass die gesamte Pipeline erfolgreich abgeschlossen wurde, einschließlich der Phase SmokeTest. Das bedeutet, dass beide Tests erfolgreich waren.
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