【问题标题】:Does ARM require provisioning a resource both within the parent resource as well as outside a parent resource?ARM 是否需要在父资源内部和父资源外部配置资源?
【发布时间】:2021-05-21 00:26:24
【问题描述】:

一个很好的例子是 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 页面,该页面向您展示了如何通过在父资源中嵌套资源数组而不使用子网数组来做到这一点。

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

谢谢!

【问题讨论】:

    标签: azure azure-resource-manager arm-template


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 感谢您的回复!在您的第一句话中,您说“TL;DR 两者都不是必需的,这有助于避免循环依赖并控制部署顺序。”,但我认为您在“the”和“is there”之间留下了一个词...“那里有什么”?谢谢!
    • @MichaelMcCarthy 我已经修好了。很明显要在深夜写答案
    【解决方案2】:

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

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

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

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

    对于子网和 accessPolicies,子资源适用于“附加”方案,但您需要注意何时部署父资源(保险库或 vnet)而不添加这些附加资源,就好像它们不包括在内一样,将会丢失.

    有帮助吗?

    【讨论】:

    • "如果您的子网存在,它会删除它们。"哎呀。我不知道这个。非常感谢您提供的信息。是否以相同的方式评估父资源的所有子数组,或者这是特定于 vnet 和 vault 等资源的东西?
    • 一般来说,指定一个空数组将声明一个空数组——无论是否有子资源。所以你可以在其他情况下看到它......但是当属性被建模为属性和子属性时,你最常遇到的问题发生。 (保险库和 vnet)
    猜你喜欢
    • 1970-01-01
    • 2023-01-08
    • 2018-10-24
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多