Как определить, существует ли ресурс Azure или нет в шаблонах ARM по типу и идентификатору ресурса


Resource Manager предоставляет следующие функции для получения значений ресурсов: Функции ресурсов для шаблонов Azure Resource Manager
Вы можете обернуть свой шаблон частью powershell\whatever, которая определит, существует ли ресурс, и передаст значение параметра в зависимости от этого, и используйте условный оператор в шаблоне, который решит, что делать на основе ввода (но ввод должен поступать откуда-то еще)
нет возможности сделать это в шаблоне руки. вы можете использовать какой-либо внешний источник (например, powershell), чтобы определить это, и передать параметр с соответствующим значением, в качестве альтернативы вы можете использовать теги, чтобы понять это (иметь тег, который представляет наличие\отсутствие ресурса).
Недавно мне понадобилось решение для этого, чтобы в основном выполнить добавочное обновление SQL-сервера. Поскольку вы не можете этого сделать; шаблон завершится ошибкой NameAlreadyExists. Поэтому мне нужно было проверить, что ресурс не существует, и создать его только в том случае, если он не существует.
Добавьте проверку «условия» существования идентификатора ресурса Azure; не создавайте, если это так.
{
...
"condition": "[empty(resourceId('[resourceGroup().id]', 'Microsoft.SQL/servers', parameters('serverName')))]",
...
}
Вы можете сделать это для любого типа ресурсов.
Это не работает, потому что функция resourceId на самом деле не проверяет, существует ли ресурс, она просто возвращает идентификатор, который будет для данной группы ресурсов, типа и имени. Дополнительные сведения см. в документации – docs.microsoft.com/en-us/azure/azure-resource-manager/…
этот ответ прямо неверен. кто голосует за это?
Следует отметить, что причина, по которой этот подход неверен, заключается в том, что когда идентификатор ресурса не может быть найден, это приводит к ошибке, а не к пустой строке. Если бы была возвращена пустая строка, то, похоже, это сработало бы.
На самом деле это возможно. Вы можете использовать теги группы ресурсов, чтобы пометить текущую развернутую версию и пропустить развертывание, если тег установлен. Все это может быть достигнуто с помощью связанного шаблона.
Обратите внимание, что мы не проверяем существование ресурса как такового, но мы по-прежнему разрешаем писать шаблон ARM, который может содержать одноразовые шаблоны инициализации. Последний восстановит ресурс, если группа ресурсов была удалена и ресурсы были утеряны (при условии, что вы снова создали группу ресурсов). Вы можете расширить это, чтобы поддерживать теги для каждого ресурса, которые в некоторых случаях будут более полезными.
Шаблон, запускающий развертывание, может выглядеть следующим образом:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"DeploymentTemplateLink": {
"type": "string"
},
"DeploymentVersion": {
"defaultValue": 1,
"type": "int"
}
},
"variables": {
"rgWithDefaultVersion": {
"tags": {
"Version": "0"
}
}
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "DeploymentTemplate",
"condition": "[less(int(union(variables('rgWithDefaultVersion'), resourceGroup()).tags['Version']), parameters('DeploymentVersion'))]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[parameters('DeploymentTemplateLink')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"DeploymentVersion": {
"value": "[parameters('DeploymentVersion')]"
}
}
}
}
]
}
Условие связанного шаблона просматривает теги и возвращает true только в том случае, если текущая версия (сохраненная в теге) меньше запрошенной. На самом деле вам не нужно поддерживать управление версиями: просто не устанавливайте параметр Версия Развертывания, и он будет развернут только в первый раз. Если вы все равно решите выполнить повторное развертывание, у вас всегда есть возможность увеличить версию, что приведет к развертыванию связанного шаблона (так называемого «основного развертывания»).
Основной шаблон развертывания находится у вас, но он должен содержать ресурс теги для поддержания логики.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"DeploymentVersion": {
"defaultValue": 1,
"type": "int"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Resources/tags",
"name": "default",
"apiVersion": "2019-10-01",
"dependsOn": [],
"properties": {
"tags": {
"Version": "[string(parameters('DeploymentVersion'))]"
}
}
}
]
}
Примечание для тех, кто не понял, что такое союз () и ргвисдефаултверсион. Развертывание шаблона ARM завершится ошибкой, если указанный объект не содержит свойства. В нашем случае таких свойств два: теги и 'Версия'. «Теги» будет существовать только в том случае, если у конкретной группы ресурсов есть или когда-либо были теги. 'Версия' будет существовать только после того, как мы уже написали его один раз (в основном развертывании). Поэтому, прежде чем мы получим к ним доступ, мы выполняем операцию союз () над возвращаемым объектом с правильным значением по умолчанию, гарантируя, что мы можем безопасно получить доступ к упомянутым свойствам.
Очень мило, и как раз то, что мне было нужно сегодня... и я даже не был тем, кто задавал вопрос. Спасибо!
Это отличный обходной путь, спасибо! Трюк с union изумительный
Хороший ответ Бенни! есть ли способ PATCH теги? (т. е. merge вместо replace). Когда несколько ресурсов, на которые влияет состояние, хранятся в виде тегов RG, становится проблемой сохранить теги без потери некоторых из-за некоторых условий гонки при параллельном выполнении шагов шаблона ARM вместо последовательности.
Приятель, ты осознал, как ты это сделал, бесполезную сложность? Собираетесь ли вы применять условия к каждому ресурсу в шаблонах ARM? Во-вторых, если реальный ресурс имеет дрейф конфигурации, он никогда не будет откатываться, если на этом ресурсе не изменен тег версии.
я имею в виду, что это в значительной степени то, что я упомянул в своем ответе, но (аналогично @BMW) я не одобряю такой подход. шаблоны предназначены для того, чтобы на самом деле не заботиться о состоянии, которое присутствует сейчас. они должны просто «сделать это так». у вас есть git для отслеживания предыдущих состояний.
Вы можете найти https://docs.microsoft.com/en-us/azure/developer/terraform/overview это полезным для решения вашего дела.
Hashicorp Terraform — это инструмент с открытым исходным кодом для предоставления и управления облачной инфраструктурой. Он кодирует инфраструктуру в файлах конфигурации, описывающих топологию облачных ресурсов. Эти ресурсы включают виртуальные машины, учетные записи хранения и сетевые интерфейсы. Terraform CLI предоставляет простой механизм для развертывания и версии файлов конфигурации в Azure.
Но это потребует от вас отказа от шаблона ARM.
Шаблоны ARM носят декларативный характер (так что теоретически это не нужно) - каков ваш сценарий, может быть другой способ сделать то, что вы думаете...