練習 - 將多個環境新增至您的管線
現在您已準備好更新管線,以同時部署至測試環境和生產環境。 在本單元中,您會更新管線以使用範本,以便在不同環境間重複使用階段。
在此過程中,您將會:
- 為 lint 階段新增管線範本。
- 新增管線範本,以定義要部署至任何環境所需要的階段。
- 更新管線以使用範本。
- 執行管線並檢視結果。
為 lint 階段新增管線範本
不論管線部署到多少環境,系統都只會在管線執行期間執行一次 lint 階段。 因此,您不必真的使用 lint 階段的範本。 但為了讓主要管線的定義檔保持簡單且容易閱讀的狀態,您決定在範本中定義 lint 階段。
在 Visual Studio Code中,於 deploy 資料夾內建立名為 pipeline-templates 的新資料夾。
在名為 lint.yml 的 pipeline-templates 資料夾中建立新檔案。
將下列管線範本定義貼到該檔案中:
jobs: - job: LintCode displayName: Lint code steps: - script: | az bicep build --file deploy/main.bicep name: LintBicepCode displayName: Run Bicep linter
此 lint 階段與管線中既存的 lint 階段相同,但現在位於不同的管線範本檔案中。
儲存變更並關閉該檔案。
新增用於部署的管線範本
建立管線範本,以定義要部署每個環境所需的所有階段。 您使用範本參數來指定在不同環境之間可能不同的設定。
在名為 deploy.yml 的 pipeline-templates 資料夾中建立新檔案。
此檔案會呈現針對您每個環境執行的所有部署活動。
將下列管線範本參數貼到該檔案中:
parameters: - name: environmentType type: string - name: resourceGroupName type: string - name: serviceConnectionName type: string - name: deploymentDefaultLocation type: string default: westus3
注意
當您開始在 Visual Studio Code 中使用 YAML 檔案時,您可能會看到一些紅色波浪線來指出有問題存在。 這是因為 YAML 檔案的 Visual Studio Code 延伸模組有時會猜錯檔案的結構描述。
您可以忽略延伸模組所報告的問題。 或者,如果您想要的話,也可以在檔案頂端新增下列程式碼,以隱藏擴充功能的猜測:
# yaml-language-server: $schema=./deploy.yml
在參數下方,貼上驗證階段的定義:
stages: - ${{ if ne(parameters.environmentType, 'Production') }}: - stage: Validate_${{parameters.environmentType}} displayName: Validate (${{parameters.environmentType}} Environment) jobs: - job: ValidateBicepCode displayName: Validate Bicep code steps: - task: AzureResourceManagerTemplateDeployment@3 name: RunPreflightValidation displayName: Run preflight validation inputs: connectedServiceName: ${{parameters.serviceConnectionName}} location: ${{parameters.deploymentDefaultLocation}} deploymentMode: Validation resourceGroupName: ${{parameters.resourceGroupName}} csmFile: deploy/main.bicep overrideParameters: > -environmentType ${{parameters.environmentType}}
請注意,這個階段有適用的條件。 其只會針對非生產環境來執行。
另請注意,階段識別碼包含
environmentType
參數的值。 此參數可確保管線中的每個階段都有唯一識別碼。 此階段也有displayName
屬性,可建立易讀格式的名稱。在驗證階段下方,貼上預覽階段的定義:
- ${{ if eq(parameters.environmentType, 'Production') }}: - stage: Preview_${{parameters.environmentType}} displayName: Preview (${{parameters.environmentType}} Environment) jobs: - job: PreviewAzureChanges displayName: Preview Azure changes steps: - task: AzureCLI@2 name: RunWhatIf displayName: Run what-if inputs: azureSubscription: ${{parameters.serviceConnectionName}} scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: | az deployment group what-if \ --resource-group ${{parameters.resourceGroupName}} \ --template-file deploy/main.bicep \ --parameters environmentType=${{parameters.environmentType}}
請注意,此階段也有適用的條件,但與驗證階段的條件相反。 預覽階段只會針對生產環境來執行。
在預覽階段下方,貼上部署階段的定義:
- stage: Deploy_${{parameters.environmentType}} displayName: Deploy (${{parameters.environmentType}} Environment) jobs: - deployment: DeployWebsite displayName: Deploy website environment: ${{parameters.environmentType}} strategy: runOnce: deploy: steps: - checkout: self - task: AzureResourceManagerTemplateDeployment@3 name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: ${{parameters.serviceConnectionName}} deploymentName: $(Build.BuildNumber) location: ${{parameters.deploymentDefaultLocation}} resourceGroupName: ${{parameters.resourceGroupName}} csmFile: deploy/main.bicep overrideParameters: > -environmentType ${{parameters.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'
請注意,當
appServiceAppHostName
變數定義所指的是發佈了主機名稱的階段時,其中便會納入environmentType
參數。 此參數可確保每個煙霧測試階段都會針對正確的環境來執行。確認 deploy.yml 檔案現在看起來像下列範例:
parameters: - name: environmentType type: string - name: resourceGroupName type: string - name: serviceConnectionName 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 steps: - task: AzureResourceManagerTemplateDeployment@3 name: RunPreflightValidation displayName: Run preflight validation inputs: connectedServiceName: ${{parameters.serviceConnectionName}} location: ${{parameters.deploymentDefaultLocation}} deploymentMode: Validation resourceGroupName: ${{parameters.resourceGroupName}} csmFile: deploy/main.bicep overrideParameters: > -environmentType ${{parameters.environmentType}} - ${{ if eq(parameters.environmentType, 'Production') }}: - stage: Preview_${{parameters.environmentType}} displayName: Preview (${{parameters.environmentType}} Environment) jobs: - job: PreviewAzureChanges displayName: Preview Azure changes steps: - task: AzureCLI@2 name: RunWhatIf displayName: Run what-if inputs: azureSubscription: ${{parameters.serviceConnectionName}} scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: | az deployment group what-if \ --resource-group ${{parameters.resourceGroupName}} \ --template-file deploy/main.bicep \ --parameters environmentType=${{parameters.environmentType}} - stage: Deploy_${{parameters.environmentType}} displayName: Deploy (${{parameters.environmentType}} Environment) jobs: - deployment: DeployWebsite displayName: Deploy website environment: ${{parameters.environmentType}} strategy: runOnce: deploy: steps: - checkout: self - task: AzureResourceManagerTemplateDeployment@3 name: DeployBicepFile displayName: Deploy Bicep file inputs: connectedServiceName: ${{parameters.serviceConnectionName}} deploymentName: $(Build.BuildNumber) location: ${{parameters.deploymentDefaultLocation}} resourceGroupName: ${{parameters.resourceGroupName}} csmFile: deploy/main.bicep overrideParameters: > -environmentType ${{parameters.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'
儲存對檔案所做的變更。
更新管線定義以使用範本
開啟 azure-pipelines.yml 檔案。
將檔案的內容取代為下列程式碼,以更新檔案來使用新的範本:
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 resourceGroupName: ToyWebsiteTest serviceConnectionName: ToyWebsiteTest # Deploy to the production environment. - template: pipeline-templates/deploy.yml parameters: environmentType: Production resourceGroupName: ToyWebsiteProduction serviceConnectionName: ToyWebsiteProduction
此管線會執行 lint 階段一次。 然後,會使用 deploy.yml 範本檔案兩次:每個環境使用一次。 這可讓管線定義變得清楚且容易理解。 此外,註解會有助於說明發生了什麼情況。
儲存您的變更。
在 Visual Studio Code 終端機中執行下列命令,以認可所做的變更,並將其推送至您的 Git 存放庫:
git add . git commit -m "Add pipeline templates" git push
檢視管線執行
在您的瀏覽器中,移至 [管線]。
選取管線的最近一次執行。
請注意,管線執行現在會顯示您在 YAML 檔案中定義的所有階段。 您可能需要水平捲動才能看到完整內容。
等候管線在部署 (實際執行環境) 階段之前暫停。 管線可能需要幾分鐘的時間才會進行到這邊。
選取 [檢閱] 按鈕,以核准部署至生產環境。
選取 [核准] 按鈕。
等候管線執行完成。
選取 [測試] 索引標籤,以顯示此管線執行的測試結果。
請注意,現在有四個測試結果。 測試環境和生產環境都會執行煙霧測試,因此您會看到這兩組測試的結果。
選取 [管線]>[環境]。
選取 [生產] 環境。
請注意,在 [環境詳細資料] 畫面上,您會看到生產環境的部署歷程記錄概觀。
選取部署,然後選取 [變更] 索引標籤。
請注意,[變更] 索引標籤會顯示部署中包含的認可清單。 此資訊可協助您確切地了解環境在各個時間的變化。
在瀏覽器中,移至 Azure 入口網站。
移至 [ToyWebsiteProduction] 資源群組。
在資源清單中,開啟 Azure App Service 應用程式。
請注意,App Service 方案的類型為 S1。
移至 [ToyWebsiteTest] 資源群組中的 App Service 應用程式。
請注意,App Service 方案的類型為 [F1]。 這兩個環境會使用不同的設定 (如 Bicep 檔案中的定義)。