ARM 是否需要在父资源内和父资源外配置资源?

Does ARM require provisioning a resource both within the parent resource as well as outside a parent resource?

vnet 资源中的子网声明就是一个很好的例子。我可以通过这个 ARM 语法将子网添加到 vnet

//vnet declaration with subnet declaration in subnets arrary
{
  "type": "Microsoft.Network/virtualNetworks",
    "apiVersion": "2020-11-01",
    "name": "vnetName",
    ...
    "properties": {
      "subnets": [
         "name": "subnetName",
         "properties": {
           ...
         }
      ],
    }            
}

我也可以像这样在 vnet 声明之外添加它:

//vnet declaration w/out subnet
{
  "type": "Microsoft.Network/virtualNetworks",
    "apiVersion": "2020-11-01",
    "name": "vnetName",
    ...
    "properties": {
      ...
    }            
}


//separate subnet declaration as specific type outside of vnet declaration, but dependsOn vnet
{
  "type": "Microsoft.Network/virtualNetworks/subnets",
  "apiVersion": "2020-11-01",
  "name": "subnetName",
    "dependsOn": [
      "[resourceId('Microsoft.Network/virtualNetworks', 'vnetName')]"
    ],
    "properties": {
      ...
    }
}

快速 google 使我进入了这个 Microsoft documentation 页面,该页面向您展示了如何通过在父资源中嵌套资源数组而不是使用子网数组来做到这一点。

我想知道需要什么 b/c 如果同一个子网需要在 vnet 声明中以及在 vnet 声明之外声明为它自己的类型,这会增加很多冗长ARM 模板。

谢谢!

TL;DR 两者都不是必需的,外部声明有助于避免 circular dependencies 并控制部署顺序。

在您的示例中,在 VNet 声明中添加子网定义总是可以的,因为您不会创建 circular dependency

但是,假设我们有一个 Key Vault 和一个引用该保管库中的机密的 Web 应用程序。

首先,我们使用所需的机密创建 Key Vault。但是,我们还需要设置访问策略以允许应用服务引用机密。 如果我们尝试在内部执行此操作,那么它将尝试引用不存在的应用程序服务。

为解决此问题,我们对依赖于 Key Vault 和 App 服务的访问策略使用外部声明。这允许创建两者,然后授予访问权限;当所有的 ID 都生成后。

This Microsoft 的文章更详细地解释了所有这些。

@blockingHD 是正确的 - 还有更多细微差别。

在 vnet 的情况下 - 子网 属性 始终被“评估”,如果您不提供它,它将被视为您提供了一个空数组。如果它们存在,这会删除您的子网。当不为空时,它们将替换为 属性.

的内容

对于 KeyVault,accessPolicies 属性 是必需的,您不能从模板中省略它。如果您提供它(无论是否为空),它都会替换保险库上的 accessPolicies——在两种情况下都相同,因为模板是声明性的。

这一切意味着您需要了解带外更改,例如为托管身份添加访问策略,以及您的 [初始] 声明是否会在再次部署时覆盖它们。

对于子网和 accessPolicies,子资源适用于“附加”场景,但您需要注意何时部署父资源(保险库或 vnet)而不添加这些内容,就好像它们不包括在内一样,将迷路了。

有帮助吗?