Exercício - Implantar um aplicativo Web

Concluído

Em sua empresa de brinquedos, sua equipe de desenvolvimento de sites comprometeu a versão mais recente do site com seu repositório Git. Agora, você está pronto para atualizar seu fluxo de trabalho para criar o site e implantá-lo no Serviço de Aplicativo do Azure.

No processo, você:

  • Adicione um novo fluxo de trabalho chamado para o trabalho de compilação.
  • Atualize o fluxo de trabalho para incluir o trabalho de compilação.
  • Adicione um novo teste de fumaça.
  • Atualize o trabalho de implantação para implantar o aplicativo.
  • Executar o fluxo de trabalho.

Adicionar um fluxo de trabalho reutilizável para o trabalho de compilação

Aqui, você adiciona uma nova definição de trabalho que contém as etapas necessárias para criar o aplicativo de site.

  1. Abra o Visual Studio Code.

  2. Na pasta .github/workflows, crie um novo arquivo chamado build.yml.

    Captura de tela do Visual Studio Code Explorer, com as pastas dot github e workflows e o arquivo build dot YML mostrado.

  3. Adicione o seguinte conteúdo ao arquivo de fluxo de trabalho build.yml :

    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
    

    O trabalho instala o SDK do .NET para criar a solução. Em seguida, ele executa uma etapa de compilação para transformar o código-fonte do aplicativo de site em um arquivo compilado pronto para ser executado no Azure. Em seguida, o trabalho compacta o artefato compilado e o carrega como um artefato de fluxo de trabalho.

  4. Guarde as alterações ao ficheiro.

Adicionar o trabalho de compilação ao fluxo de trabalho

  1. Abra o arquivo workflow.yml .

  2. Abaixo da linha jobs: , antes do trabalho lint , adicione um novo trabalho chamado build que usa o fluxo de trabalho reutilizável que você acabou de definir:

    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. Atualize o trabalho de teste de implantação para depender do novo trabalho de compilação :

    # 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. Atualize o trabalho de implantação-produção para também depender dos trabalhos de compilação e 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 }}
    

    Como a implantação de produção depende da implantação de teste, você não precisa especificar estritamente as dependências. Mas, é uma boa prática ser explícito, para evitar que seu fluxo de trabalho seja executado incorretamente se você reordenar ou remover seus trabalhos ou ambientes.

    Observe que você está especificando a needs lista de duas maneiras diferentes: as dependências da implantação do ambiente de teste são listadas em uma única linha e as do ambiente de produção usando uma lista de várias linhas. As duas abordagens são equivalentes.

  5. Guarde as alterações ao ficheiro.

Atualizar o arquivo de teste de fumaça

Os desenvolvedores do site adicionaram um ponto de extremidade de integridade ao site. Este ponto de extremidade verifica se o site está online e se pode chegar ao banco de dados. Aqui, você adiciona um novo teste de fumaça para invocar a verificação de integridade do seu fluxo de trabalho de implantação.

  1. Abra o arquivo Website.Tests.ps1 na pasta deploy .

  2. Adicione um novo caso de teste que invoque a verificação de integridade. O caso de teste falhará se o código de resposta não for 200, o que indica sucesso:

    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. Guarde as alterações ao ficheiro.

Adicionar saída ao arquivo Bicep

Em breve, você adicionará uma etapa de implantação que publica seu site no Serviço de Aplicativo do Azure. A etapa de publicação requer o nome do aplicativo do Serviço de Aplicativo. Aqui, você expõe o nome do aplicativo como uma saída do seu arquivo Bicep.

  1. Abra o arquivo main.bicep na pasta deploy .

  2. No final do conteúdo do arquivo, adicione o nome do aplicativo do Serviço de Aplicativo como saída:

    output appServiceAppName string = appServiceApp.name
    output appServiceAppHostName string = appServiceApp.properties.defaultHostName
    
  3. Guarde as alterações ao ficheiro.

Atualizar o trabalho de implantação para propagar a saída

Agora, você precisa atualizar seu trabalho de implantação para obter o valor da saída da implantação do Bicep e disponibilizá-la para o restante do fluxo de trabalho.

  1. Abra o arquivo deploy.yml na pasta .github/workflows .

  2. Na definição do trabalho de implantação , adicione uma nova saída para o appServiceAppName:

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

    Nota

    Quando você começa a trabalhar com seu arquivo YAML no Visual Studio Code, você pode ver algumas linhas onduladas vermelhas dizendo que há um problema. Isso ocorre porque a extensão de código do Visual Studio para arquivos YAML às vezes adivinha incorretamente o esquema do arquivo.

    Você pode ignorar os problemas que a extensão relata. Ou, se preferir, você pode adicionar o seguinte código à parte superior do arquivo para suprimir a adivinhação da extensão:

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

Adicionar um trabalho para implantar o site

  1. Abaixo da definição de tarefa de implantação e acima da definição de tarefa de teste de fumaça, defina um novo trabalho para implantar o site no Serviço de Aplicativo:

    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
    

    Nota

    Tenha cuidado com o recuo do arquivo YAML, garantindo que o novo trabalho seja recuado no mesmo nível do deploy trabalho. Se não tiver certeza, copie todo o conteúdo do arquivo deploy.yml do exemplo na próxima etapa.

    Observe que o trabalho depende do trabalho de implantação usando a needs palavra-chave. Essa dependência garante que o site não seja implantado até que a infraestrutura esteja pronta. Ele também permite que o trabalho acesse a appServiceAppName saída do trabalho de implantação .

    Além disso, observe que esse trabalho inclui etapas para baixar os artefatos de fluxo de trabalho e entrar no Azure. Cada trabalho é executado em seu próprio corredor, por isso precisa ser independente.

  2. Guarde as alterações ao ficheiro.

Verifique o conteúdo do arquivo deploy.yml e confirme as alterações

  1. Verifique se o arquivo deploy.yml se parece com o exemplo a seguir:

    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. Guarde as alterações ao ficheiro.

  3. No terminal do Visual Studio Code, confirme e envie suas alterações para o repositório Git executando os seguintes comandos:

    git add .
    git commit -m "Build and deploy website application"
    git push
    
  4. Esta é a primeira vez que você envia por push para este repositório, portanto, você pode ser solicitado a entrar.

    No Windows, digite 1 para autenticar usando um navegador da Web e selecione Enter.

    No macOS, selecione Autorizar.

  5. É apresentada uma janela do browser. Talvez seja necessário fazer login no GitHub novamente. Selecionar Autorizar.

Executar o fluxo de trabalho

  1. No navegador, vá para Ações.

    A primeira execução do fluxo de trabalho, rotulada como Confirmação inicial, é mostrada como uma falha. O GitHub executou automaticamente o fluxo de trabalho quando você criou o repositório. Falhou porque os segredos não estavam prontos naquele momento. Você pode ignorar essa falha.

  2. Selecione o fluxo de trabalho deploy-toy-website-end-to-end .

  3. Selecione a execução mais recente do seu fluxo de trabalho.

  4. Aguarde até que o trabalho de compilação seja concluído com êxito.

    Captura de tela do GitHub que mostra os trabalhos de execução do fluxo de trabalho.

  5. Aguarde até que o trabalho deploy-test/deploy seja concluído com êxito.

    Alguns avisos estão listados no painel Anotações . Todos esses avisos são devido à maneira como o Bicep grava mensagens informativas no log do fluxo de trabalho. Você pode ignorar esses avisos.

  6. Em seguida, o fluxo de trabalho executa o trabalho deploy-test/smoke-test , mas o teste de fumaça falha:

    Captura de tela do GitHub que mostra o trabalho de teste de fumaça da execução do fluxo de trabalho para o ambiente de teste. O status mostra que o trabalho falhou.

  7. Selecione o trabalho deploy-test / smoke-test para abrir o log do fluxo de trabalho.

  8. Selecione a etapa Executar testes de fumaça para exibir a seção associada do log de fluxo de trabalho:

    Captura de tela do GitHub mostrando o log de execução do fluxo de trabalho, com a saída do teste de fumaça exibida. O resultado do teste de integridade JSON é realçado.

    Observe que o log de fluxo de trabalho indica que o site e a configuração não estão íntegros. Há um problema com a comunicação do aplicativo com o Banco de Dados SQL do Azure. Você ainda não implantou ou configurou um banco de dados, e é por isso que o site não pode acessá-lo. Você corrigirá esse problema em breve.