Azure资源管理器模板:条件部署

Azure资源管理器模板:条件部署,azure,azure-resource-manager,Azure,Azure Resource Manager,我正在处理ARM模板,需要执行条件部署。例如,我在变量“subnets”中定义了两个网络安全组 "variables": { "subnets": [ { "subnetname": "AzureBastionSubnet", "nsgname": "nsg_bastion1" }, { "subnetname": "client-subnet",

我正在处理ARM模板,需要执行条件部署。例如,我在变量“subnets”中定义了两个网络安全组

"variables": {
    "subnets": [
        {
            "subnetname": "AzureBastionSubnet",
            "nsgname": "nsg_bastion1"
        },
        {
            "subnetname": "client-subnet",
            "nsgname": "nsg_client1"
        }
    ]
}
网络安全组“nsg_bastion1”需要使用预定义规则进行特殊处理,因为它是Azure Bastion子网的网络安全组。 “nsg_client1”将分配一些自定义规则,这在此时并不重要

为了区分非堡垒和堡垒网络安全组,我创建了两个条件资源块:

"resources": [
// NSG (non-Bastion)
{
    "condition": "[not(equals(variables('subnets')[copyIndex()].name, 'AzureBastionSubnet'))]",
    "name": "[variables('subnets')[copyIndex()].nsg]",
    "type": "Microsoft.Network/networkSecurityGroups",
    "apiVersion": "2019-11-01",
    "location": "[parameters('location')]",
    "properties": {},
    "copy": {
        "name": "nsg-c",
        "count": "[length(variables('subnets'))]"
    }
},
// NSG (Bastion)
{
    "condition": "[equals(variables('subnets')[copyIndex()].name, 'AzureBastionSubnet')]",
    "name": "[variables('subnets')[copyIndex()].nsg]",
    "type": "Microsoft.Network/networkSecurityGroups",
    "apiVersion": "2019-11-01",
    "location": "[parameters('location')]",
    "properties": {},
    "resources": [
        // Bastion Security Rules .....
    ],
    "copy": {
        "name": "nsg-bastion-c",
        "count": "[length(variables('subnets'))]"
    }
},]
condition属性检查子网是否称为“AzureBastionSubnet”。我已经验证了这两个资源块都可以单独使用,但是当它们都包含在代码中时就不行了。它总是抛出以下错误消息:

    Code=InvalidTemplate; Message=Deployment template validation failed:
'The resource 'Microsoft.Network/networkSecurityGroups/AzureBastionSubnet' at line '' and column '' is defined multiple times in a template.

我将感谢任何帮助,提前谢谢

好的,我以为我们已经解决了这个问题,但还没有

即使您的条件是互斥的,也不能在同一模板中有两个资源具有相同的resourceId

我猜两者的区别在于安全规则?如果是这样,最简单的选择可能是定义两个单独的变量,然后根据您的条件使用If()语句在它们之间进行交换


如果失败,如果你想在模板上展开,可以看看是否有更好的选项…

好的,我想我们已经解决了这个问题,但还没有

即使您的条件是互斥的,也不能在同一模板中有两个资源具有相同的resourceId

我猜两者的区别在于安全规则?如果是这样,最简单的选择可能是定义两个单独的变量,然后根据您的条件使用If()语句在它们之间进行交换


如果您不想扩展模板,可以查看是否有更好的选项…

我建议将AzureBastion NSG设置为不同的参数,而不是将其包含在普通NSG的相同数组中。我想知道copyIndex()在条件中是如何工作的。您是如何部署模板的?更具体地说,您知道部署中的apiVersion是什么吗?(这是固定的)nm-见下面的答案…我建议将AzureBastion NSG设置为不同的参数,而不是将其包含在正常NSG的同一数组中。我想知道copyIndex()在条件中是如何工作的。您是如何部署模板的?更具体地说,您知道部署中的apiVersion是什么吗?(这意味着是固定的)nm-请参阅下面的答案…如果我们根据条件使用或不使用资源中的属性,该怎么办。例如:
hostnameConfigurations
是一个数组,它不是必需的。我想根据参数列表中的bool条件来提供这一点。在这种情况下我能做什么?如果我的案例为false,我不能只定义一个变量并使其内容为空。这将提供空值或null值,对吗?听起来像这样的场景:-你可以说:if(not(empty(hosthames)),hostnames,json('null')-你说的空是对的,在ARM中有特定的含义(即空数组),但是json('null')将从声明中删除属性,就好像你从未提供过它一样。是的,绝对是我需要的。谢谢@bmoore-msft。如果我们根据条件使用或不使用资源中的属性,该怎么办。例如:
hostnameConfigurations
是一个数组,它不是必需的。我想根据参数列表中的bool条件来提供这一点。在这种情况下我能做什么?如果我的案例为false,我不能只定义一个变量并使其内容为空。这将提供空值或null值,对吗?听起来像这样的场景:-你可以说:if(not(empty(hosthames)),hostnames,json('null')-你说的空是对的,在ARM中有特定的含义(即空数组),但是json('null')将从声明中删除属性,就好像你从未提供过它一样。是的,绝对是我需要的。谢谢@bmoore msft。