Übung: Hinzufügen eines Testauftrags zu Ihrem Workflow

Abgeschlossen

Das Sicherheitsteam Ihres Spielzeugunternehmens möchte, dass Sie überprüfen, ob auf Ihre Website nur über HTTPS zugegriffen werden kann. In dieser Übung konfigurieren Sie Ihren Workflow für die Ausführung einer Feuerprobe, welche die Vorgaben des Sicherheitsteams überprüft.

Während des Prozesses führen Sie die folgenden Aufgaben aus:

  • Fügen Sie ein Testskript zu Ihrer Repository hinzu.
  • Sie aktualisieren Ihre Workflowdefinition, um einen Testauftrag hinzuzufügen.
  • Sie führen den Workflow aus und beobachten, ob der Test Fehler verursacht.
  • Sie korrigieren die Bicep-Datei und beobachten, ob der Workflow erfolgreich ausgeführt wird.

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.

  1. Erstellen Sie in Visual Studio Code eine neue Datei im Ordner Bereitstellen mit dem Namen Website.Tests.ps1.

    Screenshot: Visual Studio Code-Explorer mit Ordner „deploy“ und der Testdatei

  2. Kopieren Sie den folgenden Testcode, und fügen Sie ihn 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"
        }
    
    }
    

    Das Ergebnis ist eine Pester-Testdatei. Hierfür ist ein Parameter mit dem Namen $HostName erforderlich. Es werden zwei Tests für den Hostnamen ausgeführt:

    • Versucht, ü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.
    • Versucht, ü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. In der Zusammenfassung finden Sie Links, unter denen Sie bei Interesse mehr erfahren können.

Veröffentlichen der Ausgabe Ihrer Bicep-Datei als Auftragsausgabe

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 Auftragsausgabe veröffentlichen.

  1. Öffnen Sie in Visual Studio Code die Datei workflow.yml im Ordner .github/workflows.

  2. Fügen Sie im Bereitstellungsauftrag (deploy) dem Schritt Deploy website eine id hinzu, damit Sie auf den Schritt verweisen können. Fügen Sie außerdem eine Auftragsausgabe hinzu, die die appServiceAppHostName-Ausgabe aus dem Bereitstellungsschritt kopiert:

    deploy:
      runs-on: ubuntu-latest
      environment: Website
      needs: preview
      outputs:
        appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }}
      steps:
      - uses: actions/checkout@v3
      - uses: azure/login@v1
        name: Sign in to Azure
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
      - uses: azure/arm-deploy@v1
        id: deploy
        name: Deploy website
        with:
          failOnStdErr: false
          deploymentName: ${{ github.run_number }}
          resourceGroupName: ${{ env.AZURE_RESOURCEGROUP_NAME }}
          template: ./deploy/main.bicep
          parameters: environmentType=${{ env.ENVIRONMENT_TYPE }}
    
  3. Speichern Sie die Datei .

Hinzufügen eines Feuerprobenauftrags zu Ihrem Workflow

Nun können Sie einen Feuerprobenauftrag hinzufügen, in dem Ihre Tests ausgeführt werden.

  1. Fügen Sie am Ende der Datei die folgende Definition für den Feuerprobenauftrag (smoke-test) hinzu:

    smoke-test:
      runs-on: ubuntu-latest
      needs: deploy
      steps:
      - uses: actions/checkout@v3
      - run: |
          $container = New-PesterContainer `
            -Path 'deploy/Website.Tests.ps1' `
            -Data @{ HostName = '${{needs.deploy.outputs.appServiceAppHostName}}' }
          Invoke-Pester `
            -Container $container `
            -CI
        name: Run smoke tests
        shell: pwsh
    

    Dieser Code definiert den Auftrag. Der Auftrag enthält einen Schritt zum Auschecken des Codes und einen weiteren zum Ausführen von Tests mit Pester.

    Die Auftragsdefinition verwendet die needs-Eigenschaft, um eine Abhängigkeit vom Auftrag deploy zu definieren. Durch diese Abhängigkeit wird sichergestellt, dass die Aufträge in der gewünschten Reihenfolge ausgeführt werden. Außerdem können Sie die Ausgaben des Auftrags deploy verwenden, wenn Sie die Feuerprobe ausführen.

    Hinweis

    PowerShell und Pester sind auf in GitHub gehosteten Runnern vorinstalliert. Sie müssen keine besonderen Vorkehrungen treffen, um diese in einem Skriptschritt zu verwenden.

  2. Speichern Sie die Datei .

Überprüfen und Committen Ihrer Workflowdefinition

  1. Überprüfen Sie, ob die Datei workflow.yml wie im folgenden Code aussieht:

    name: deploy-toy-website-test
    concurrency: toy-company
    
    on:
      push:
        branches:
          - main
    
    permissions:
      id-token: write
      contents: read
    
    env:
      AZURE_RESOURCEGROUP_NAME: ToyWebsiteTest
      ENVIRONMENT_TYPE: Test
    
    jobs:
      lint:
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v3
        - name: Run Bicep linter
          run: az bicep build --file deploy/main.bicep
    
      validate:
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v3
        - uses: azure/login@v1
          name: Sign in to Azure
          with:
            client-id: ${{ secrets.AZURE_CLIENT_ID }}
            tenant-id: ${{ secrets.AZURE_TENANT_ID }}
            subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        - uses: azure/arm-deploy@v1
          name: Run preflight validation
          with:
            deploymentName: ${{ github.run_number }}
            resourceGroupName: ${{ env.AZURE_RESOURCEGROUP_NAME }}
            template: ./deploy/main.bicep
            parameters: environmentType=${{ env.ENVIRONMENT_TYPE }}
            deploymentMode: Validate
    
      preview:
        runs-on: ubuntu-latest
        needs: [lint, validate]
        steps:
        - uses: actions/checkout@v3
        - uses: azure/login@v1
          name: Sign in to Azure
          with:
            client-id: ${{ secrets.AZURE_CLIENT_ID }}
            tenant-id: ${{ secrets.AZURE_TENANT_ID }}
            subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        - uses: azure/arm-deploy@v1
          name: Run what-if
          with:
            failOnStdErr: false
            resourceGroupName: ${{ env.AZURE_RESOURCEGROUP_NAME }}
            template: deploy/main.bicep
            parameters: >
              environmentType=${{ env.ENVIRONMENT_TYPE }}
            additionalArguments: --what-if
    
      deploy:
        runs-on: ubuntu-latest
        environment: Website
        needs: preview
        outputs:
          appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }}
        steps:
        - uses: actions/checkout@v3
        - uses: azure/login@v1
          name: Sign in to Azure
          with:
            client-id: ${{ secrets.AZURE_CLIENT_ID }}
            tenant-id: ${{ secrets.AZURE_TENANT_ID }}
            subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        - uses: azure/arm-deploy@v1
          id: deploy
          name: Deploy website
          with:
            failOnStdErr: false
            deploymentName: ${{ github.run_number }}
            resourceGroupName: ${{ env.AZURE_RESOURCEGROUP_NAME }}
            template: ./deploy/main.bicep
            parameters: environmentType=${{ env.ENVIRONMENT_TYPE }}
    
      smoke-test:
        runs-on: ubuntu-latest
        needs: deploy
        steps:
        - uses: actions/checkout@v3
        - run: |
            $container = New-PesterContainer `
              -Path 'deploy/Website.Tests.ps1' `
              -Data @{ HostName = '${{needs.deploy.outputs.appServiceAppHostName}}' }
            Invoke-Pester `
              -Container $container `
              -CI
          name: Run smoke tests
          shell: pwsh
    

    Wenn Ihre Datei anders aussieht, ändern Sie sie entsprechend diesem Beispiel, und speichern Sie sie dann.

  2. 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 job"
    git push
    

Ausführen des Workflows und Überprüfen der Testergebnisse

  1. Navigieren Sie in Ihrem Browser zu Ihrem Workflow.

  2. Wählen Sie die letzte Ausführung Ihres Workflows aus.

    Warten Sie, bis der Workflow die Aufträge lint, validate und preview abgeschlossen hat. Obwohl GitHub Actions die Seite automatisch mit dem aktuellen Status aktualisiert, sollten Sie die Seite gelegentlich aktualisieren.

  3. Wählen Sie die Schaltfläche Bereitstellungen überprüfen, die Umgebung Website und anschließend Genehmigen und bereitstellen aus.

    Warten Sie, bis die Workflowausführung abgeschlossen ist.

  4. Sie sehen, dass der Auftrag deploy erfolgreich abgeschlossen wurde. Der Auftrag smoke-test wird mit einem Fehler beendet.

    Screenshot der GitHub-Benutzeroberfläche mit Aufträgen der Workflowausführung. Der Feuerprobenauftrag meldet Fehler.

  5. Wählen Sie den Auftrag smoke-test aus, um die zugehörigen Details anzuzeigen.

  6. Die Ausgabe von smoke-test 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.

    Screenshot der GitHub-Benutzeroberfläche mit den Ergebnissen aus der Ausführung der Workflowtests, wobei der fehlerhafte Test hervorgehoben ist

    Dieser Text weist darauf hin, dass die Website nicht korrekt konfiguriert wurde, um die Vorgaben 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, können Sie diese korrigieren.

  1. Öffnen Sie in Visual Studio Code die Datei main.bicep im Ordner Bereitstellen.

  2. Suchen Sie die Definition für die App Service-App, und aktualisieren Sie sie so, dass sie die Eigenschaft httpsOnly im Bereich properties 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
            }
          ]
        }
      }
    }
    
  3. Speichern Sie die Datei .

  4. 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
    

Erneutes Ausführen des Workflows

  1. Navigieren Sie in Ihrem Browser zu Ihren Workflowausführungen.

  2. Wählen Sie die letzte Ausführung aus.

    Warten Sie, bis der Workflow die Aufträge lint, validate und preview abgeschlossen hat. Obwohl GitHub die Seite automatisch mit dem aktuellen Status aktualisiert, sollten Sie die Seite gelegentlich aktualisieren.

  3. Wählen Sie den Vorschauauftrag (preview) aus, und überprüfen Sie die What-If-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:
      - Delete
      + Create
      ~ Modify
      = Nochange
      * Ignore
    
    The deployment will update the following scope:
    
    Scope: /subscriptions/***/resourceGroups/ToyWebsiteTest
    
      ~ Microsoft.OperationalInsights/workspaces/workspace-abcdefghijklm [2022-10-01]
        - properties.retentionInDays: 30
        - properties.sku:
    
            name: "pergb2018"
    
        - properties.workspaceCapping:
    
            dailyQuotaGb: -1.0
    
      ~ Microsoft.Web/sites/toy-website-abcdefghijklm [2022-03-01]
        + properties.siteConfig.localMySqlEnabled:   false
        + properties.siteConfig.netFrameworkVersion: "v4.6"
        ~ properties.httpsOnly:                      false => true
    
      = Microsoft.Insights/components/toywebsite [2020-02-02]
      = Microsoft.Storage/storageAccounts/mystorageabcdefghijklm [2022-09-01]
      = Microsoft.Web/serverfarms/toy-website [2022-03-01]
      * microsoft.alertsmanagement/smartDetectorAlertRules/Failure Anomalies - toywebsite
    
    Resource changes: 2 to modify, 3 no change, 1 to ignore.
    
  4. Wechseln Sie zurück zur Workflowausführung.

  5. Wählen Sie die Schaltfläche Bereitstellungen überprüfen, die Umgebung Website und anschließend Genehmigen und bereitstellen aus.

    Warten Sie, bis die Workflowausführung abgeschlossen ist.

  6. Sie sehen, dass der gesamte Workflow erfolgreich abgeschlossen wurde, einschließlich des Auftrags smoke-test. Das bedeutet, dass beide Tests erfolgreich waren.

    Screenshot der GitHub-Benutzeroberfläche mit einer erfolgreichen Workflowausführung

Bereinigen der Ressourcen

Nachdem Sie die Übung abgeschlossen haben, können Sie die Ressourcen entfernen, damit sie Ihnen nicht in Rechnung gestellt 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