练习 - 在多个环境中使用 Bicep 参数
管道部署到这两个环境后,即可与用于产品评论的第三方 API 集成。
网站团队已提供了网站应用于访问服务的 API 密钥和 URL。 测试和生产环境可以使用不同的值。 在本单元中,你将更新管道,以使用产品评论 API 的正确设置配置每个环境。
在此过程中,你将:
- 为每个环境创建变量组。
- 更新管道,使其为每个环境选择正确的变量组,而不是使用模板参数。
- 更新 Bicep 文件以传播产品评论 API 所需的设置。
- 更新变量组和管道,以设置产品评论 API 设置的值。
- 查看管道结果和对 Azure 环境的更改。
添加变量组
由于要添加更多参数,这些参数因环境而异,因此你决定不再直接将管道参数添加到管道 YAML 文件中。 相反,你将使用变量组将每个环境的值保存在一起。
在浏览器中,转到“管道”>“库”。
选择“+ 变量组”按钮。
输入 ToyWebsiteTest 作为变量组名称。
选择“+ 添加”按钮以向变量组添加变量。 使用以下设置创建两个变量:
名称 值 EnvironmentType 测试 ResourceGroupName ToyWebsiteTest 请注意,你不能在变量组中定义服务连接名称。 服务连接名称有关于如何指定它们的特殊规则。 在本模块中,你将使用管道模板参数。
选择“保存”。
在浏览器中选择“后退”按钮以返回到变量组列表。
添加另一个名为 ToyWebsiteProduction 的变量组。 使用以下设置创建两个变量:
名称 值 EnvironmentType 生产 ResourceGroupName ToyWebsiteProduction 请注意,两种环境的变量名称相同,但值不同。
保存生产变量组。
更新部署管道模板以使用变量组
在 Visual Studio Code 中,打开 deploy.yml 文件。
在文件顶部,删除
resourceGroupName
和serviceConnectionName
参数。 不要删除environmentType
或deploymentDefaultLocation
参数。parameters: - name: environmentType type: string - name: deploymentDefaultLocation type: string default: westus3
更新
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:
更新
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)
更新
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)
对
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)
对
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
验证 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'
保存对该文件所做的更改。
更新管道定义以简化参数列表
打开“azure pipelines.yml”文件。
更新使用模板的阶段以删除
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
保存对该文件所做的更改。
使用以下命令将更改提交到 Git 存储库而不推送它们:
git add . git commit -m "Use variable groups"
更新 Bicep 文件
打开 main.bicep 文件。
在文件中已有的参数下方,为新的评论 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
更新
appServiceApp
资源定义以向应用程序提供评论 API URL 和密钥,以便网站代码可以使用它们: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 } ] } } }
保存对该文件所做的更改。
更新变量组
在浏览器中,转到“管道”>“库”,然后打开 ToyWebsiteTest 变量组。
添加以下变量:
名称 值 ReviewApiKey sandboxsecretkey ReviewApiUrl https://sandbox.contoso.com/reviews
选择 ReviewApiKey 变量旁边的挂锁图标。 此步骤指示 Azure Pipelines 安全地处理变量的值。
保存变量组。
更新 ToyWebsiteProduction 变量组以添加一组类似的变量:
名称 值 ReviewApiKey productionsecretkey ReviewApiUrl https://api.contoso.com/reviews
请记住选择 ReviewApiKey 变量旁边的挂锁图标。
保存变量组。
将评论 API 变量添加到变量组
在 Visual Studio Code 中,打开 deploy.yml 文件。
在
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)
对
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 命令中还有其他行。对
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
验证 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'
使用以下命令提交更改并将其推送到 Git 存储库:
git add . git commit -m "Add new review API settings to Bicep file and pipeline" git push
查看部署结果
在浏览器中,转到“管道”。
选择管道的最新运行。
在部署(生产环境)阶段之前等待管道暂停。 管道可能需要几分钟时间才能达到这一点。
如果要求授予访问资源的权限,请选择“查看”,然后选择“允许”。
通过选择“审核”>“批准”,批准部署到生产环境。
等待管道完成运行。
选择“管道”>“环境”。
选择生产环境。
请注意,现在可以在环境历史记录中看到多个部署。
在浏览器中转到 Azure 门户。
请转到 ToyWebsiteProduction 资源组。
在资源列表中,打开 Azure 应用服务应用。
选择“配置”。
选择“显示值”。
请注意,生产站点的 ReviewApiKey 和 ReviewApiUrl 设置值设置为你在生产变量组中配置的值。
将当前值与 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