Поделиться через


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

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

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

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

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

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

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

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

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

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

Параметры

Сведения в этом разделе могут быть полезны при работе с параметрами.

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

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

  • Используйте camel case для имен параметров.

  • Используйте параметры для настроек, которые зависят от среды, например 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 разрешает этот конфликт именования, добавив postfix 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 для параметра расположения. Указанные расположения могут быть недоступны во всех облаках.

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

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

Переменные

При работе с переменными могут быть полезны следующие сведения:

  • Используйте camelCase для имен переменных.

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

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

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

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

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

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

Версия API

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

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

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

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

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

При выборе зависимостей , которые необходимо задать, используйте следующие рекомендации.

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

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

  • Ресурсы с элементом condition, установленным 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]"
      }
    }
    

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

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

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

  • Свойство 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-файле, включая файлы параметров.

Инструменты Visual Studio Code для ARM

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

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

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

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

Дальнейшие шаги