Cvičení – nasazení webové aplikace

Dokončeno

Ve vaší společnosti pro vývoj webů váš tým pro vývoj webů potvrdil nejnovější verzi webu do vašeho úložiště Git. Teď jste připraveni aktualizovat pracovní postup tak, aby se web sestavil, a nasadit ho do služby Aplikace Azure Service.

V procesu:

  • Přidejte nový volaný pracovní postup pro úlohu sestavení.
  • Aktualizujte pracovní postup tak, aby zahrnoval úlohu sestavení.
  • Přidejte nový orientační test.
  • Aktualizujte úlohu nasazení a nasaďte aplikaci.
  • Spuštění pracovního postupu.

Přidání opakovaně použitelného pracovního postupu pro úlohu sestavení

Tady přidáte novou definici úlohy, která obsahuje kroky potřebné k sestavení webové aplikace.

  1. Otevřete Visual Studio Code.

  2. Ve složce .github/workflows vytvořte nový soubor s názvem build.yml.

    Snímek obrazovky s Průzkumníkem editoru Visual Studio Code se zobrazenými složkami githubu a pracovními postupy a souborem buildu YML

  3. Do souboru pracovního postupu build.yml přidejte následující obsah:

    name: build-website
    
    on:
      workflow_call:
    
    jobs:
      build-application:
        name: Build application
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v3
    
        - name: Install .NET Core
          uses: actions/setup-dotnet@v3
          with:
            dotnet-version: 3.1
    
        - name: Build publishable website
          run: |
            dotnet publish --configuration Release
          working-directory: ./src/ToyCompany/ToyCompany.Website
    
        - name: Zip publishable website
          run: |
            zip -r publish.zip .
          working-directory: ./src/ToyCompany/ToyCompany.Website/bin/Release/netcoreapp3.1/publish
    
        - name: Upload website as workflow artifact
          uses: actions/upload-artifact@v3
          with:
            name: website
            path: ./src/ToyCompany/ToyCompany.Website/bin/Release/netcoreapp3.1/publish/publish.zip
    

    Úloha nainstaluje sadu .NET SDK pro sestavení řešení. Potom spustí krok sestavení, který převede zdrojový kód webové aplikace na zkompilovaný soubor připravený ke spuštění v Azure. Úloha pak komprimuje zkompilovaný artefakt a nahraje ho jako artefakt pracovního postupu.

  4. Uložte změny souboru.

Přidání úlohy sestavení do pracovního postupu

  1. Otevřete soubor workflow.yml.

  2. Pod úlohu: řádek před úlohu lint přidejte novou úlohu s názvem build, který používá opakovaně použitelný pracovní postup, který jste právě definovali:

    name: deploy-toy-website-end-to-end
    concurrency: toy-company
    
    on:
      push:
        branches:
          - main
      workflow_dispatch:
    
    permissions:
      id-token: write
      contents: read
    
    jobs:
    
      # Build the application and database.
      build:
        uses: ./.github/workflows/build.yml
    
      # Lint the Bicep file.
      lint:
        uses: ./.github/workflows/lint.yml
    
  3. Aktualizujte úlohu deploy-test tak, aby závisela na nové úloze sestavení:

    # Deploy to the test environment.
    deploy-test:
      uses: ./.github/workflows/deploy.yml
      needs: [build, lint]
      with:
        environmentType: Test
        resourceGroupName: ToyWebsiteTest
        reviewApiUrl: https://sandbox.contoso.com/reviews
      secrets:
        AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
        AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        reviewApiKey: ${{ secrets.REVIEW_API_KEY_TEST }}
    
  4. Aktualizujte produkční úlohu nasazení tak, aby závisela také na úlohách sestavení a lint.

    # Deploy to the production environment.
    deploy-production:
      uses: ./.github/workflows/deploy.yml
      needs:
      - lint
      - build
      - deploy-test
      with:
        environmentType: Production
        resourceGroupName: ToyWebsiteProduction
        reviewApiUrl: https://api.contoso.com/reviews
      secrets:
        AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
        AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        reviewApiKey: ${{ secrets.REVIEW_API_KEY_PRODUCTION }}
    

    Vzhledem k tomu, že produkční nasazení závisí na testovacím nasazení, nemusíte přesně specifikovat závislosti. Je ale vhodné, abyste se vyhnuli nesprávnému spuštění pracovního postupu, pokud změníte pořadí nebo odeberete úlohy nebo prostředí.

    Všimněte si, že seznam zadáváte needs dvěma různými způsoby – závislosti testovacího prostředí jsou uvedené na jednom řádku a produkční prostředí pomocí víceřádkového seznamu. Dva přístupy jsou ekvivalentní.

  5. Uložte změny souboru.

Aktualizace souboru orientačního testu

Vývojáři webu přidali na web koncový bod stavu. Tento koncový bod zkontroluje, jestli je web online a že se může připojit k databázi. Tady přidáte nový orientační test pro vyvolání kontroly stavu z pracovního postupu nasazení.

  1. Ve složce deploy otevřete soubor Website.Tests.ps1.

  2. Přidejte nový testovací případ, který vyvolá kontrolu stavu. Testovací případ selže, pokud kód odpovědi není 200, což značí úspěch:

    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"
        }
    
        It 'Returns a success code from the health check endpoint' {
          $response = Invoke-WebRequest -Uri "https://$HostName/health" -SkipHttpErrorCheck
          Write-Host $response.Content
          $response.StatusCode |
            Should -Be 200 -Because "the website and configuration should be healthy"
        }
    
    }
    
  3. Uložte změny souboru.

Přidání výstupu do souboru Bicep

Brzy přidáte krok nasazení, který publikuje web do služby Aplikace Azure Service. Krok publikování vyžaduje název aplikace App Service. V této části zveřejníte název aplikace jako výstup ze souboru Bicep.

  1. Otevřete soubor main.bicep ve složce deploy.

  2. Na konec obsahu souboru přidejte název aplikace App Service jako výstup:

    output appServiceAppName string = appServiceApp.name
    output appServiceAppHostName string = appServiceApp.properties.defaultHostName
    
  3. Uložte změny souboru.

Aktualizace úlohy nasazení pro rozšíření výstupu

Teď potřebujete aktualizovat úlohu nasazení , aby převzala hodnotu výstupu z nasazení Bicep a aby byla dostupná pro zbytek pracovního postupu.

  1. Otevřete soubor deploy.yml ve složce .github/workflows.

  2. V definici úlohy nasazení přidejte nový výstup pro appServiceAppName:

    deploy:
      needs: validate
      environment: ${{ inputs.environmentType }}
      runs-on: ubuntu-latest
      outputs:
        appServiceAppName: ${{ steps.deploy.outputs.appServiceAppName }}
        appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }}
      steps:
    

    Poznámka:

    Když začnete pracovat se souborem YAML v editoru Visual Studio Code, může se zobrazit několik červených vlnovek s informací, že došlo k problému. Důvodem je to, že přípona editoru Visual Studio Code pro soubory YAML někdy nesprávně odhadne schéma souboru.

    Problémy, které rozšíření hlásí, můžete ignorovat. Nebo pokud chcete, můžete do horní části souboru přidat následující kód, který potlačí odhad přípony:

    # yaml-language-server: $schema=./deploy.yml
    

Přidání úlohy pro nasazení webu

  1. Pod definicí úlohy nasazení a nad definicí úlohy orientačního testu definujte novou úlohu pro nasazení webu do služby App Service:

    deploy-website:
      needs: deploy
      environment: ${{ inputs.environmentType }}
      runs-on: ubuntu-latest
      steps:
      - uses: actions/download-artifact@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/webapps-deploy@v2
        name: Deploy website
        with:
          app-name: ${{ needs.deploy.outputs.appServiceAppName }}
          package: website/publish.zip
    

    Poznámka:

    Při odsazení souboru YAML buďte opatrní a ujistěte se, že je nová úloha odsazená na stejné úrovni jako úloha deploy . Pokud si nejste jistí, zkopírujte celý deploy.yml obsah souboru z příkladu v dalším kroku.

    Všimněte si, že úloha závisí na úloze nasazení pomocí klíčového needs slova. Tato závislost zajišťuje, že se web nenasadí, dokud nebude infrastruktura připravená. Tato úloha také umožňuje přístup k výstupu appServiceAppNamez úlohy nasazení .

    Všimněte si také, že tato úloha obsahuje kroky pro stažení artefaktů pracovního postupu a přihlášení k Azure. Každá úloha běží na vlastním spouštěči, takže musí být samostatná.

  2. Uložte změny souboru.

Ověřte obsah souboru deploy.yml a potvrďte změny.

  1. Ověřte, že váš soubor deploy.yml vypadá jako v následujícím příkladu:

    name: deploy
    
    on:
      workflow_call:
        inputs:
          environmentType:
            required: true
            type: string
          resourceGroupName:
            required: true
            type: string
          reviewApiUrl:
            required: true
            type: string
        secrets:
          AZURE_CLIENT_ID:
            required: true
          AZURE_TENANT_ID:
            required: true
          AZURE_SUBSCRIPTION_ID:
            required: true
          reviewApiKey:
            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 }}
               reviewApiUrl=${{ inputs.reviewApiUrl }}
               reviewApiKey=${{ secrets.reviewApiKey }}
             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 }}
               reviewApiUrl=${{ inputs.reviewApiUrl }}
               reviewApiKey=${{ secrets.reviewApiKey }}
             additionalArguments: --what-if
    
      deploy:
        needs: validate
        environment: ${{ inputs.environmentType }}
        runs-on: ubuntu-latest
        outputs:
          appServiceAppName: ${{ steps.deploy.outputs.appServiceAppName }}
          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 }}
               reviewApiUrl=${{ inputs.reviewApiUrl }}
               reviewApiKey=${{ secrets.reviewApiKey }}
    
      deploy-website:
        needs: deploy
        environment: ${{ inputs.environmentType }}
        runs-on: ubuntu-latest
        steps:
        - uses: actions/download-artifact@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/webapps-deploy@v2
          name: Deploy website
          with:
            app-name: ${{ needs.deploy.outputs.appServiceAppName }}
            package: website/publish.zip
    
      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
    
  2. Uložte změny souboru.

  3. V terminálu editoru Visual Studio Code potvrďte a nasdílejte změny do úložiště Git spuštěním následujících příkazů:

    git add .
    git commit -m "Build and deploy website application"
    git push
    
  4. To je poprvé, co jste do tohoto úložiště nasdíleli, takže se může zobrazit výzva k přihlášení.

    Ve Windows zadejte 1 pro ověření pomocí webového prohlížeče a vyberte Enter.

    V systému macOS vyberte Autorizovat.

  5. Zobrazí se okno prohlížeče. Možná se budete muset znovu přihlásit k GitHubu. Vyberte Autorizovat.

Spuštění pracovního postupu

  1. V prohlížeči přejděte na Akce.

    První spuštění pracovního postupu s popiskem Počáteční potvrzení se zobrazí jako selhání. GitHub automaticky spustil pracovní postup při vytváření úložiště. Selhalo, protože tajné kódy nebyly v té době připravené. Toto selhání můžete ignorovat.

  2. Vyberte pracovní postup deploy-toy-website-end.to-end.

  3. Vyberte poslední spuštění pracovního postupu.

  4. Počkejte, až se úloha sestavení úspěšně dokončí.

    Snímek obrazovky GitHubu, který zobrazuje úlohy spuštění pracovního postupu

  5. Počkejte, až se úloha nasazení nebo nasazení úspěšně dokončí.

    Některá upozornění jsou uvedena na panelu Poznámky . Všechna tato upozornění jsou způsobená způsobem, jakým Bicep zapisuje informační zprávy do protokolu pracovního postupu. Tato upozornění můžete ignorovat.

  6. Pracovní postup pak spustí úlohu deploy-test / smoke-test , ale orientační test selže:

    Snímek obrazovky GitHubu znázorňující úlohu orientačního testu pracovního postupu pro testovací prostředí Stav ukazuje, že úloha selhala.

  7. Výběrem úlohy deploy-test / smoke-test otevřete protokol pracovního postupu.

  8. Vyberte krok Spustit orientační testy, abyste zobrazili přidruženou část protokolu pracovního postupu:

    Snímek obrazovky GitHubu s protokolem spuštění pracovního postupu a zobrazeným výstupem orientačního testu Zvýrazní se výsledek testu stavu JSON.

    Všimněte si, že protokol pracovního postupu označuje, že web a konfigurace nejsou v pořádku. Došlo k problému s komunikací aplikace se službou Azure SQL Database. Zatím jste databázi nenasadili ani nenakonfigurovali, proto k ní web nemá přístup. Tento problém brzy vyřešíte.