Рекомендации по работе с шаблоном ARM

В этой статье показано, как использовать рекомендации при создании шаблона Azure Resource Manager (шаблона ARM). Эти рекомендации помогут избежать распространенных проблем при использовании шаблона ARM для развертывания решения.

Ограничения шаблонов

Ограничьте размер шаблона 4 МБ, а определение каждого ресурса — 1 МБ. Ограничения применяются к конечному состоянию шаблона после его расширения с помощью итеративных определений ресурсов, а также значений для переменных и параметров. Файл параметров также ограничен до 4 МБ. Если общий размер запроса слишком велик, может возникнуть ошибка с файлом шаблона или параметров размером менее 4 МБ. Дополнительные сведения о том, как упростить шаблон, чтобы запрос не был слишком большим, см. в статье Устранение ошибок при превышении размера задания.

Кроме того, ограничение распространяется на:

  • 256 параметров;
  • 256 переменных;
  • 800 ресурсов (включая число копий);
  • 64 выходных значения;
  • 10 уникальных расположений на подписку, клиент или область группы управления
  • 24 576 знаков в выражении шаблона.

Некоторые ограничения можно превысить, используя вложенные шаблоны. Дополнительные сведения см. в статье Использование связанных и вложенных шаблонов при развертывании ресурсов Azure. Чтобы уменьшить число параметров, переменных или выходных данных, можно объединить несколько значений в объект. См. дополнительные сведения об использовании объектов как параметров.

Группа ресурсов

При развертывании ресурсов в группе ресурсов она будет хранить метаданные о ресурсах. Метаданные будут храниться в расположении группы ресурсов.

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

Параметры

Здесь приведены некоторые рекомендации по работе с параметрами.

Общие рекомендации по работе с параметрами

  • Используйте как можно меньше параметров. Вместо этого используйте переменные или литеральные значения для свойств, которые не указываются во время развертывания.

  • Имена для параметров необходимо указывать в нижнем регистре.

  • Используйте параметры для настроек, которые могут меняться в зависимости от среды, например SKU, размера или емкости.

  • Используйте параметры для имен ресурсов, которые вы хотите задать, чтобы упростить идентификацию.

  • Укажите описание для каждого параметра в метаданных.

    "parameters": {
      "storageAccountType": {
        "type": "string",
        "metadata": {
          "description": "The type of the new storage account created to store the VM disks."
        }
      }
    }
    
  • Укажите значения по умолчанию для конфиденциальных параметров. Указав значение по умолчанию, проще развернуть шаблон, и пользователи шаблона будут видеть пример соответствующего значения. Любое значение для параметра по умолчанию должно быть допустимым для всех пользователей в конфигурации развертывания по умолчанию.

    "parameters": {
      "storageAccountType": {
        "type": "string",
        "defaultValue": "Standard_GRS",
        "metadata": {
          "description": "The type of the new storage account created to store the VM disks."
        }
      }
    }
    
  • Чтобы указать дополнительный параметр, не используйте пустую строку в качестве значения по умолчанию. Вместо этого используйте литеральное значение или выражение языка для составления значения.

    "storageAccountName": {
       "type": "string",
       "defaultValue": "[concat('storage', uniqueString(resourceGroup().id))]",
       "metadata": {
         "description": "Name of the storage account"
       }
    }
    
  • Используйте allowedValues только в крайнем случае. Используйте ее только в том случае, когда необходимо убедиться в том, что некоторые значения не включены в разрешенные параметры. При излишнем использовании allowedValues допустимые развертывания можно заблокировать, не обновляя списка.

  • Если имя параметра в шаблоне совпадает с параметром в команде развертывания PowerShell, Resource Manager разрешает такие конфликты именования, добавляя постфикс FromTemplate к параметру шаблона. Предположим, вы добавили в шаблон параметр ResourceGroupName, и он конфликтует с параметром ResourceGroupName в командлете New-AzResourceGroupDeployment. При развертывании вам будет предложено указать значение для параметра ResourceGroupNameFromTemplate.

Рекомендации по безопасности параметров

  • Всегда используйте параметры для имен пользователей и паролей (или секретов).

  • Используйте securestring для всех паролей и секретов. При передаче конфиденциальных данных в объекте JSON используйте тип secureObject. Параметры шаблона с типами строки и объекта безопасности невозможно считать после развертывания ресурса.

    "parameters": {
      "secretValue": {
        "type": "securestring",
        "metadata": {
          "description": "The value of the secret to store in the vault."
        }
      }
    }
    
  • Не указывайте значения по умолчанию для имен пользователей, паролей или любое значение, которое требует тип secureString.

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

Рекомендации по расположению параметров

  • Используйте параметр для указания расположения ресурсов и задайте значения по умолчанию для resourceGroup().location. Параметр расположения позволяет пользователям шаблона указывать расположение, на которое они имеют разрешение для развертывания ресурсов.

    "parameters": {
       "location": {
         "type": "string",
         "defaultValue": "[resourceGroup().location]",
         "metadata": {
           "description": "The location in which the resources should be deployed."
         }
       }
    }
    
  • Не указывайте allowedValues для параметра расположения. Указываемые расположения могут оказаться недоступными во всех облаках.

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

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

Переменные

Ниже приведены некоторые рекомендации по работе с переменными.

  • Используйте "верблюжий" стиль для имен переменных.

  • Применяйте переменные для значений, которые необходимо использовать в шаблоне более одного раза. Если значение используется только один раз, жестко задайте его. Это облегчит чтение шаблона.

  • Используйте переменные для значений, составленных на основе сложного упорядочения функций шаблонов. Шаблон более удобен для считывания, если сложное выражение отображается только в переменных.

  • Нельзя использовать функцию reference в разделе variables в шаблоне. Функция reference получает свое значение из состояния среды выполнения ресурса. а переменные разрешаются при начальной обработке шаблона. Создайте значения, для которых требуется функция reference, непосредственно в разделах resources или outputs в шаблоне.

  • Добавьте переменные для имен ресурсов, которые должны быть уникальными.

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

  • Удалите неиспользуемые переменные.

Версия API

Задайте для свойства apiVersion жестко заданную версию API для типа ресурса. При создании нового шаблона рекомендуется использовать последнюю версию API для типа ресурса. Чтобы определить доступные значения, см. справочник по шаблонам.

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

Не используйте параметр для версии API. Свойства и значения ресурсов могут отличаться в зависимости от версии API. Функции IntelliSense в редакторах кода не могут определить правильную схему, если версия API указана в качестве значения параметра. При передаче версии API, которая не соответствует свойствам в шаблоне, развертывание завершится сбоем.

Не используйте переменные для версии API.

Зависимости ресурсов

Решая, какие зависимости следует установить, следуйте следующим рекомендациям.

  • Используйте функцию reference и передайте имя ресурса, чтобы задать неявные зависимости между ресурсами, которые должны совместно использовать свойство. Не добавляйте явный элемент dependsOn, если неявная зависимость уже определена. Такой подход уменьшает риск появления ненужных зависимостей. Пример настройки неявной зависимости см. в разделе о функциях reference и list.

  • Назначайте дочерний ресурс зависимым от его родительского ресурса.

  • Ресурсы, в которых установлено значение элемента условияfalse, автоматически удаляются из порядка зависимостей. Назначайте зависимости так, как и при развернутом ресурсе.

  • Позвольте зависимостям задействоваться последовательно, не задавая их явно. Например, виртуальная машина зависит от виртуального сетевого интерфейса, а он зависит от виртуальной сети и общедоступных IP-адресов. Таким образом, виртуальная машина развертывается только после всех трех ресурсов, но эта зависимость виртуальной машины от них не задана явным образом. Такой подход проясняет порядок зависимостей и упрощает последующее изменение шаблона.

  • Если значение может быть определено до развертывания, попробуйте развернуть ресурс без зависимостей. Например, если в значении конфигурации требуется указать имя другого ресурса, можно обойтись и без зависимости. Эта рекомендация не всегда уместна, так как некоторые ресурсы проверяют наличие другого ресурса. Если произошла ошибка, добавьте зависимость.

Ресурсы

Ниже приведены некоторые рекомендации по работе с ресурсами.

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

    "resources": [
      {
        "name": "[variables('storageAccountName')]",
        "type": "Microsoft.Storage/storageAccounts",
        "apiVersion": "2019-06-01",
        "location": "[resourceGroup().location]",
        "comments": "This storage account is used to store the VM disks.",
          ...
      }
    ]
    

    Если шаблон ARM хранится в файле .jsonc, комментарии, использующие синтаксис //, поддерживаются, как показано ниже.

    "resources": [
      {
        // This storage account is used to store the VM disks.
        "name": "[variables('storageAccountName')]",
        "type": "Microsoft.Storage/storageAccounts",
        "apiVersion": "2019-06-01",
        "location": "[resourceGroup().location]",
          ...
      }
    ]
    

    Дополнительные сведения о комментариях и метаданных см. в статье Общие сведения о структуре и синтаксисе шаблонов ARM.

  • Если вы используете в шаблоне общедоступную конечную точку (например, общедоступную конечную точку хранилища BLOB-объектов Azure), то не следует жестко кодировать пространство имен. Используйте функцию reference для динамического извлечения пространства имен. Вы можете использовать этот подход, чтобы развернуть шаблон в другом общедоступном пространстве имен, не изменяя конечную точку в шаблоне вручную. Задайте для версии API ту же версию, которая указана в учетной записи хранения в вашем шаблоне.

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2019-06-01').primaryEndpoints.blob]"
      }
    }
    

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

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(variables('storageAccountName')).primaryEndpoints.blob]"
      }
    }
    

    Можно также использовать функцию reference для ссылки на учетную запись хранения в другой группе ресурсов.

    "diagnosticsProfile": {
      "bootDiagnostics": {
        "enabled": "true",
        "storageUri": "[reference(resourceId(parameters('existingResourceGroup'), 'Microsoft.Storage/storageAccounts', parameters('existingStorageAccountName')), '2019-06-01').primaryEndpoints.blob]"
      }
    }
    
  • Назначайте общедоступные IP-адреса виртуальной машине только в том случае, если это требуется для работы приложения. Чтобы подключиться к виртуальной машине с целью администрирования, используйте правила преобразования сетевых адресов для входящих подключений, шлюз виртуальной машины или jumpbox.

    Дополнительные сведения о подключении к виртуальным машинам можно получить в приведенных ниже статьях.

  • Свойство domainNameLabel для общедоступных IP-адресов должно быть уникальным. Свойство domainNameLabel должно содержать от 3 до 63 знаков и соответствовать правилам, определенным таким регулярным выражением: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. Так как функция uniqueString создает строку длиной 13 знаков, в параметре dnsPrefixString можно использовать не более 50 знаков.

    "parameters": {
      "dnsPrefixString": {
        "type": "string",
        "maxLength": 50,
        "metadata": {
          "description": "The DNS label for the public IP address. It must be lowercase. It should match the following regular expression, or it will raise an error: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$"
        }
      }
    },
    "variables": {
      "dnsPrefix": "[concat(parameters('dnsPrefixString'),uniquestring(resourceGroup().id))]"
    }
    
  • При добавлении пароля к расширению пользовательских скриптов используйте свойство commandToExecute в свойстве protectedSettings.

    "properties": {
      "publisher": "Microsoft.Azure.Extensions",
      "type": "CustomScript",
      "typeHandlerVersion": "2.0",
      "autoUpgradeMinorVersion": true,
      "settings": {
        "fileUris": [
          "[concat(variables('template').assets, '/lamp-app/install_lamp.sh')]"
        ]
      },
      "protectedSettings": {
        "commandToExecute": "[concat('sh install_lamp.sh ', parameters('mySqlPassword'))]"
      }
    }
    

    Примечание

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

  • Укажите явные значения для свойств, имеющих значения по умолчанию, которые могут изменяться со временем. Например, при развертывании кластера AKS можно либо указать, либо пропустить свойство kubernetesVersion. Если оно не будет указано, тогда для кластера по умолчанию будет использоваться дополнительный номер версии N-1, а также последнее исправление. При развертывании кластера с помощью шаблона ARM это поведение по умолчанию может отличаться от ожидаемого. Повторное развертывание шаблона может привести к непредвиденному обновлению кластера до новой версии Kubernetes. Вместо этого рекомендуется указать явный номер версии, а затем вручную изменить его, когда вы будете готовы к обновлению кластера.

Комментарии

В дополнение к свойству comments поддерживаются комментарии с использованием синтаксиса //. Дополнительные сведения о комментариях и метаданных см. в статье Общие сведения о структуре и синтаксисе шаблонов ARM. JSON-файлы, содержащие примечания //, можно сохранить используя расширение файла .jsonc, чтобы указать, что JSON-файл содержит комментарии. Служба ARM также будет принимать комментарии в любом JSON-файле, включая файлы параметров.

Средства ARM Visual Studio Code

Работать с шаблонами ARM гораздо проще с помощью средств Azure Resource Manager (ARM) для Visual Studio Code. Это расширение обеспечивает поддержку языка, фрагменты ресурсов и автоматическое завершение ресурсов, чтобы помочь вам создавать и проверять шаблоны Resource Manager Azure. Дополнительные сведения и установка расширения см. в странице со сведениями о средствах A Resource Manager (ARM).

Использование набора средств тестирования

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

Завершив работу с шаблоном, запустите набор средств тестирования, чтобы узнать, есть ли способы улучшить его реализацию. Дополнительные сведения см. в статье Использование набора средств для тестирования шаблонов ARM.

Дальнейшие действия