Как проверить наличие ресурса в шаблоне руки

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

Шаблоны ARM носят декларативный характер (так что теоретически это не нужно) - каков ваш сценарий, может быть другой способ сделать то, что вы думаете...

bmoore-msft 08.07.2019 15:04
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
12
1
10 136
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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/…

David Gard 05.09.2019 12:04

этот ответ прямо неверен. кто голосует за это?

4c74356b41 16.10.2019 08:45

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

The Gilbert Arenas Dagger 28.04.2020 00:30

На самом деле это возможно. Вы можете использовать теги группы ресурсов, чтобы пометить текущую развернутую версию и пропустить развертывание, если тег установлен. Все это может быть достигнуто с помощью связанного шаблона.
Обратите внимание, что мы не проверяем существование ресурса как такового, но мы по-прежнему разрешаем писать шаблон 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 завершится ошибкой, если указанный объект не содержит свойства. В нашем случае таких свойств два: теги и 'Версия'. «Теги» будет существовать только в том случае, если у конкретной группы ресурсов есть или когда-либо были теги. 'Версия' будет существовать только после того, как мы уже написали его один раз (в основном развертывании). Поэтому, прежде чем мы получим к ним доступ, мы выполняем операцию союз () над возвращаемым объектом с правильным значением по умолчанию, гарантируя, что мы можем безопасно получить доступ к упомянутым свойствам.

Очень мило, и как раз то, что мне было нужно сегодня... и я даже не был тем, кто задавал вопрос. Спасибо!

Razoll 01.05.2020 06:07

Это отличный обходной путь, спасибо! Трюк с union изумительный

Vladislav 15.07.2020 14:52

Хороший ответ Бенни! есть ли способ PATCH теги? (т. е. merge вместо replace). Когда несколько ресурсов, на которые влияет состояние, хранятся в виде тегов RG, становится проблемой сохранить теги без потери некоторых из-за некоторых условий гонки при параллельном выполнении шагов шаблона ARM вместо последовательности.

johni 28.07.2020 14:11

Приятель, ты осознал, как ты это сделал, бесполезную сложность? Собираетесь ли вы применять условия к каждому ресурсу в шаблонах ARM? Во-вторых, если реальный ресурс имеет дрейф конфигурации, он никогда не будет откатываться, если на этом ресурсе не изменен тег версии.

BMW 26.04.2021 03:42

я имею в виду, что это в значительной степени то, что я упомянул в своем ответе, но (аналогично @BMW) я не одобряю такой подход. шаблоны предназначены для того, чтобы на самом деле не заботиться о состоянии, которое присутствует сейчас. они должны просто «сделать это так». у вас есть git для отслеживания предыдущих состояний.

4c74356b41 26.04.2021 17:49

Вы можете найти https://docs.microsoft.com/en-us/azure/developer/terraform/overview это полезным для решения вашего дела.
Hashicorp Terraform — это инструмент с открытым исходным кодом для предоставления и управления облачной инфраструктурой. Он кодирует инфраструктуру в файлах конфигурации, описывающих топологию облачных ресурсов. Эти ресурсы включают виртуальные машины, учетные записи хранения и сетевые интерфейсы. Terraform CLI предоставляет простой механизм для развертывания и версии файлов конфигурации в Azure.

Но это потребует от вас отказа от шаблона ARM.

Другие вопросы по теме