Могу ли я перебрать свойства в шаблонах ARM?

У меня есть шаблон ARM, в котором я настроил балансировщик нагрузки, и я хочу добавить несколько открытий портов, добавив правила и зонды в LB.

Это шаблон, который у меня есть на данный момент:

    {
        "type": "Microsoft.Network/loadBalancers",
        "name": "LB-front",
        "apiVersion": "2016-03-30",
        "location": "westeurope",
        "tags": { },
        "properties": {
            "frontendIPConfigurations": [
                {
                    "name": "LoadBalancerIPConfig",
                    "properties": {
                        "privateIPAllocationMethod": "Dynamic",
                        "publicIPAddress": {
                            "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddresses_lbipdev_0_name'))]"
                        }
                    }
                }
            ],
            "backendAddressPools": [
                {
                    "name": "LoadBalancerBEAddressPool"
                }
            ],
            "loadBalancingRules": [
                {
                    "name": "AppPortLBRule1",
                    "properties": {
                        "frontendIPConfiguration": {
                            "id": "[parameters('loadBalancers_LB_dev_id_6')]"
                        },
                        "frontendPort": 80,
                        "backendPort": 80,
                        "enableFloatingIP": false,
                        "idleTimeoutInMinutes": 5,
                        "protocol": "Tcp",
                        "loadDistribution": "Default",
                        "backendAddressPool": {
                            "id": "[parameters('loadBalancers_LB_dev_id_7')]"
                        },
                        "probe": {
                            "id": "[parameters('loadBalancers_LB_dev_id_8')]"
                        }
                    }
                },
                {
                    "name": "AppPortLBRule2",
                    "properties": {
                        "frontendIPConfiguration": {
                            "id": "[parameters('loadBalancers_LB_dev_id_9')]"
                        },
                        "frontendPort": 81,
                        "backendPort": 81,
                        "enableFloatingIP": false,
                        "idleTimeoutInMinutes": 5,
                        "protocol": "Tcp",
                        "loadDistribution": "Default",
                        "backendAddressPool": {
                            "id": "[parameters('loadBalancers_LB_dev_id_10')]"
                        },
                        "probe": {
                            "id": "[parameters('loadBalancers_LB_dev_id_11')]"
                        }
                    }
                },
                {
                    "name": "AppPortLBRule3",
                    "properties": {
                        "frontendIPConfiguration": {
                            "id": "[parameters('loadBalancers_LB_dev_id_12')]"
                        },
                        "frontendPort": 82,
                        "backendPort": 82,
                        "enableFloatingIP": false,
                        "idleTimeoutInMinutes": 5,
                        "protocol": "Tcp",
                        "loadDistribution": "Default",
                        "backendAddressPool": {
                            "id": "[parameters('loadBalancers_LB_dev_id_13')]"
                        },
                        "probe": {
                            "id": "[parameters('loadBalancers_LB_dev_id_14')]"
                        }
                    }
                }
            ],
            "probes": [
                {
                    "name": "AppPortProbe1",
                    "properties": {
                        "protocol": "Tcp",
                        "port": 80,
                        "intervalInSeconds": 5,
                        "numberOfProbes": 2
                    }
                },
                {
                    "name": "AppPortProbe2",
                    "properties": {
                        "protocol": "Tcp",
                        "port": 81,
                        "intervalInSeconds": 5,
                        "numberOfProbes": 2
                    }
                },
                {
                    "name": "AppPortProbe3",
                    "properties": {
                        "protocol": "Tcp",
                        "port": 82,
                        "intervalInSeconds": 5,
                        "numberOfProbes": 2
                    }
                }
            ],
            "inboundNatRules": [],
            "outboundNatRules": [],
            "inboundNatPools": []
        },
        "resources": [],
        "dependsOn": [
            "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddresses_lbipdev_1_name'))]"
        ]
    },

(некоторые детали опущены)

Что я хотел бы сделать, так это иметь массив номеров портов, для которых я хочу создавать правила и проверки и перебирать их, вместо того, чтобы явно писать каждое правило и проверять как свойство для ресурса.

В основном я хотел бы, чтобы в моем шаблоне был такой параметр или переменная:

"ports": [ 80, 81, 82, ...]

и что я мог бы повторить это примерно так: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-multiple.


person Lee G.    schedule 26.01.2017    source источник


Ответы (4)


Вы можете применить объект-копию только к ресурсу верхнего уровня.

Его нельзя применить к свойству типа ресурса или к дочернему ресурсу.

"resources": [
  {
    "type": "{provider-namespace-and-type}",
    "name": "parentResource",
    "copy": {  
      /* yes, copy can be applied here */
    },
    "properties": {
      "exampleProperty": {
        /* no, copy cannot be applied here */
      }
    },
    "resources": [
      {
        "type": "{provider-type}",
        "name": "childResource",
        /* copy can be applied if resource is promoted to top level */ 
      }
    ]
  }
] 

Источник предложения: развертывание нескольких экземпляров ресурсов в шаблонах Azure Resource Manager

Вы можете перебирать свойства в шаблоне ARM ТОЛЬКО ЕСЛИ объект копии применяется к ресурсу верхнего уровня, которым в вашем случае является «Microsoft.Network/loadBalancers», но это также создаст множественную копию указанного ресурса.

Если это не то, чего вы хотите достичь, я бы порекомендовал вам сохранить существующий путь до тех пор, пока шаблон ARM не будет поддерживать копирование объекта в свойство для типа ресурса в будущем.

person juvchan    schedule 27.01.2017
comment
Как я могу продвинуть ресурс до верхнего уровня, если этот ресурс технически является дочерним по отношению к конкретному ресурсу? Например. Веб-сайт как верхний уровень, а веб-сайт / расширение как дочерний уровень. Могу ли я поместить ресурс расширения как объявление верхнего уровня и сделать некоторую зависимость от веб-сайта? - person Lee G.; 27.01.2017
comment
Кстати, спасибо за ответ. - person Lee G.; 27.01.2017
comment
@ lee-g да, вы можете объявить дочерние ресурсы на верхнем уровне, просто добавив тип / имя родительского ресурса к типу / имени дочернего ресурса. См. Здесь: docs .microsoft.com / en-us / azure / azure-resource-manager /. Как только вы это сделаете, вы также можете снова использовать итерацию свойств. - person Torben Knerr; 24.08.2018
comment
Больше не верный ответ - person Dmitry Gorshkov; 25.03.2020

Вы действительно можете! Копирование работает со свойствами!

Создайте такой параметр или переменную (в этом примере будет использоваться массив параметров):

"lbRules": {
  "type": "array",
  "defaultValue": [
    {
      "name": "httpPort",
      "frontendPort": "80",
      "backendPort": "80",
      "protocol": "tcp"
    },
    {
      "name": "customAppPort",
      "frontendPort": "8080",
      "backendPort": "8888",
      "protocol": "tcp"
    },
    {
      "name": "httpsPort",
      "frontendPort": "443",
      "backendPort": "443",
      "protocol": "tcp"
    }
  ]
}

Используйте этот параметр в ресурсе Loadbalancer, используя копию, как это, что создаст столько тестов и правил, которые вы определили в своем массиве параметров:

{
  "apiVersion": "[variables('lbApiVersion')]",
  "type": "Microsoft.Network/loadBalancers",
  "name": "[parameters('myLoadBalancer')]",
  "location": "[parameters('computeLocation')]",
  "dependsOn": [
    "[concat('Microsoft.Network/publicIPAddresses/',concat(parameters('lbIPName'),'-','0'))]"
  ],
  "properties": {
    "frontendIPConfigurations": [
      {
        "name": "LoadBalancerIPConfig",
        "properties": {
          "publicIPAddress": {
            "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('lbIPName'),'-','0'))]"
          }
        }
      }
    ],
    "backendAddressPools": [
      {
        "name": "LoadBalancerBEAddressPool",
        "properties": {}
      }
    ],

    "copy": [
      {
        "name": "probes",
        "count": "[length(parameters('lbRules'))]",
        "input": {
          "name": "[concat(parameters('lbRules')[copyIndex('probes')].name,'Probe')]",
          "properties": {
            "intervalInSeconds": 5,
            "numberOfProbes": 2,
            "port": "[parameters('lbRules')[copyIndex('probes')].backendPort]",
            "protocol": "[parameters('lbRules')[copyIndex('probes')].protocol]"

          }
        }
      },

      {
        "name": "loadBalancingRules",
        "count": "[length(parameters('lbRules'))]",
        "input": {
          "name": "[parameters('lbRules')[copyIndex('loadBalancingRules')].name]",
          "properties": {
            "frontendIPConfiguration": {
              "id": "[concat(resourceId('Microsoft.Network/loadBalancers', parameters('myLoadBalancer')),'/frontendIPConfigurations/LoadBalancerIPConfig')]"
            },
            "frontendport": "[parameters('lbRules')[copyIndex('loadBalancingRules')].frontendport]",
            "backendport": "[parameters('lbRules')[copyIndex('loadBalancingRules')].backendport]",
            "enableFloatingIP": false,
            "idleTimeoutInMinutes": "5",
            "protocol": "[parameters('lbRules')[copyIndex('loadBalancingRules')].protocol]",
            "backendAddressPool": {
              "id": "[concat(resourceId('Microsoft.Network/loadBalancers', parameters('myLoadBalancer')),'/backendAddressPools/LoadBalancerBEAddressPool')]"
            },
            "probe": {
              "id": "[concat(variables('lbID0'),'/probes/', parameters('lbRules')[copyIndex('loadBalancingRules')].name,'Probe')]"
            }
          }
        }
      }
    ],


    "inboundNatPools": []
  },

  }
}

Более подробную информацию можно найти здесь:

person HobPet    schedule 07.04.2018
comment
Некоторое время назад я делал это для клиента и не мог вспомнить синтаксис. Это был отличный пример, который прекрасно описывает функциональность. Спасибо, что поделился! - person Rogala; 06.09.2020
comment
Я нашел docs.microsoft.com/en- us / azure / azure-resource-manager / templates /, чтобы быть лучшим ресурсом - person Ben; 05.11.2020


То, чего вы хотите достичь, возможно с помощью функции взять. Вы сами связались с нужным сайтом документации. Перейдите по опубликованной вами ссылке и ознакомьтесь с разделом «Создание нескольких экземпляров, когда копирование не работает».

в вашем случае это будет выглядеть так:

"variables": {
    "probeArray": [                    
           {
             "name": "AppPortProbe1",
             "properties": {
                 "protocol": "Tcp",
                 "port": 80,
                 "intervalInSeconds": 5,
                 "numberOfProbes": 2
             }
           },
           {
             "name": "AppPortProbe2",
             "properties": {
                 "protocol": "Tcp",
                 "port": 81,
                 "intervalInSeconds": 5,
                 "numberOfProbes": 2
             }
           },
           {
             "name": "AppPortProbe3",
             "properties": {
                 "protocol": "Tcp",
                 "port": 82,
                 "intervalInSeconds": 5,
                 "numberOfProbes": 2
             }
           }
    ],

Затем вы создаете параметр, определяющий, сколько зондов вы хотите.

"parameters": {
...
"numProbes": {
  "type": "int",
  "maxValue": 3,
  "metadata": {
    "description": "This parameter allows you to select the number of probes you want"
  }
}

Наконец, вы используете take внутри ресурса:

"resources": [
...
{
  "type": "Microsoft.Network/loadBalancers",
  "properties": {
      ...
      "probes": "[take(variables('probeArray'),parameters('numProbes'))]"
    },
    ...
  }
  ...
}
]

Если вы продолжите изучать документацию, вы увидите, что можете стать еще более сумасшедшим и объединить копирование и получение со связанными шаблонами.

person TobiWi    schedule 29.01.2017
comment
Разве это не означает, что мне все равно придется объявить все зонды, но вместо этого они будут вставлены в переменную? Я надеялся найти способ просто объявить их в одном куске и перебрать единственное, что меняется, то есть номера портов. - person Lee G.; 01.02.2017
comment
Да вы должны определить зонды, когда вы это делаете, это было. Нет простого способа просто перебирать свойства с помощью copyIndex (). - person TobiWi; 10.02.2017