通过指定依赖关系来控制部署顺序

已完成

假设你想要将一组资源部署到 Azure,但前提是已部署另一个资源。 此时,你需要在一个资源依赖于另一个资源的模板中进行通信。

需要考虑以下几个方面:

  • 需要存在一些资源才能部署其他资源。

    例如,假设需要 Azure Key Vault 中的密钥保管库,才能获取需要在虚拟机 (VM) 中加载的机密。 部署密钥保管库时,可以同时在同一个模板中部署其机密。 但是,需要先部署密钥保管库,然后才能部署其机密。 因此,机密依赖于密钥保管库而存在。 由于这种依赖关系,会从密钥保管库开始,按顺序逐个部署密钥保管库和机密。

  • 我是否可以依赖于 Azure 资源管理器的工作原理?

    检查其他资源是否存在时,首先想到的可能是使用 Azure PowerShell 或 Azure CLI 检查某资源是否存在。 更自动化的解决方案使用资源管理器的内置幂等性。 如果资源管理器发现某模板中定义的资源已存在于云中,则不会对其进行重新部署。 为了使其成为一种有效的方法,你需要了解资源管理器如何执行检查。

    注意

    当现有资源标识与模板中定义的内容相匹配时,Azure 资源管理器会对属性进行比较。 如果属性完全匹配,则资源保持不变。 如果不匹配,则引擎将进行更改,可能会重新部署资源。

  • 可以将资源嵌套在其他资源中。

    在 Azure 资源管理器模板中,可以将资源嵌套在其他资源中。 通过嵌套资源,可以定义嵌套资源和父资源之间的关系。

如何定义 Azure 资源之间的依赖关系?

假设你想要确保某个资源(例如存储帐户)在其他资源需要它之前已部署。 如何检查依赖存储帐户是否存在?

可以先通过运行 Azure PowerShell 或 Azure CLI 命令来检查部署的当前状态,从而检查存储帐户是否存在。 还可以检查是否存在允许你执行相同检查的资源管理器构造。

资源管理器模板中就有一个这样的构造,称为 dependsOn。 使用此构造可以使资源等待,直到指出的资源已完成部署。

什么是 dependsOn 构造?

它是一个键值对,可用于定义资源之间的部署顺序。 有时,你需要确保资源的先后顺序。 例如,你可能需要先部署数据库再部署应用,或者需要先部署机密资源再部署密钥保管库。

在依赖于先部署的其他资源的资源上放置 dependsOn 构造。 资源可以依赖于多个资源,这就是构造需要将从属资源列表作为其值的原因。

以下示例演示如何在 ARM 模板中采用 JSON 格式表示此类依赖关系:

"resources": [
  {
    "name": "<name of resource that needs to exist first>"
  },
  {
    "name": "someResource",
    "dependsOn": [
      "<name of resource that needs to exist first>"
    ]
  }
]

在此示例中,你将使用资源的名称来指定所依赖的资源。 但是,许多资源可能具有相同的名称。 若要确保此比较满足你的需求,可以改为使用 resourceId() 构造来获取唯一资源标识符:

"dependsOn": [
  "resourceId('Microsoft.Network/loadBalancers', variables('nameOfLoadBalancer')))"
]

上述 JSON 代码通过组合命名空间、类型和变量名称来构造唯一 ID。 通过这种方式,可以确保指定了正确的依赖资源。

什么是子资源?

子资源是仅存在于另一个资源的上下文中的资源。 虚拟机扩展就是这种情况的示例,该扩展的存在必须依赖于虚拟机。

模板中的父子关系的典型代码如下所示:

"resources": [
  {
    "name": "parent-resource",
    "resources": [{
      "name": "child-resource"
    }]
  }
]

此父子依赖关系不会自动创建这样一种依赖关系,即父资源的部署先于其子资源部署。 你需要明确依赖关系。

因此,当你表示此类关系时,请确保添加 dependsOn 构造,如下所示:

"resources": [
  {
    "name": "parent-resource",
    "resources": [{
      "dependsOn": ["parent-resource"],
      "name": "child resource"
    }]
  }
]