Упражнение. Добавление задания тестирования в рабочий процесс

Завершено

Команда безопасности вашей компании по безопасности toy хочет убедиться, что ваш веб-сайт доступен только через HTTPS. В этом упражнении вы настроите рабочий процесс для выполнения теста состояния, который проверяет соответствие требованию команды обеспечения безопасности.

Во время процесса вы выполните следующие задачи:

  • Добавьте в репозиторий сценарий теста.
  • Обновите определение рабочего процесса, чтобы добавить задание тестирования.
  • Запустите рабочий процесс и обратите внимание на сбой теста.
  • Исправьте файл Bicep и понаблюдайте за успешным выполнением рабочего процесса.

Добавление сценария теста

Здесь вы добавляете сценарий теста, чтобы убедиться в доступности веб-сайта при использовании протокола HTTPS и недоступности при использовании незащищенного протокола HTTP.

  1. В Visual Studio Code создайте новый файл Website.Tests.ps1 в папке deploy.

    Снимок экрана: Visual Studio Code Explorer с папкой развертывания и тестовым файлом.

  2. Скопируйте и вставьте следующий тестовый код в файл:

    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"
        }
    
    }
    

    Результатом является тестовый файл Pester. Для этого требуется параметр с именем $HostName. Он выполняет два теста для имени узла:

    • Пытается подключиться к веб-сайту по протоколу HTTPS. Тест считается пройденным, если сервер возвращает код состояния HTTP-ответа в диапазоне от 200 до 299, что говорит об успешном подключении.
    • Пытается подключиться к веб-сайту по протоколу HTTP. Тест считается пройденным, если сервер возвращает код состояния HTTP-ответа от 300.

    Для целей этого упражнения необязательно полностью понимать тестовый файл и принцип его работы. В сводке представлены ссылки, чтобы вы могли ознакомиться с дополнительными сведениями.

Публикация выходных данных файла Bicep в качестве выходных данных задания

Сценарий теста, созданный на предыдущих шагах, требует имя узла для проверки. Файл Bicep уже содержит выходные данные, однако прежде чем использовать его в тестах состояния, необходимо опубликовать его в качестве выходных данных задания.

  1. В Visual Studio Code откройте файл workflow.yml в папке .github/workflows.

  2. В задании развертывания добавьте id к шагу Deploy website, чтобы можно было ссылаться на шаг. Кроме того, добавьте выходные данные задания, которое копирует выходные данные appServiceAppHostName из шага развертывания:

    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. Сохраните файл.

Добавление задания тестирования состояния в рабочий процесс

Теперь можно добавить задание тестирования состояния, в котором выполняются тесты.

  1. В нижней части файла добавьте следующее определение задания тестирования состояния:

    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
    

    Этот код определяет задание. Задание содержит шаг для извлечения кода и шаг для выполнения тестов с помощью Pester.

    Определение задания использует свойство needs для определения зависимости от задания развертывания. Эта зависимость гарантирует выполнение заданий в нужной последовательности. Это также позволяет использовать выходные данные задания развертывания при выполнении тестов состояния.

    Примечание.

    PowerShell и Pester предварительно установлены в средствах выполнения, размещенных на GitHub. Для их использования в шаге скрипта ничего делать не нужно.

  2. Сохраните файл.

Проверка и фиксация определения рабочего процесса

  1. Убедитесь, что файл workflow.yml выглядит следующим образом:

    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
    

    Если файл выглядит иначе, обновите его в соответствии с этим примером, а затем сохраните его.

  2. Зафиксируйте и отправьте изменения в репозиторий Git, выполнив следующие команды в терминале Visual Studio Code:

    git add .
    git commit -m "Add test job"
    git push
    

Запуск рабочего процесса и проверка результатов теста

  1. В браузере перейдите к рабочему процессу.

  2. Выберите последнее выполнение рабочего процесса.

    Подождите, пока рабочий процесс завершит задания анализа кода, проверки и предварительного просмотра. Хотя GitHub Actions автоматически обновляет страницу с учетом последнего состояния, рекомендуется периодически обновлять страницу.

  3. Нажмите кнопку "Рецензирование развертываний" , выберите среду веб-сайта , а затем выберите " Утвердить" и развернуть.

    Дождитесь завершения рабочего процесса.

  4. Обратите внимание, что задание развертывания успешно завершено. Задание тестирования состояния завершается с ошибкой.

    Снимок экрана: интерфейс GitHub с выполнением заданий рабочего процесса. Задание тестирования состояния завершилось сбоем.

  5. Выберите задание тестирования состояния, чтобы просмотреть сведения о нем.

  6. Обратите внимание, что выходные данные теста состояния показывают, что выполнено два теста. Один из них завершился с ошибкой, другой — успешно. У непройденного теста есть примечание: Toy Website. Не обслуживает страницы по HTTP.

    Снимок экрана: интерфейс GitHub, отображающий результаты теста выполнения рабочего процесса с выделенным неудачным тестом.

    Этот текст указывает, что веб-сайт не был правильно настроен для удовлетворения требований вашей группы безопасности.

Обновление файла Bicep

Теперь, когда вы определили, что определение Bicep не соответствует требованию вашей команды безопасности, вы можете исправить его.

  1. В Visual Studio Code откройте файл main.bicep в папке deploy.

  2. Найдите определение для приложения Службы приложений Azure и обновите его, включив свойство httpsOnly в область properties:

    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. Сохраните файл.

  4. Зафиксируйте и отправьте изменения в репозиторий Git, выполнив следующие команды в терминале Visual Studio Code:

    git add .
    git commit -m "Configure HTTPS on website"
    git push
    

Запустите рабочий процесс еще раз

  1. В браузере перейдите к рабочему процессу.

  2. Выберите последний запуск.

    Подождите, пока рабочий процесс завершит задания анализа кода, проверки и предварительного просмотра. Хотя GitHub автоматически обновляет страницу с учетом последнего состояния, рекомендуется периодически обновлять страницу.

  3. Выберите задание предварительного просмотра и снова просмотрите результаты команды "что если".

    Обратите внимание, что команда what-if обнаружила изменение значения httpsOnly свойства:

    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. Вернитесь к выполнению рабочего процесса.

  5. Нажмите кнопку "Рецензирование развертываний" , выберите среду веб-сайта , а затем выберите " Утвердить" и развернуть.

    Дождитесь завершения рабочего процесса.

  6. Обратите внимание, что весь рабочий процесс завершается успешно, включая задание тестирования состояния. Это означает, что оба теста пройдены.

    Снимок экрана: интерфейс GitHub, где показано успешное выполнение рабочего процесса.

Очистка ресурсов

После завершения упражнения вы можете удалить ресурсы, чтобы вы не выставляли счета за них.

В окне терминала Visual Studio Code выполните следующую команду:

az group delete --resource-group ToyWebsiteTest --yes --no-wait

Группа ресурсов удалится в фоновом режиме.

Remove-AzResourceGroup -Name ToyWebsiteTest -Force