Übung: Hinzufügen mehrerer Umgebungen zu Ihrem Workflow

Abgeschlossen

Nun können Sie Ihren Workflow für die Bereitstellung in Ihrer Test- und Produktionsumgebung aktualisieren. In dieser Lerneinheit aktualisieren Sie Ihren Workflow so, dass er aufgerufene Workflows verwendet, damit Sie die Aufträge in allen Umgebungen wiederverwenden können.

In dem Prozess gehen Sie wie folgt vor:

  • Hinzufügen eines wiederverwendbaren Workflows für den Lint-Auftrag.
  • Hinzufügen eines wiederverwendbaren Workflows, der die erforderlichen Aufträge für die Bereitstellung in einer beliebigen Umgebung definiert.
  • Aktualisieren des Workflows, damit die aufgerufenen Workflows verwendet werden.
  • Ausführen des Workflows und Anzeigen der Ergebnisse.

Hinzufügen eines wiederverwendbaren Workflows für den Lint-Auftrag

Der Lint-Auftrag wird während der Workflowausführung nur einmal ausgeführt, unabhängig davon, in wie vielen Umgebungen der Workflow eine Bereitstellung durchführt. Daher müssen Sie eigentlich keinen aufgerufenen Workflow für den Lint-Auftrag verwenden. Um die Definitionsdatei für den Hauptworkflow jedoch einfach und leicht lesbar zu halten, entscheiden Sie sich, den Lint-Auftrag in einer separaten Workflowdatei zu definieren.

  1. Erstellen Sie in Visual Studio Code eine neue Datei im Ordner .github/workflows namens lint.yml.

    Screenshot: Visual Studio Code-Explorer mit den Ordnern „.github“ und „workflows“ sowie der Datei „lint.yml“.

  2. Fügen Sie die folgende Workflowdefinition in die Datei ein:

    name: lint
    
    on:
      workflow_call:
    
    jobs:
      lint:
        name: Lint code
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v3
    
        - name: Lint code
          run: |
            az bicep build --file deploy/main.bicep
    

    Der Lint-Auftrag ist mit dem Lint-Auftrag identisch, der sich bereits im Workflow befindet, befindet sich jetzt aber in einer separaten Workflowdatei.

  3. Speichern Sie Ihre Änderungen, und schließen Sie die Datei.

Hinzufügen eines wiederverwendbaren Workflows für die Bereitstellung

Erstellen Sie einen wiederverwendbaren Workflow, der alle erforderlichen Aufträge zum Bereitstellen der einzelnen Umgebungen definiert. Sie verwenden Eingaben und Geheimnisse, um die Einstellungen anzugeben, die in den verschiedenen Umgebungen verschieden sein können.

  1. Erstellen Sie im Ordner .github/workflows eine neue Datei mit dem Namen deploy.yml.

    Screenshot: Visual Studio Code-Explorer mit den Ordnern „.github“ und „workflows“ sowie der Datei „deploy.yml“.

    Diese Datei stellt alle Bereitstellungsaktivitäten dar, die jeweils für eine Umgebung ausgeführt werden.

  2. Fügen Sie die folgenden Angaben für Workflownamen, Trigger, Eingaben und Geheimnisse in die Datei ein:

    name: deploy
    
    on:
      workflow_call:
        inputs:
          environmentType:
            required: true
            type: string
          resourceGroupName:
            required: true
            type: string
        secrets:
          AZURE_CLIENT_ID:
            required: true
          AZURE_TENANT_ID:
            required: true
          AZURE_SUBSCRIPTION_ID:
            required: true
    

    Hinweis

    Wenn Sie beginnen, mit Ihrer YAML-Datei in Visual Studio Code zu arbeiten, werden möglicherweise einige rote Wellenlinien angezeigt, die darauf hindeuten, dass ein Problem vorliegt. Dies liegt daran, dass die Visual Studio Code-Erweiterung für YAML-Dateien manchmal fälschlicherweise das Schema der Datei errät.

    Sie können die Probleme ignorieren, die die Erweiterung meldet. Wenn Sie möchten, können Sie den folgenden Code am Anfang der Datei hinzufügen, um das Raten durch die Erweiterung zu unterdrücken:

    # yaml-language-server: $schema=./deploy.yml
    
  3. Fügen Sie unter den Geheimnissen die Definition des Validierungsauftrags ein:

    jobs:
      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 }}
         - if: inputs.environmentType != 'Production'
           uses: azure/arm-deploy@v1
           name: Run preflight validation
           with:
             deploymentName: ${{ github.run_number }}
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             deploymentMode: Validate
         - if: inputs.environmentType == 'Production'
           uses: azure/arm-deploy@v1
           name: Run what-if
           with:
             failOnStdErr: false
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             additionalArguments: --what-if
    

    Beachten Sie, dass eine Bedingung auf die Aufträge angewendet wird. Die Preflightvalidierung wird nur für Nicht-Produktionsumgebungen ausgeführt. Der Was-wäre-wenn-Vorgang wird nur für die Produktionsumgebung ausgeführt. Im vorherigen Modul im Lernpfad haben Sie separate Aufträge für diese Vorgänge verwendet, in diesem Modul werden sie aber zusammengefasst, um den Workflow zu vereinfachen.

    Tipp

    YAML-Dateien berücksichtigen Einzüge. Unabhängig davon, ob Sie diesen Code eingeben oder einfügen, stellen Sie sicher, dass der Einzug korrekt ist. Später in dieser Übung sehen Sie die vollständige YAML-Workflowdefinition, sodass Sie überprüfen können, ob Ihre Datei übereinstimmt.

  4. Fügen Sie die Definition des Bereitstellungsauftrags unter dem Validierungsauftrag ein:

    deploy:
      needs: validate
      environment: ${{ inputs.environmentType }}
      runs-on: ubuntu-latest
      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 Bicep file
        with:
          failOnStdErr: false
          deploymentName: ${{ github.run_number }}
          resourceGroupName: ${{ inputs.resourceGroupName }}
          template: ./deploy/main.bicep
          parameters: >
            environmentType=${{ inputs.environmentType }}
    
  5. Fügen Sie die Definition der Buildakzeptanztestaufgabe unter dem Bereitstellungsauftrag ein:

    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
    
  6. Vergewissern Sie sich, dass die Datei deploy.yml jetzt wie im folgenden Beispiel aussieht:

    name: deploy
    
    on:
      workflow_call:
        inputs:
          environmentType:
            required: true
            type: string
          resourceGroupName:
            required: true
            type: string
        secrets:
          AZURE_CLIENT_ID:
            required: true
          AZURE_TENANT_ID:
            required: true
          AZURE_SUBSCRIPTION_ID:
            required: true
    
    jobs:
      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 }}
         - if: inputs.environmentType != 'Production'
           uses: azure/arm-deploy@v1
           name: Run preflight validation
           with:
             deploymentName: ${{ github.run_number }}
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             deploymentMode: Validate
         - if: inputs.environmentType == 'Production'
           uses: azure/arm-deploy@v1
           name: Run what-if
           with:
             failOnStdErr: false
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             additionalArguments: --what-if
    
      deploy:
        needs: validate
        environment: ${{ inputs.environmentType }}
        runs-on: ubuntu-latest
        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 Bicep file
          with:
            failOnStdErr: false
            deploymentName: ${{ github.run_number }}
            resourceGroupName: ${{ inputs.resourceGroupName }}
            template: ./deploy/main.bicep
            parameters: >
              environmentType=${{ inputs.environmentType }}
    
      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
    
  7. Speichern Sie die geänderte Datei.

Aktualisieren der Workflowdefinition zur Verwendung der Vorlagen

  1. Öffnen Sie die Datei workflow.yml im Ordner .github/workflows.

  2. Entfernen Sie den Inhalt des env:-Abschnitts, einschließlich der beiden Umgebungsvariablen. Sie werden bald durch umgebungsspezifische Variablen ersetzt.

  3. Entfernen Sie den Inhalt der lint:-Auftragsdefinition, und ersetzen Sie ihn durch den folgenden Code, damit die zuvor erstellte lint.yml-Datei verwendet wird:

    # Lint the Bicep file.
    lint:
      uses: ./.github/workflows/lint.yml
    
  4. Löschen Sie alles in der Datei unterhalb des Lint-Auftrags, den Sie aktualisiert haben.

  5. Fügen Sie am Ende der Datei den folgenden Code hinzu, um die Bereitstellung in der Testumgebung zu durchführen:

    # Deploy to the test environment.
    deploy-test:
      uses: ./.github/workflows/deploy.yml
      needs: lint
      with:
        environmentType: Test
        resourceGroupName: ToyWebsiteTest
      secrets:
        AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
        AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
  6. Fügen Sie unter dem Code, den Sie gerade hinzugefügt haben, den folgenden Code für die Bereitstellung in der Produktionsumgebung hinzu:

    # Deploy to the production environment.
    deploy-production:
      uses: ./.github/workflows/deploy.yml
      needs: deploy-test
      with:
        environmentType: Production
        resourceGroupName: ToyWebsiteProduction
      secrets:
        AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
        AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    

    Ihr aktualisierter Workflow führt den Lintauftrag einmal aus. Anschließend wird die Vorlagendatei deploy.yml zweimal aufgerufen: jeweils einmal pro Umgebung. Dadurch bleibt die Workflowdefinition klar und leicht verständlich. Die Kommentare in der YAML-Datei identifizieren die Zielumgebung jedes Auftrags.

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

    name: deploy-toy-website-environments
    concurrency: toy-company
    
    on:
      push:
        branches:
          - main
      workflow_dispatch:
    
    permissions:
      id-token: write
      contents: read
    
    jobs:
    
      # Lint the Bicep file.
      lint:
        uses: ./.github/workflows/lint.yml
    
      # Deploy to the test environment.
      deploy-test:
        uses: ./.github/workflows/deploy.yml
        needs: lint
        with:
          environmentType: Test
          resourceGroupName: ToyWebsiteTest
        secrets:
          AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
          AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
      # Deploy to the production environment.
      deploy-production:
        uses: ./.github/workflows/deploy.yml
        needs: deploy-test
        with:
          environmentType: Production
          resourceGroupName: ToyWebsiteProduction
        secrets:
          AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
          AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
  8. Speichern Sie die Änderungen.

  9. 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 reusable workflows"
    git push
    
  10. Da Sie zum ersten Mal an das Repository pushen, werden Sie möglicherweise aufgefordert, sich anzumelden.

    Geben Sie unter Windows 1 ein, um sich über einen Webbrowser zu authentifizieren, und drücken Sie die EINGABETASTE.

    Wählen Sie unter macOS Authorize (Autorisieren) aus.

  11. Ein Browserfenster wird geöffnet. Möglicherweise müssen Sie sich erneut bei GitHub anmelden. Wählen Sie Autorisieren.

Anzeigen der Workflowausführung

  1. Navigieren Sie in Ihrem Browser zu Actions.

    Für die erste Ausführung Ihres Workflows mit der Bezeichnung Initial commit (Erster Commit) wird ein Fehler angezeigt. GitHub hat den Workflow automatisch ausgeführt, als Sie das Repository erstellt haben. Der Fehler ist aufgetreten, da die Geheimnisse zu diesem Zeitpunkt nicht verfügbar waren. Diesen Fehler können Sie ignorieren.

  2. Wählen Sie den Workflow deploy-toy-website-environments aus.

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

    Beachten Sie, dass die Workflowausführung nun alle Aufträge anzeigt, die Sie in der YAML-Datei definiert haben.

    Im Bereich Annotations (Anmerkungen) werden einige Warnungen aufgeführt. All diese Warnungen sind darauf zurückzuführen, wie Bicep Informationsmeldungen in das Workflowprotokoll schreibt. Sie können diese Warnungen ignorieren.

  4. Warten Sie, bis der Workflow vor dem Auftrag deploy-production / deploy angehalten wurde. Es kann einige Minuten dauern, bis der Workflow diesen Punkt erreicht hat.

    Screenshot: GitHub-Benutzeroberfläche die anzeigt, dass die Workflowausführung zur Genehmigung angehalten wurde.

  5. Genehmigen Sie die Bereitstellung in der Produktionsumgebung, indem Sie auf die Schaltfläche Review deployments klicken.

  6. Wählen Sie die Production-Umgebung und dann die Schaltfläche Approve and deploy aus.

    Screenshot: GitHub-Benutzeroberfläche mit der Workflowgenehmigungsseite und hervorgehobener Schaltfläche zum Genehmigen und Bereitstellen.

    Warten Sie, bis die Ausführung des Workflows beendet wurde. Der Workflow wird erfolgreich beendet.

  7. Wählen Sie Code aus.

  8. Wählen Sie die Produktionsbereitstellung.

    Screenshot: GitHub-Benutzeroberfläche mit Anzeige der Codepageumgebung mit hervorgehobener Produktionsumgebung.

  9. Beachten Sie, dass auf dem Bereitstellungsbildschirm eine Übersicht über den Bereitstellungsverlauf der Produktionsumgebung angezeigt wird.

    Screenshot: GitHub-Benutzeroberfläche mit Anzeige der Produktionsumgebung und einer einzelnen Bereitstellung im Bereitstellungsverlauf.

  10. Wählen Sie den Bezeichner des Commits aus.

    Beachten Sie, dass in GitHub die Liste der in der Bereitstellung enthaltenen Commits angezeigt wird. Dadurch können Sie die Änderungen in Ihrer Umgebung im Laufe der Zeit sehen.

    Screenshot: GitHub-Benutzeroberfläche mit Anzeige der Bereitstellungsdetails der Produktionsumgebung und einer Liste von Commits.

  11. Navigieren Sie in Ihrem Browser zum Azure-Portal.

  12. Wechseln Sie zur Ressourcengruppe ToyWebsiteProduction.

  13. Öffnen Sie in der Liste der Ressourcen die Azure App Service-App.

    Screenshot: Azure-Portal mit Anzeige der App Service-App für die Produktion und den SKU-Details des App Service-Plans.

    Beachten Sie, dass der Typ des App Service-Plans S1 ist.

  14. Wechseln Sie zur App Service-App in der Ressourcengruppe ToyWebsiteTest.

    Beachten Sie, dass der Typ des App Service-Plans F1 ist. Die beiden Umgebungen verwenden unterschiedliche Einstellungen, wie Sie es in Ihrer Bicep-Datei definiert haben.