Упражнение. Использование параметров Bicep в нескольких средах

Завершено

Теперь, когда конвейер настроен для развертывания в обеих средах, можно приступать к интеграции со сторонним интерфейсом API отзывов о товарах.

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

В процессе вы:

  • Создадите группы переменных для каждой среды.
  • Измените конвейер таким образом, чтобы он выбирал соответствующую группу переменных для каждой среды вместо использования параметров шаблона.
  • Измените файл Bicep для распространения параметров, необходимых для интерфейса API отзывов о товарах.
  • Измените группу переменных и конвейер, задав значения для параметров интерфейса API отзывов о товарах.
  • Проверите результаты работы конвейера и изменения в среде Azure.

Добавление групп переменных

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

  1. В браузере перейдите на страницу Pipelines>Библиотека.

    Снимок экрана Azure DevOps: пункт меню

  2. Нажмите кнопку + Группа переменных.

    Снимок экрана: страница библиотеки Azure DevOps с кнопкой для добавления группы переменных.

  3. В качестве имени группы переменных введите ToyWebsiteTest.

  4. Нажмите кнопку + Добавить, чтобы добавить переменные в группу переменных. Создайте две переменные:

    Имя. Значение
    EnvironmentType Тест
    ResourceGroupName ToyWebsiteTest

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

    Снимок экрана: тестовая группа переменных и переменные.

  5. Выберите Сохранить.

  6. Нажмите в браузере кнопку Назад, чтобы вернуться к списку групп переменных.

  7. Добавьте еще одну группу переменных с именем ToyWebsiteProduction. Создайте две переменные:

    Имя. Значение
    EnvironmentType Производственный экземпляр
    ResourceGroupName ToyWebsiteProduction

    Снимок экрана: рабочая группа переменных и переменные.

    Обратите внимание, что имена переменных одинаковы для обеих сред, но значения различны.

  8. Сохраните рабочую группу переменных.

Изменение шаблона конвейера развертывания для использования группы переменных

  1. В Visual Studio Code откройте файл deploy.yml.

  2. В начале файла удалите параметры resourceGroupName и serviceConnectionName. Не удаляйте параметры environmentType и deploymentDefaultLocation.

    parameters:
    - name: environmentType
      type: string
    - name: deploymentDefaultLocation
      type: string
      default: westus3
    
  3. Измените задание ValidateBicepCode, чтобы импортировать группу переменных:

    - ${{ if ne(parameters.environmentType, 'Production') }}:
      - stage: Validate_${{parameters.environmentType}}
        displayName: Validate (${{parameters.environmentType}} Environment)
        jobs:
        - job: ValidateBicepCode
          displayName: Validate Bicep code
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
    
  4. Измените задание ValidateBicepCode, чтобы имя подключения к службе определялось автоматически на основе значения параметра environmentType:

    - ${{ if ne(parameters.environmentType, 'Production') }}:
      - stage: Validate_${{parameters.environmentType}}
        displayName: Validate (${{parameters.environmentType}} Environment)
        jobs:
        - job: ValidateBicepCode
          displayName: Validate Bicep code
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
            - task: AzureResourceManagerTemplateDeployment@3
              name: RunPreflightValidation
              displayName: Run preflight validation
              inputs:
                connectedServiceName: ToyWebsite${{parameters.environmentType}}
                location: ${{parameters.deploymentDefaultLocation}}
                deploymentMode: Validation
                resourceGroupName: $(ResourceGroupName)
                csmFile: deploy/main.bicep
                overrideParameters: >
                  -environmentType $(EnvironmentType)
    
  5. Измените задание ValidateBicepCode так, чтобы использовать импортированную группу переменных для настройки имени группы ресурсов и аргументов типа среды для задачи развертывания:

    - ${{ if ne(parameters.environmentType, 'Production') }}:
      - stage: Validate_${{parameters.environmentType}}
        displayName: Validate (${{parameters.environmentType}} Environment)
        jobs:
        - job: ValidateBicepCode
          displayName: Validate Bicep code
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
            - task: AzureResourceManagerTemplateDeployment@3
              name: RunPreflightValidation
              displayName: Run preflight validation
              inputs:
                connectedServiceName: ToyWebsite${{parameters.environmentType}}
                location: ${{parameters.deploymentDefaultLocation}}
                deploymentMode: Validation
                resourceGroupName: $(ResourceGroupName)
                csmFile: deploy/main.bicep
                overrideParameters: >
                  -environmentType $(EnvironmentType)
    
  6. Внесите изменения в задание PreviewAzureChanges:

    - ${{ if eq(parameters.environmentType, 'Production') }}:
      - stage: Preview_${{parameters.environmentType}}
        displayName: Preview (${{parameters.environmentType}} Environment)
        jobs:
        - job: PreviewAzureChanges
          displayName: Preview Azure changes
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
            - task: AzureCLI@2
              name: RunWhatIf
              displayName: Run what-if
              inputs:
                azureSubscription: ToyWebsite${{parameters.environmentType}}
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  az deployment group what-if \
                    --resource-group $(ResourceGroupName) \
                    --template-file deploy/main.bicep \
                    --parameters environmentType=$(EnvironmentType)
    
  7. Внесите те же изменения в задание развертывания Deploy:

    - stage: Deploy_${{parameters.environmentType}}
      displayName: Deploy (${{parameters.environmentType}} Environment)
      jobs:
      - deployment: DeployWebsite
        displayName: Deploy website
        variables:
        - group: ToyWebsite${{parameters.environmentType}}
        environment: ${{parameters.environmentType}}
        strategy:
          runOnce:
            deploy:
              steps:
                - checkout: self
    
                - task: AzureResourceManagerTemplateDeployment@3
                  name: DeployBicepFile
                  displayName: Deploy Bicep file
                  inputs:
                    connectedServiceName: ToyWebsite${{parameters.environmentType}}
                    deploymentName: $(Build.BuildNumber)
                    location: ${{parameters.deploymentDefaultLocation}}
                    resourceGroupName: $(ResourceGroupName)
                    csmFile: deploy/main.bicep
                    overrideParameters: >
                      -environmentType $(EnvironmentType)
                    deploymentOutputs: deploymentOutputs
    
  8. Убедитесь в том, что файл deploy.yml теперь выглядит следующим образом:

    parameters:
    - name: environmentType
      type: string
    - name: deploymentDefaultLocation
      type: string
      default: westus3
    
    stages:
    
    - ${{ if ne(parameters.environmentType, 'Production') }}:
      - stage: Validate_${{parameters.environmentType}}
        displayName: Validate (${{parameters.environmentType}} Environment)
        jobs:
        - job: ValidateBicepCode
          displayName: Validate Bicep code
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
            - task: AzureResourceManagerTemplateDeployment@3
              name: RunPreflightValidation
              displayName: Run preflight validation
              inputs:
                connectedServiceName: ToyWebsite${{parameters.environmentType}}
                location: ${{parameters.deploymentDefaultLocation}}
                deploymentMode: Validation
                resourceGroupName: $(ResourceGroupName)
                csmFile: deploy/main.bicep
                overrideParameters: >
                  -environmentType $(EnvironmentType)
    
    - ${{ if eq(parameters.environmentType, 'Production') }}:
      - stage: Preview_${{parameters.environmentType}}
        displayName: Preview (${{parameters.environmentType}} Environment)
        jobs:
        - job: PreviewAzureChanges
          displayName: Preview Azure changes
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
            - task: AzureCLI@2
              name: RunWhatIf
              displayName: Run what-if
              inputs:
                azureSubscription: ToyWebsite${{parameters.environmentType}}
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  az deployment group what-if \
                    --resource-group $(ResourceGroupName) \
                    --template-file deploy/main.bicep \
                    --parameters environmentType=$(EnvironmentType)
    
    - stage: Deploy_${{parameters.environmentType}}
      displayName: Deploy (${{parameters.environmentType}} Environment)
      jobs:
      - deployment: DeployWebsite
        displayName: Deploy website
        variables:
        - group: ToyWebsite${{parameters.environmentType}}
        environment: ${{parameters.environmentType}}
        strategy:
          runOnce:
            deploy:
              steps:
                - checkout: self
    
                - task: AzureResourceManagerTemplateDeployment@3
                  name: DeployBicepFile
                  displayName: Deploy Bicep file
                  inputs:
                    connectedServiceName: ToyWebsite${{parameters.environmentType}}
                    deploymentName: $(Build.BuildNumber)
                    location: ${{parameters.deploymentDefaultLocation}}
                    resourceGroupName: $(ResourceGroupName)
                    csmFile: deploy/main.bicep
                    overrideParameters: >
                      -environmentType $(EnvironmentType)
                    deploymentOutputs: deploymentOutputs
    
                - bash: |
                    echo "##vso[task.setvariable variable=appServiceAppHostName;isOutput=true]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppHostName.value')"
                  name: SaveDeploymentOutputs
                  displayName: Save deployment outputs into variables
                  env:
                    DEPLOYMENT_OUTPUTS: $(deploymentOutputs)
    
    - stage: SmokeTest_${{parameters.environmentType}}
      displayName: Smoke Test (${{parameters.environmentType}} Environment)
      jobs:
      - job: SmokeTest
        displayName: Smoke test
        variables:
          appServiceAppHostName: $[ stageDependencies.Deploy_${{parameters.environmentType}}.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ]
        steps:
          - task: PowerShell@2
            name: RunSmokeTests
            displayName: Run smoke tests
            inputs:
              targetType: inline
              script: |
                $container = New-PesterContainer `
                  -Path 'deploy/Website.Tests.ps1' `
                  -Data @{ HostName = '$(appServiceAppHostName)' }
                Invoke-Pester `
                  -Container $container `
                  -CI
    
          - task: PublishTestResults@2
            name: PublishTestResults
            displayName: Publish test results
            condition: always()
            inputs:
              testResultsFormat: NUnit
              testResultsFiles: 'testResults.xml'
    
  9. Сохраните внесенные в файл изменения.

Изменение определения конвейера для упрощения списка параметров

  1. Откройте файл azure-pipelines.yml.

  2. Измените этапы, для которых используются шаблоны, удалив параметры resourceGroupName и serviceConnectionName. Оставьте только параметр environmentType.

    trigger:
      batch: true
      branches:
        include:
        - main
    
    pool:
      vmImage: ubuntu-latest
    
    stages:
    
    # Lint the Bicep file.
    - stage: Lint
      jobs: 
      - template: pipeline-templates/lint.yml
    
    # Deploy to the test environment.
    - template: pipeline-templates/deploy.yml
      parameters:
        environmentType: Test
    
    # Deploy to the production environment.
    - template: pipeline-templates/deploy.yml
      parameters:
        environmentType: Production
    
  3. Сохраните внесенные в файл изменения.

  4. Зафиксируйте изменения в репозитории GIT, не отправляя их, с помощью следующих команд:

    git add .
    git commit -m "Use variable groups"
    

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

  1. Откройте файл main.bicep.

  2. Под уже имеющимися в файле параметрами добавьте следующие параметры для нового интерфейса API отзывов:

    @description('The URL to the product review API.')
    param reviewApiUrl string
    
    @secure()
    @description('The API key to use when accessing the product review API.')
    param reviewApiKey string
    
  3. Измените определение ресурса appServiceApp для предоставления приложению URL-адреса и ключа интерфейса API отзывов, чтобы код веб-сайта мог использовать их:

    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
            }
            {
              name: 'ReviewApiUrl'
              value: reviewApiUrl
            }
            {
              name: 'ReviewApiKey'
              value: reviewApiKey
            }
          ]
        }
      }
    }
    
  4. Сохраните внесенные в файл изменения.

Изменение групп переменных

  1. В браузере перейдите на страницу Pipelines>Библиотека и откройте группы переменных ToyWebsiteTest.

  2. Добавьте следующие переменные:

    Имя. Значение
    ReviewApiKey sandboxsecretkey
    ReviewApiUrl https://sandbox.contoso.com/reviews
  3. Щелкните значок замка рядом с переменной ReviewApiKey. Таким образом вы сообщаете Azure Pipelines, что значение переменной должно быть защищено.

    Снимок экрана: группа переменных для тестовой среды и кнопка секретной переменной.

  4. Сохраните группу переменных.

    Снимок экрана: группа переменных для тестовой среды с обновленными переменными.

  5. Измените группу переменных ToyWebsiteProduction, добавив аналогичный набор переменных:

    Имя. Значение
    ReviewApiKey productionsecretkey
    ReviewApiUrl https://api.contoso.com/reviews

    Не забудьте щелкнуть значок замка рядом с переменной ReviewApiKey.

    Снимок экрана: группа переменных для рабочей среды с обновленными переменными.

  6. Сохраните группу переменных.

Добавление переменных для интерфейса API отзывов в группы переменных

  1. В Visual Studio Code откройте файл deploy.yml.

  2. В задании ValidateBicepCode добавьте значения параметров для интерфейса API отзывов в задачу развертывания:

    - ${{ if ne(parameters.environmentType, 'Production') }}:
      - stage: Validate_${{parameters.environmentType}}
        displayName: Validate (${{parameters.environmentType}} Environment)
        jobs:
        - job: ValidateBicepCode
          displayName: Validate Bicep code
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
            - task: AzureResourceManagerTemplateDeployment@3
              name: RunPreflightValidation
              displayName: Run preflight validation
              inputs:
                connectedServiceName: ToyWebsite${{parameters.environmentType}}
                location: ${{parameters.deploymentDefaultLocation}}
                deploymentMode: Validation
                resourceGroupName: $(ResourceGroupName)
                csmFile: deploy/main.bicep
                overrideParameters: >
                  -environmentType $(EnvironmentType)
                  -reviewApiUrl $(ReviewApiUrl)
                  -reviewApiKey $(ReviewApiKey)
    
  3. Внесите то же изменение в задание PreviewAzureChanges:

    - ${{ if eq(parameters.environmentType, 'Production') }}:
      - stage: Preview_${{parameters.environmentType}}
        displayName: Preview (${{parameters.environmentType}} Environment)
        jobs:
        - job: PreviewAzureChanges
          displayName: Preview Azure changes
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
            - task: AzureCLI@2
              name: RunWhatIf
              displayName: Run what-if
              inputs:
                azureSubscription: ToyWebsite${{parameters.environmentType}}
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  az deployment group what-if \
                    --resource-group $(ResourceGroupName) \
                    --template-file deploy/main.bicep \
                    --parameters environmentType=$(EnvironmentType) \
                                 reviewApiUrl=$(ReviewApiUrl) \
                                 reviewApiKey=$(ReviewApiKey)
    

    Внимание

    Не забудьте поставить обратную косую черту (\) в конце строки, в которой задается значение параметра environmentType, и в следующей строке. Символ \ указывает, что последующие строки являются частью той же команды Azure CLI.

  4. Внесите то же изменение в задание Deploy:

    - stage: Deploy_${{parameters.environmentType}}
      displayName: Deploy (${{parameters.environmentType}} Environment)
      jobs:
      - deployment: DeployWebsite
        displayName: Deploy website
        variables:
        - group: ToyWebsite${{parameters.environmentType}}
        environment: ${{parameters.environmentType}}
        strategy:
          runOnce:
            deploy:
              steps:
                - checkout: self
    
                - task: AzureResourceManagerTemplateDeployment@3
                  name: DeployBicepFile
                  displayName: Deploy Bicep file
                  inputs:
                    connectedServiceName: ToyWebsite${{parameters.environmentType}}
                    deploymentName: $(Build.BuildNumber)
                    location: ${{parameters.deploymentDefaultLocation}}
                    resourceGroupName: $(ResourceGroupName)
                    csmFile: deploy/main.bicep
                    overrideParameters: >
                      -environmentType $(EnvironmentType)
                      -reviewApiUrl $(ReviewApiUrl)
                      -reviewApiKey $(ReviewApiKey)
                    deploymentOutputs: deploymentOutputs
    
  5. Убедитесь в том, что файл deploy.yml теперь выглядит следующим образом:

    parameters:
    - name: environmentType
      type: string
    - name: deploymentDefaultLocation
      type: string
      default: westus3
    
    stages:
    
    - ${{ if ne(parameters.environmentType, 'Production') }}:
      - stage: Validate_${{parameters.environmentType}}
        displayName: Validate (${{parameters.environmentType}} Environment)
        jobs:
        - job: ValidateBicepCode
          displayName: Validate Bicep code
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
            - task: AzureResourceManagerTemplateDeployment@3
              name: RunPreflightValidation
              displayName: Run preflight validation
              inputs:
                connectedServiceName: ToyWebsite${{parameters.environmentType}}
                location: ${{parameters.deploymentDefaultLocation}}
                deploymentMode: Validation
                resourceGroupName: $(ResourceGroupName)
                csmFile: deploy/main.bicep
                overrideParameters: >
                  -environmentType $(EnvironmentType)
                  -reviewApiUrl $(ReviewApiUrl)
                  -reviewApiKey $(ReviewApiKey)
    
    - ${{ if eq(parameters.environmentType, 'Production') }}:
      - stage: Preview_${{parameters.environmentType}}
        displayName: Preview (${{parameters.environmentType}} Environment)
        jobs:
        - job: PreviewAzureChanges
          displayName: Preview Azure changes
          variables:
          - group: ToyWebsite${{parameters.environmentType}}
          steps:
            - task: AzureCLI@2
              name: RunWhatIf
              displayName: Run what-if
              inputs:
                azureSubscription: ToyWebsite${{parameters.environmentType}}
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: |
                  az deployment group what-if \
                    --resource-group $(ResourceGroupName) \
                    --template-file deploy/main.bicep \
                    --parameters environmentType=$(EnvironmentType) \
                                 reviewApiUrl=$(ReviewApiUrl) \
                                 reviewApiKey=$(ReviewApiKey)
    
    - stage: Deploy_${{parameters.environmentType}}
      displayName: Deploy (${{parameters.environmentType}} Environment)
      jobs:
      - deployment: DeployWebsite
        displayName: Deploy website
        variables:
        - group: ToyWebsite${{parameters.environmentType}}
        environment: ${{parameters.environmentType}}
        strategy:
          runOnce:
            deploy:
              steps:
                - checkout: self
    
                - task: AzureResourceManagerTemplateDeployment@3
                  name: DeployBicepFile
                  displayName: Deploy Bicep file
                  inputs:
                    connectedServiceName: ToyWebsite${{parameters.environmentType}}
                    deploymentName: $(Build.BuildNumber)
                    location: ${{parameters.deploymentDefaultLocation}}
                    resourceGroupName: $(ResourceGroupName)
                    csmFile: deploy/main.bicep
                    overrideParameters: >
                      -environmentType $(EnvironmentType)
                      -reviewApiUrl $(ReviewApiUrl)
                      -reviewApiKey $(ReviewApiKey)
                    deploymentOutputs: deploymentOutputs
    
                - bash: |
                    echo "##vso[task.setvariable variable=appServiceAppHostName;isOutput=true]$(echo $DEPLOYMENT_OUTPUTS | jq -r '.appServiceAppHostName.value')"
                  name: SaveDeploymentOutputs
                  displayName: Save deployment outputs into variables
                  env:
                    DEPLOYMENT_OUTPUTS: $(deploymentOutputs)
    
    - stage: SmokeTest_${{parameters.environmentType}}
      displayName: Smoke Test (${{parameters.environmentType}} Environment)
      jobs:
      - job: SmokeTest
        displayName: Smoke test
        variables:
          appServiceAppHostName: $[ stageDependencies.Deploy_${{parameters.environmentType}}.DeployWebsite.outputs['DeployWebsite.SaveDeploymentOutputs.appServiceAppHostName'] ]
        steps:
          - task: PowerShell@2
            name: RunSmokeTests
            displayName: Run smoke tests
            inputs:
              targetType: inline
              script: |
                $container = New-PesterContainer `
                  -Path 'deploy/Website.Tests.ps1' `
                  -Data @{ HostName = '$(appServiceAppHostName)' }
                Invoke-Pester `
                  -Container $container `
                  -CI
    
          - task: PublishTestResults@2
            name: PublishTestResults
            displayName: Publish test results
            condition: always()
            inputs:
              testResultsFormat: NUnit
              testResultsFiles: 'testResults.xml'
    
  6. Зафиксируйте и отправьте изменения в репозиторий GIT с помощью следующих команд:

    git add .
    git commit -m "Add new review API settings to Bicep file and pipeline"
    git push
    

Проверка результатов развертывания

  1. В браузере перейдите на страницу Pipelines.

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

    Дождитесь приостановки конвейера перед этапом Развертывание (рабочая среда). Для достижения этого момента может потребоваться несколько минут.

  3. Если вам будет предложено предоставить разрешение на доступ к ресурсу, выберите Просмотр и щелкните Разрешить.

  4. Утвердите развертывание в рабочей среде, нажав кнопку Проверка>Утвердить.

    Подождите, пока конвейер завершит работу.

  5. Выберите Pipelines>Среды.

  6. Выберите среду Рабочая.

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

  7. В браузере перейдите на портал Azure.

  8. Перейдите к группе ресурсов ToyWebsiteProduction.

  9. В списке ресурсов откройте приложение Службы приложений Azure.

    Выберите Конфигурация.

    Снимок экрана портала Azure: приложение Службы приложений и пункт меню

  10. Выберите Показать значения.

    Снимок экрана портала Azure: параметры приложения Службы приложений и кнопка для отображения значений.

  11. Обратите внимание, что для параметров ReviewApiKey и ReviewApiUrl рабочего сайта заданы значения, настроенные в группе переменных для рабочей среды.

    Снимок экрана портала Azure: параметры приложения Службы приложений и параметры конфигурации.

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

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

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

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

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

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

Remove-AzResourceGroup -Name ToyWebsiteTest -Force
Remove-AzResourceGroup -Name ToyWebsiteProduction -Force