将 ARM 模板与 Azure Pipelines 集成

可以将 Azure 资源管理器模板(ARM 模板)与 Azure Pipelines 集成,以便持续集成和持续部署(CI/CD)。 本文介绍使用 Azure Pipelines 部署模板的两种更高级方法。

选择你的选项

在继续本文之前,让我们考虑从管道部署 ARM 模板的不同选项。

  • 使用 ARM 模板部署任务。 此选项是最简单的选项。 如果想要直接从存储库部署模板,则此方法有效。 本文未介绍此选项,但本教程介绍了 ARM 模板与 Azure Pipelines 的持续集成。 它演示如何使用 ARM 模板部署任务 从 GitHub 存储库部署模板。

  • 添加运行 Azure PowerShell 脚本的任务。 此选项的优点是在整个开发生命周期内提供一致性,因为可以使用运行本地测试时使用的相同脚本。 脚本部署模板,但也可执行其他作,例如获取用作参数的值。 本文中显示了此选项。 请参阅 Azure PowerShell 任务

    Visual Studio 提供包含 PowerShell 脚本的 Azure 资源组项目 。 该脚本会将项目中的生成工件暂存到资源管理器可以访问的存储帐户。 项目中的工件是指链接的模板、脚本以及应用程序的二进制文件等项目项。 若要继续使用项目中的脚本,请使用本文中所示的 PowerShell 脚本任务。

  • 添加任务以复制和部署任务。 此选项提供了项目脚本的便捷替代方法。 在管道中配置两个任务。 一个任务将生成工件暂存到可访问的位置。 另一个任务从该位置部署模板。 本文中显示了此选项。 请参阅 复制和部署任务

准备项目

本文假设 ARM 模板和 Azure DevOps 组织已准备好创建管道。 以下步骤演示如何确保已准备就绪:

  • 你已有一个 Azure DevOps 组织。 如果你没有,请创建一个。 如果你的团队已创建了一个 Azure DevOps 组织,请确保你是要使用的 Azure DevOps 项目的管理员。

  • 您已为 Azure 订阅配置了 服务连接。 管道中的任务将以服务主体的身份执行。 有关创建连接的步骤,请参阅创建 DevOps 项目

  • 你有一个 ARM 模板 ,用于定义项目的基础结构。

创建管道

  1. 如果之前尚未添加管道,则需要创建新的管道。 在 Azure DevOps 组织中,选择 “管道 ”和“ 新建管道”。

    “添加新管道”按钮的屏幕截图

  2. 指定代码的存储位置。 在下图中,选择的是“Azure Repos Git”。

    在 Azure DevOps 中选择代码源代码的屏幕截图

  3. 从该源中,选择具有项目代码的存储库。

    在 Azure DevOps 中选择项目的存储库的屏幕截图

  4. 选择要创建的管道类型。 可以选择“初学者管道”。

    选择要在 Azure DevOps 中创建的管道类型的屏幕截图

现已准备好添加 Azure PowerShell 任务,或者复制文件并部署任务。

Azure PowerShell 任务

本部分介绍如何使用在项目中运行 PowerShell 脚本的单个任务配置持续部署。 如果需要部署模板的 PowerShell 脚本,请参阅 Deploy-AzTemplate.ps1Deploy-AzureResourceGroup.ps1

以下 YAML 文件创建 Azure PowerShell 任务

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: AzurePowerShell@5
  inputs:
    azureSubscription: 'script-connection'
    ScriptType: 'FilePath'
    ScriptPath: './Deploy-AzTemplate.ps1'
    ScriptArguments: -Location 'chinaeast' -ResourceGroupName 'demogroup' -TemplateFile templates\mainTemplate.json
    azurePowerShellVersion: 'LatestVersion'

将任务设置为AzurePowerShell@5时,管道将使用Az 模块。 如果在脚本中使用 AzureRM 模块,请将任务设置为 AzurePowerShell@3

steps:
- task: AzurePowerShell@3

对于 azureSubscription,请提供所创建的服务连接的名称。

inputs:
    azureSubscription: '<your-connection-name>'

对于 scriptPath,请提供从管道文件到脚本的相对路径。 可以在存储库中查看路径。

ScriptPath: '<your-relative-path>/<script-file-name>.ps1'

ScriptArguments中,提供脚本所需的任何参数。 以下示例显示了脚本的一些参数,但需要自定义脚本的参数。

ScriptArguments: -Location 'chinaeast' -ResourceGroupName 'demogroup' -TemplateFile templates\mainTemplate.json

选择“ 保存”时,将自动运行生成管道。 返回生成管道的摘要并观察状态。

Azure DevOps 中管道结果视图的屏幕截图

可以选择当前正在运行的管道以查看有关任务的详细信息。 完成后,会看到每个步骤的结果。

复制并部署任务

本部分介绍如何使用两个任务配置持续部署。 第一个任务将项目暂存到存储帐户,第二个任务部署模板。

若要将文件复制到存储帐户,必须为服务连接的服务主体分配存储 Blob 数据参与者或存储 Blob 数据所有者角色。 有关详细信息,请参阅 AzCopy 入门

以下 YAML 显示了 Azure 文件复制任务

trigger:
- master

pool:
  vmImage: 'windows-latest'

steps:
- task: AzureFileCopy@4
  inputs:
    SourcePath: 'templates'
    azureSubscription: 'copy-connection'
    Destination: 'AzureBlob'
    storage: 'demostorage'
    ContainerName: 'projecttemplates'
  name: AzureFileCopy

此任务有几个部分需要根据你的环境进行修改。 SourcePath 表示工件在管道文件中的位置。

SourcePath: '<path-to-artifacts>'

对于 azureSubscription,请提供所创建的服务连接的名称。

azureSubscription: '<your-connection-name>'

对于存储和容器名称,请指定您用于存储物品的存储帐户和容器的名称。 存储帐户必须存在。

storage: '<your-storage-account-name>'
ContainerName: '<container-name>'

创建复制文件任务后,即可添加任务以部署暂存模板。

以下 YAML 显示了 Azure 资源管理器模板部署任务

- task: AzureResourceManagerTemplateDeployment@3
  inputs:
    deploymentScope: 'Resource Group'
    azureResourceManagerConnection: 'copy-connection'
    subscriptionId: 'aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e'
    action: 'Create Or Update Resource Group'
    resourceGroupName: 'demogroup'
    location: 'China North'
    templateLocation: 'URL of the file'
    csmFileLink: '$(AzureFileCopy.StorageContainerUri)templates/mainTemplate.json$(AzureFileCopy.StorageContainerSasToken)'
    csmParametersFileLink: '$(AzureFileCopy.StorageContainerUri)templates/mainTemplate.parameters.json$(AzureFileCopy.StorageContainerSasToken)'
    deploymentMode: 'Incremental'
    deploymentName: 'deploy1'

此任务的几个部分需要进行更详细的审查。

  • deploymentScope:从选项中选择部署范围: Management GroupSubscriptionResource Group。 若要了解有关范围的详细信息,请参阅 部署范围

  • azureResourceManagerConnection:提供所创建的服务连接的名称。

  • subscriptionId:提供目标订阅 ID。 此属性仅适用于资源组部署范围和订阅部署范围。

  • resourceGroupNamelocation:提供要部署到的资源组的名称和位置。 如果资源组不存在,该任务将创建该资源组。

    resourceGroupName: '<resource-group-name>'
    location: '<location>'
    
  • csmFileLink:提供暂存模板的链接。 设置值时,请使用从文件复制任务返回的变量。 以下示例链接到名为 mainTemplate.json的模板。 包含名为 模板 的文件夹,是因为文件复制任务将文件复制到了该文件夹。 在管道中,提供模板的路径和模板的名称。

    csmFileLink: '$(AzureFileCopy.StorageContainerUri)templates/mainTemplate.json$(AzureFileCopy.StorageContainerSasToken)'
    

管道如下所示:

trigger:
- master

pool:
  vmImage: 'windows-latest'

steps:
- task: AzureFileCopy@4
  inputs:
    SourcePath: 'templates'
    azureSubscription: 'copy-connection'
    Destination: 'AzureBlob'
    storage: 'demostorage'
    ContainerName: 'projecttemplates'
  name: AzureFileCopy
- task: AzureResourceManagerTemplateDeployment@3
  inputs:
    deploymentScope: 'Resource Group'
    azureResourceManagerConnection: 'copy-connection'
    subscriptionId: 'aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e'
    action: 'Create Or Update Resource Group'
    resourceGroupName: 'demogroup'
    location: 'China North'
    templateLocation: 'URL of the file'
    csmFileLink: '$(AzureFileCopy.StorageContainerUri)templates/mainTemplate.json$(AzureFileCopy.StorageContainerSasToken)'
    csmParametersFileLink: '$(AzureFileCopy.StorageContainerUri)templates/mainTemplate.parameters.json$(AzureFileCopy.StorageContainerSasToken)'
    deploymentMode: 'Incremental'
    deploymentName: 'deploy1'

选择“ 保存”时,将自动运行生成管道。 在 “作业 ”框架下,选择 “作业 ”以查看作业状态。

后续步骤