使用管道模板处理环境之间的相似性
将更改部署到多个环境时,部署到每个环境所涉及的步骤相似或完全相同。 本单元将介绍如何使用管道模板以避免重复,并允许重用管道代码。
对多个环境的部署
在与网站团队的同事交谈后,你决定为玩具公司的网站选择以下管道:
该管道运行 Bicep linter 以检查 Bicep 代码是否有效并遵循最佳做法。
对 Bicep 代码进行 Lint 分析时无需连接到 Azure,因此部署到多少环境并不重要。 它仅运行一次。
管道部署到测试环境。 此阶段需要:
- 运行 Azure 资源管理器预检验证。
- 部署 Bicep 代码。
- 针对测试环境运行一些测试。
如果管道的任何部分出现故障,则整个管道都会停止,以便你可以调查和解决问题。 但如果一切顺利,管道将继续部署到生产环境:
- 管道运行预览阶段,该阶段在生产环境中运行 What-if 操作以列出将对生产 Azure 资源进行的更改。 预览阶段还会验证部署,因此无需为生产环境运行单独的验证阶段。
- 管道将暂停以便进行手动验证。
- 如果收到审批,管道将针对生产环境运行部署和版本验收测试。
其中一些阶段在测试环境和生产环境之间重复,而有些阶段仅针对特定环境运行:
阶段 | 环境 |
---|---|
Lint | 两者都不 - Lint 分析不适用于环境 |
验证 | 仅测试 |
预览 | 仅生产 |
部署 | 两种环境 |
版本验收测试 | 两种环境 |
当需要在管道中重复步骤时,可以尝试复制并粘贴步骤定义。 但是,最好避免这种做法。 复制管道的代码时,很容易意外地犯一些细微的错误或使内容不同步。 将来,需要更改步骤时,必须记住在多个位置应用更改。
管道模板
通过管道模板,可创建管道定义的可重用部分。 模板可以定义步骤、作业甚至整个阶段。 可以使用模板在单个管道中多次重复使用管道的各个部分,甚至在多个管道中重复使用。 还可以为想要在多个管道中重复使用的一组变量创建模板。
模板只是一个包含可重用内容的 YAML 文件。 步骤定义的简单模板可能如下所示,并保存在名为 script.yml 的文件中:
steps:
- script: |
echo Hello world!
通过在通常定义单个步骤的位置使用 template
关键字,可以在管道中使用模板:
jobs:
- job: Job1
pool:
vmImage: 'windows-latest'
steps:
- template: script.yml
- job: Job2
pool:
vmImage: 'ubuntu-latest'
steps:
- template: script.yml
嵌套模板
还可以在其他模板中嵌套模板。 假设前面的文件名为 jobs.yml,并且你创建了一个名为 azure-pipelines.yml 的文件,该文件在多个管道阶段重用作业模板:
trigger:
branches:
include:
- main
pool:
vmImage: ubuntu-latest
stages:
- stage: Stage1
jobs:
- template: jobs.yml
- stage: Stage2
jobs:
- template: jobs.yml
嵌套模板或在单个管道中多次重用模板时,需要注意不要意外地将同一名称用于多个管道资源。 例如,一个阶段中的每个作业都需要自己的标识符。 因此,如果在模板中定义作业标识符,则不能在同一阶段多次重复使用它。
使用复杂的部署管道集时,为共享管道模板创建专用 Git 存储库会很有帮助。 然后,可以在多个管道中重用同一存储库,即使它们用于不同的项目。 我们在摘要中提供了指向更多详细信息的链接。
管道模板参数
管道模板参数使模板文件更易于重用,因为无论何时使用模板,都不必再为模板中的细微差异而费心。
创建管道模板时,可以在文件顶部指示其参数:
parameters:
- name: environmentType
type: string
default: 'Test'
- name: serviceConnectionName
type: string
可以根据需要定义任意数量的参数。 但就像 Bicep 参数一样,尽量不要过度使用管道模板参数。 你应该让其他人也可以轻松地重用你的模板,而不必指定过多设置。
每个管道模板参数都有三个属性:
- 参数的名称,用于引用模板文件中的参数。
- 参数的类型。 参数支持多种不同类型的数据,包括字符串、数字和布尔值。 还可以定义接受结构化对象的更复杂的模板。
- 参数的默认值,这是可选的。 如果未指定默认值,则必须在使用管道模板时提供此值。
在该示例中,管道定义了一个名为 environmentType
的字符串参数(其默认值为 Test
)以及一个名为 serviceConnectionName
的必需参数。
在管道模板中,使用特殊语法来引用参数的值。 使用 ${{parameters.YOUR_PARAMETER_NAME}}
宏,如下例所示:
steps:
- script: |
echo Hello ${{parameters.environmentType}}!
可以使用 parameters
关键字将参数的值传递给管道模板,如下例所示:
steps:
- template: script.yml
parameters:
environmentType: Test
- template: script.yml
parameters:
environmentType: Production
还可以在为管道模板中的作业和阶段分配标识符时使用参数。 当需要在管道中多次重复使用同一模板时,此方法会有所帮助,如下所示:
parameters:
- name: environmentType
type: string
default: 'Test'
jobs:
- job: Job1-${{parameters.environmentType}}
pool:
vmImage: 'windows-latest'
steps:
- template: script.yml
- job: Job2-${{parameters.environmentType}}
pool:
vmImage: 'ubuntu-latest'
steps:
- template: script.yml
条件
可以使用管道条件来指定是否应根据你指定的规则运行步骤、作业甚至阶段。 可以组合模板参数和管道条件,以针对许多不同的情况自定义部署过程。
例如,假设你定义了运行脚本步骤的管道模板。 你计划在每个环境中重用该模板。 在部署生产环境时,你希望运行一个其他步骤。 以下是使用 if
宏和 eq
(等于)运算符实现这一目标的方法:
parameters:
- name: environmentType
type: string
default: 'Test'
steps:
- script: |
echo Hello ${{parameters.environmentType}}!
- ${{ if eq(parameters.environmentType, 'Production') }}:
- script: |
echo This step only runs for production deployments.
此处的条件转换为:如果 environmentType 参数的值等于“Production”,则运行以下步骤。
提示
使用示例中的条件时,请注意 YAML 文件的缩进。 该条件适用的步骤需要缩进一个额外的级别。
还可以在阶段、作业或步骤上指定 condition
属性。 下面的示例展示了如何使用 ne
(不等于)运算符指定条件 - 如果 environmentType 参数的值不等于“Production”,则运行以下步骤:
- script: |
echo This step only runs for non-production deployments.
condition: ne('${{ parameters.environmentType }}', 'Production')
尽管条件是增加管道灵活性的一种方式,但尽量不要使用过多的条件。 条件过多会使管道变得复杂,更加难以理解其流。 如果在管道模板中有很多条件,则该模板可能并不是计划运行的工作流的最佳解决方案,你可能需要重新设计管道。
此外,请考虑使用 YAML 注释来解释你使用的条件以及管道中可能需要多加说明的其他方面。 注释有助于使管道易于理解和在将来使用。 在整个模块的练习中存在一些示例 YAML 注释。