了解端到端部署
管道是一种灵活的工具,可以通过许多不同的方式进行配置以满足需求。 在本单元中,你将学习如何使用管道来部署整个解决方案(包括配置 Azure 基础结构),以及如何执行其他部署操作。
需要多少管道?
在某些组织中,管理 Azure 环境的团队不同于开发在环境中运行的代码的团队。 在这些情况下,通常倾向于创建多个管道,每个管道都由负责该特定领域的团队拥有。 例如,你可以创建一个管道来部署 Bicep 代码,用于部署网站的 Azure 资源,同时再创建另一个管道,用于部署网站应用程序。
尽管这种方法可能会在管理管道方面提供一些灵活性,但可能较难保持所有内容同步。例如,假设你的网站团队需要在其 Azure 应用服务应用上进行新设置,以启用其正在生成的功能。 在基础结构部署管道成功完成之前,应用程序部署管道无法运行。 此外,在管道之间发送数据(如基础结构管道创建的 Azure 资源的名称)可能会变得复杂。
相反,最好创建一个管道来部署解决方案所需的所有内容,即使由不同的人员或不同的团队管理组件也是如此。 可以使用 Git 和 Azure DevOps 等工具来协调工作。 添加新功能后,可以使用分支对 Bicep 文件进行必要的更改。 如果更改已准备好进行集成和发布,单个管道可执行生成和部署解决方案所需的全部步骤。 单个管道可减少不同步的可能性。
提示
为解决方案生成代码时,可能需要经常对其进行部署,以测试其表现情况。 你会发现,将基础结构与应用程序代码一起部署会使管道运行缓慢并阻碍进度。
如果你处于这种情况,可以考虑禁用开发环境的基础结构部署。 可以使用路径筛选器、管道模板和条件来实现此目的。 但是对于其他环境,应保持完整部署序列不变。
控制平面和数据平面
许多 Azure 资源提供两种不同的访问平面。 控制平面用于部署和配置资源。 数据平面用于访问资源的功能。
创建和部署 Bicep 文件时,会与控制平面进行交互。 在 Azure 中,控制平面为 Azure 资源管理器。 可使用资源管理器定义每个资源的配置。
但除了与控制平面交互,你的管道通常还需要执行其他操作。 例如,可能需要执行其他任务:
- 将 Blob 上传到存储帐户。
- 修改数据库架构。
- 对第三方服务进行 API 调用。
- 触发机器学习模型的更新。
- 将网站部署到 Azure 应用服务应用。
- 将软件部署到虚拟机。
- 向第三方提供程序注册域名服务器 (DNS) 条目。
考虑使用端到端管道时,通常需要部署 Azure 资源,然后针对这些资源的数据平面执行一系列操作。 有时,这些操作被称为部署的“最后一英里”,因为你是通过使用控制平面来执行大部分的部署,并且仅剩下少量的配置。
注意
某些资源在控制平面和数据平面之间没有明确的划分。 其中包括 Azure 数据工厂和 Azure API 管理。 这两种服务都支持使用 Bicep 进行完全自动化部署,但需要特别注意。 在模块结尾的“总结”页面上,可以找到用于提供更多信息的链接。
如何执行数据平面操作
创建与资源的数据平面交互的部署管道时,可以使用以下三种常见方法中的任意一种:
- 资源管理器部署脚本。
- 管道脚本。
- 管道任务。
资源管理器部署脚本在 Bicep 文件中进行定义。 它们运行 Bash 或 PowerShell 脚本,并且可以与 Azure CLI 或 Azure PowerShell cmdlet 进行交互。 创建托管标识以便部署脚本可以对 Azure 进行身份验证,Azure 会自动预配和管理运行部署脚本所需的其他资源。
需要在部署过程中运行基本脚本时,部署脚本是不错的选择。 但是,它们不会让你轻松访问管道中的其他元素。
还可以从部署管道中运行自己的逻辑。 Azure Pipelines 为需要执行的工作提供丰富的任务生态系统。 如果找不到满足需求的任务,可以使用脚本运行自己的 Bash 或 PowerShell 代码。 管道任务和脚本从管道的代理运行。 通常,你需要向正在使用的服务的数据平面验证任务或脚本,而执行此验证的方式取决于服务。
管道任务和脚本提供了灵活性和控制力。 你还可通过它们访问管道工件(将在后续部分介绍)。 本模块重点介绍管道脚本和任务。 在模块结尾的“总结”页面上,我们提供了有关资源管理器部署脚本更多信息的链接。
输出
管道通常通过部署 Bicep 文件来创建和配置 Azure 资源。 然后,管道的后续部分与这些资源的数据平面进行交互。 为了能够与资源进行交互,管道任务和步骤需要有关已创建的 Azure 资源的信息。
例如,假设你有一个部署存储帐户的 Bicep 文件。 你希望管道部署存储帐户,然后将一些 Blob 上传到存储帐户中的 Blob 容器。 上传 Blob 的管道任务需要知道要连接到的存储帐户的名称以及要将文件上传到的 Blob 容器的名称。
最佳做法是让 Bicep 文件决定 Azure 资源的名称。 它可能会使用参数、变量或表达式来创建存储帐户和 Blob 容器的名称。 然后,Bicep 文件可以公开提供每个资源名称的输出。 管道中的稍后步骤可以读取输出的值。 这样,管道定义就不需要对可能在环境之间有所变化的名称或其他信息进行硬编码。 此外,该定义不需要基于 Bicep 文件中定义的规则。
使用 Azure Pipelines,可以使用管道变量传播输出的值。 可以在管道脚本中设置管道变量的值。 使用 Azure Pipelines 知道如何解释的特殊格式的日志输出,如下所示:
stages:
- stage: Stage1
jobs:
- job: Job1
steps:
# Set the variable's value.
- script: |
echo "##vso[task.setvariable variable=myVariableName;isOutput=true]VariableValue"
name: Step1
# Read the variable's value.
- script:
echo $(myVariableName)
当在一个作业中创建某个变量,但希望在同一阶段的另一个作业中访问该变量时,需要对其进行映射。
stages:
- stage: Stage2
jobs:
- job: Job2
steps:
# Set the variable's value.
- script: |
echo "##vso[task.setvariable variable=myVariableName;isOutput=true]VariableValue"
name: Step1
- job: Job3
dependsOn: Job2
variables: # Map the variable to this job.
myVariableName: $[ dependencies.Job2.outputs['Step1.myVariableName'] ]
steps:
# Read the variable's value.
- script: |
echo $(myVariableName)
若要跨管道阶段访问变量,也需要对变量进行映射,但会使用不同的语法:
stages:
- stage: Stage2
jobs:
- job: Job2
steps:
# Set the variable's value.
- script: |
echo "##vso[task.setvariable variable=myVariableName;isOutput=true]VariableValue"
name: Step1
- job: Job3
dependsOn: Job2
variables: # Map the variable to this job.
myVariableName: $[ dependencies.Job2.outputs['Step1.myVariableName'] ]
steps:
# Read the variable's value.
- script: |
echo $(myVariableName)
- stage: Stage3
dependsOn: Stage2
jobs:
- job: Job4
variables: # Map the variable to this stage.
myVariableName: $[ stageDependencies.Stage2.Job2.outputs['Step1.myVariableName'] ]
steps:
# Read the variable's value.
- script: |
echo $(myVariableName)
通过使用 Bicep 输出和管道变量,可以创建一个多阶段管道来部署 Bicep 代码,然后在部署过程中对资源执行各种操作。