演習 - Bicep パラメーターを複数の環境で使用する

完了

パイプラインが両方の環境にデプロイされるようになったので、製品レビューのためのサードパーティ API と統合することができます。

Web サイト チームから、サービスにアクセスするために Web サイトが使用する API キーと URL が渡されました。 テスト環境と運用環境で使用する値は異なります。 このユニットでは、パイプラインを更新して、製品レビュー API の正しい設定を使用して各環境を構成します。

このプロセスでは、次のことを行います。

  • 各環境に対して、変数グループを作成します。
  • パイプラインを更新して、テンプレート パラメーターを使用せずに、各環境に対して正しい変数グループを選択できるようにします。
  • Bicep ファイルを更新して、製品レビュー API で必要な設定を反映します。
  • 変数グループとパイプラインを更新して、製品レビュー API の設定に対して値を設定します。
  • パイプラインの結果と、Azure 環境への変更をレビューします。

変数グループを追加する

環境ごとに異なるパラメーターをさらに追加する必要があるので、パイプライン パラメーターをパイプライン YAML ファイルに直接追加する方法は取らないことにします。 代わりに、変数グループを使用して各環境の値をまとめて保持します。

  1. ブラウザーで、[Pipelines]>[ライブラリ] に移動します。

    [Pipelines] カテゴリの [ライブラリ] メニュー項目を示す Azure DevOps のスクリーンショット。

  2. [+ Variable group](変数グループの追加) ボタンを選択します。

    Azure DevOps の ライブラリ ページと、変数グループを追加するボタンのスクリーンショット。

  3. 変数グループ名として、「ToyWebsiteTest」を入力します。

  4. [+ Add](+ 追加) ボタンを選択して、変数を変数グループに追加します。 次の設定で 2 つの変数を作成します。

    Name
    EnvironmentType テスト
    ResourceGroupName ToyWebsiteTest

    サービス接続名は、変数グループでは定義しません。 サービス接続名には、指定方法に関して特別なルールがあります。 このモジュールでは、パイプライン テンプレート パラメーターを使います。

    テスト環境の変数グループと変数のスクリーンショット。

  5. [保存] を選択します。

  6. ブラウザーの [戻る] ボタンを選択して、変数グループの一覧に戻ります。

  7. ToyWebsiteProduction という名前の、別の変数グループを追加します。 次の設定で 2 つの変数を作成します。

    Name
    EnvironmentType Production
    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. environmentType パラメーター値に基づいてサービス接続名を自動的に推測するように、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)
    
  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 リソース定義を更新してレビュー API URL とキーをアプリケーションに対して指定し、Web サイトのコードで使用できるようします。

    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. 次の変数を追加します。

    Name
    ReviewApiKey sandboxsecretkey
    ReviewApiUrl https://sandbox.contoso.com/reviews
  3. ReviewApiKey 変数の隣にある padlock アイコンを選択します。 このステップは、Azure Pipelines に変数の値を安全に処理するように指示します。

    テスト環境の変数グループとシークレット変数ボタンのスクリーンショット。

  4. 変数グループを保存します。

    テスト環境の変数グループのスクリーンショット。変数が更新されています。

  5. ToyWebsiteProduction 変数グループを更新して、同様の変数のセットを追加します。

    Name
    ReviewApiKey productionsecretkey
    ReviewApiUrl https://api.contoso.com/reviews

    ReviewApiKey 変数の隣の padlock アイコンを忘れずに選択してください。

    運用環境の変数グループのスクリーンショット。変数が更新されています。

  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 portal に移動します。

  8. ToyWebsiteProduction リソース グループに移動します。

  9. リソースの一覧で、Azure App Service アプリを開きます。

    [構成] を選択します。

    App Service アプリと [構成] メニュー項目を示す Azure portal のスクリーンショット。

  10. [Show values](値の表示) を選択します。

    App Service アプリの設定と値を表示するためのボタンを示す Azure portal のスクリーンショット。

  11. ReviewApiKeyReviewApiUrl の設定に対する運用環境サイトの値が、運用環境の変数グループで構成した値に設定されています。

    App Service アプリの設定と構成設定を示す Azure portal のスクリーンショット。

  12. 現在の値を、ToyWebsiteTest リソース グループの App Service アプリの構成設定と比較します。 値が異なっていることに注目してください。

リソースのクリーンアップ

これで演習が完了したので、課金されないようにリソースを削除しましょう。

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