Разработка шаблонов ARM для обеспечения согласованности данных в облаке

Важно!

Для использования этой функции Azure в PowerShell требуется установленный модуль AzureRM. Это устаревший модуль, поддерживаемый только в Windows PowerShell 5.1.x, в который больше не добавляются новые функции. Модули Az и AzureRM являются несовместимыми при использовании с одинаковыми версиями PowerShell. Если вам необходимы обе версии, выполните следующее:

  1. Удалите модуль Az в сеансе PowerShell 5.1.
  2. Установите модуль AzureRM в сеансе PowerShell 5.1.
  3. Скачайте и установите PowerShell Core 6.x или последующей версии.
  4. Установите модуль Az в сеансе PowerShell Core.

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

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

  • Глобальная платформа Azure, поддерживаемая растущей сетью центров обработки данных, управляемых корпорацией Майкрософт, в различных регионах по всему миру.
  • Изолированные национальные облака, такие как Azure для Германии, Azure для государственных организаций и Microsoft Azure под управлением 21Vianet. Национальные облака обеспечивают согласованную платформу с большинством замечательных возможностей, к которым имеют доступ клиенты глобальной платформы Azure по всему миру.
  • Azure Stack, гибридная облачная платформа, которая позволяет доставлять службы Azure из корпоративного центра обработки данных. Предприятия могут настроить Azure Stack в собственных центрах обработки данных или использовать службы Azure от поставщиков услуг, запуская Azure Stack на своих предприятиях (также известных как размещенные регионы).

В основе всех этих облачных сред лежит API, предоставляемый Azure Resource Manager, который обеспечивает широкий ряд пользовательских интерфейсов для взаимодействия с платформой Azure. Этот API предоставляет мощные возможности модели "инфраструктура как код". Любой тип ресурса, который доступен в облачной платформе Azure, можно развернуть и настроить с помощью Azure Resource Manager. Используя один шаблон, можно развернуть и настроить полное приложение, готовое к работе.

Схема различных сред Azure, включая глобальную среду Azure, национальные облака и Azure Stack.

Согласованность глобальной платформы Azure, национальных облаков, размещенных облаков и облака в вашем центре обработки данных позволяет воспользоваться преимуществами Azure Resource Manager. Можно повторно использовать инвестиции в разработку в этих облаках при настройке конфигурации и развертывания ресурсов на основе шаблона.

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

В оставшейся части этого руководства описаны аспекты, которые необходимо учитывать при разработке новых или обновлении существующих шаблонов ARM для Azure Stack. Как правило, такой контрольный список должен включать следующие элементы:

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

Общие сведения о шаблонах ARM см. в статье Развертывание шаблона.

Проверка работы функций шаблонов

Базовый синтаксис шаблона ARM имеет формат JSON. Шаблоны используют подмножество нотации JSON, расширяя синтаксис с помощью выражений и функций. Модуль обработки языка шаблонов часто обновляется для поддержки дополнительных функций шаблонов. Подробное описание доступных функций шаблонов см. в статье Функции шаблонов ARM.

Новые функции шаблонов, представленные в Azure Resource Manager, не сразу становятся доступны в национальных облаках или Azure Stack. Для успешного развертывания шаблона все функции, на которые ссылается шаблон, должны быть доступны в целевом облаке.

Возможности Azure Resource Manager всегда сначала выпускаются в глобальном облаке Azure. Вы можете использовать следующий сценарий PowerShell, чтобы проверить, поддерживаются ли новые функции шаблона в Azure Stack:

  1. Клонируйте репозиторий GitHub: https://github.com/marcvaneijk/arm-template-functions.

  2. Создав локальный клон репозитория, подключитесь к целевому экземпляру Azure Resource Manager с помощью PowerShell.

  3. Импортируйте модуль psm1 и выполните командлет Test-AzureRmTemplateFunctions:

    # Import the module
    Import-module <path to local clone>\AzTemplateFunctions.psm1
    
    # Execute the Test-AzureRmTemplateFunctions cmdlet
    Test-AzureRmTemplateFunctions -path <path to local clone>
    

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

Работа со связанными артефактами

Шаблон может содержать ссылки на связанные артефакты и ресурс развертывания, который ссылается на другой шаблон. Связанные шаблоны (также называемые вложенными шаблонами) извлекаются Resource Manager во время выполнения. Шаблон также может содержать ссылки на артефакты для расширений виртуальной машины. Эти артефакты можно получить с помощью расширения виртуальной машины, выполняющегося внутри виртуальной машины, для настройки расширения виртуальной машины во время развертывания шаблона.

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

Использование вложенных шаблонов в разных регионах

Шаблоны можно разложить на небольшие, многократно используемые шаблоны, каждый из которых имеет конкретное назначение и может повторно использоваться в разных сценариях развертывания. Чтобы выполнить развертывание, необходимо указать один шаблон, называемый главным или основным шаблоном. Он указывает развертываемые ресурсы, такие как виртуальные сети, виртуальные машины и веб-приложения. Основной шаблон также может содержать ссылку на другой шаблон, таким образом, можно создавать вложенные шаблоны. Аналогичным образом, вложенный шаблон может содержать ссылки на другие шаблоны. Для шаблонов поддерживается до пяти уровней вложения.

В следующем коде показано, как параметр templateLink ссылается на вложенный шаблон:

"resources": [
  {
     "type": "Microsoft.Resources/deployments",
     "apiVersion": "2020-10-01",
     "name": "linkedTemplate",
     "properties": {
       "mode": "incremental",
       "templateLink": {
          "uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/vNet.json",
          "contentVersion":"1.0.0.0"
       }
     }
  }
]

Azure Resource Manager оценивает основной шаблон во время выполнения и извлекает и оценивает каждый вложенный шаблон. После извлечения всех вложенных шаблонов шаблон становится плоским и инициируется дальнейшая обработка.

Предоставление доступа к связанным шаблонам в разных облаках

Рассмотрим, где и как хранить используемые связанные шаблоны. Во время выполнения Azure Resource Manager получает все связанные шаблоны, поэтому ему требуется прямой доступ к ним. Как правило, для хранения вложенных шаблонов используется GitHub. Репозиторий GitHub может содержать файлы, доступные всем пользователям Интернета через URL-адрес. Несмотря на то, что это удобный вариант для общедоступного облака и национальных облаков, среда Azure Stack может размещаться в корпоративной сети или в удаленных расположениях, не имеющих исходящего подключения к Интернету. В таком случае Azure Resource Manager не сможет получить доступ к вложенным шаблонам.

Для развертываний в нескольких облаках рекомендуется хранить связанные шаблоны в расположении, доступном для целевого облака. В идеале все артефакты развертывания обслуживаются в конвейере непрерывной интеграции и разработки (CI/CD) и развертываются из него. Кроме того, вложенные шаблоны можно хранить в контейнере хранилища BLOB-объектов, из которого Azure Resource Manager может их получить.

Так как хранилище BLOB-объектов для каждого облака использует другое полное доменное имя (FQDN) конечной точки, в шаблоне необходимо настроить расположение связанных шаблонов с помощью двух параметров. Параметры могут принимать ввод пользователя во время развертывания. Шаблоны обычно создаются и совместно используются несколькими пользователями, поэтому мы рекомендуем применять для этих параметров стандартные имена. Соглашения об именовании помогают расширить возможности использования шаблонов в разных регионах и облачных средах, а также разными авторами.

В следующем примере кода _artifactsLocation используется для указания одного расположения, которое содержит все артефакты, связанные с развертыванием. Обратите внимание, что предоставлено значение по умолчанию. Во время развертывания, если не указать входное значение для _artifactsLocation, используется значение по умолчанию. _artifactsLocationSasToken используется в качестве входных данных для sasToken. Значение по умолчанию должно быть пустой строкой для сценариев, где для _artifactsLocation не предусмотрена защита, как, например, в случае с общедоступным репозиторием GitHub.

"parameters": {
  "_artifactsLocation": {
    "type": "string",
    "metadata": {
      "description": "The base URI where artifacts required by this template are located."
    },
    "defaultValue": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.compute/vm-custom-script-windows/"
  },
  "_artifactsLocationSasToken": {
    "type": "securestring",
    "metadata": {
      "description": "The sasToken required to access _artifactsLocation."
    },
    "defaultValue": ""
  }
}

В шаблоне ссылки создаются путем объединения базового URI (из параметра _artifactsLocation) с относительным путем к артефакту и _artifactsLocationSasToken. В примере кода ниже показано, как указать ссылку на вложенный шаблон с помощью функции шаблона URI:

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2020-10-01",
    "name": "shared",
    "properties": {
      "mode": "Incremental",
      "templateLink": {
        "uri": "[uri(parameters('_artifactsLocation'), concat('nested/vnet.json', parameters('_artifactsLocationSasToken')))]",
        "contentVersion": "1.0.0.0"
      }
    }
  }
]

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

Помимо использования для вложенных шаблонов, URL-адрес в параметре _artifactsLocation используется в качестве основы для всех связанных артефактов шаблона развертывания. Некоторые расширения виртуальных машин включают ссылку на сценарий, который хранится за пределами шаблона. Для этих расширений не следует жестко кодировать ссылки. Например, расширения пользовательских сценариев и PowerShell DSC могут быть связаны с внешним сценарием на сайте GitHub, как показано ниже:

"properties": {
  "publisher": "Microsoft.Compute",
  "type": "CustomScriptExtension",
  "typeHandlerVersion": "1.9",
  "autoUpgradeMinorVersion": true,
  "settings": {
    "fileUris": [
      "https://raw.githubusercontent.com/Microsoft/dotnet-core-sample-templates/master/dotnet-core-music-windows/scripts/configure-music-app.ps1"
    ]
  }
}

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

Resource Manager извлекает вложенные шаблоны во время выполнения. Для расширений виртуальной машины получение любых внешних артефактов выполняется агентом виртуальной машины. Помимо отличия в инициаторе извлечения артефактов, решение в определении шаблона аналогично. Используйте параметр _artifactsLocation со значением базового пути по умолчанию, где хранятся все артефакты (включая сценарии расширений виртуальной машины) и параметр _artifactsLocationSasToken в качестве входных данных для sasToken.

"parameters": {
  "_artifactsLocation": {
    "type": "string",
    "metadata": {
      "description": "The base URI where artifacts required by this template are located."
    },
    "defaultValue": "https://raw.githubusercontent.com/Microsoft/dotnet-core-sample-templates/master/dotnet-core-music-windows/"
  },
  "_artifactsLocationSasToken": {
    "type": "securestring",
    "metadata": {
      "description": "The sasToken required to access _artifactsLocation."
    },
    "defaultValue": ""
  }
}

Для создания абсолютного URI артефакта рекомендуется использовать функцию шаблона uri, вместо функции шаблона concat. Заменив жестко закодированные ссылки на сценарии в расширении виртуальной машины функцией шаблона uri, можно настроить эту функциональность в шаблоне для обеспечения согласованности с облаком.

"properties": {
  "publisher": "Microsoft.Compute",
  "type": "CustomScriptExtension",
  "typeHandlerVersion": "1.9",
  "autoUpgradeMinorVersion": true,
  "settings": {
    "fileUris": [
      "[uri(parameters('_artifactsLocation'), concat('scripts/configure-music-app.ps1', parameters('_artifactsLocationSasToken')))]"
    ]
  }
}

При таком подходе все артефакты развертывания, включая сценарии конфигурации, могут храниться в одном расположении вместе с шаблоном. Чтобы изменить расположение всех ссылок, необходимо только указать другой базовый URL-адрес для параметров artifactsLocation.

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

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

Зная, что набор доступных служб может различаться в разных регионах и облаках Azure, можно принять некоторые упреждающие решения в отношении шаблонов. Лучше всего начать с проверки доступных поставщиков ресурсов для облака. Поставщик ресурсов сообщает о наборе ресурсов и операций, доступных для службы Azure.

Шаблон развертывает и настраивает ресурсы. Тип ресурса предоставляется поставщиком ресурсов. Например, поставщик вычислительных ресурсов (Microsoft.Compute) предоставляет несколько типов ресурсов, таких как virtualMachines и availabilitySets. Каждый поставщик ресурсов предоставляет API для Azure Resource Manager, определяемый общим контрактом, включая согласованные, унифицированные возможности разработки для всех поставщиков ресурсов. Тем не менее поставщик ресурсов, доступный в глобальной платформе Azure, может оказаться недоступным в национальном облаке или регионе Azure Stack.

Схема, иллюстрирующая связь между поставщиками ресурсов, типами ресурсов и версиями API.

Чтобы проверить поставщиков ресурсов, доступных в данной облачной среде, выполните следующий сценарий в Azure CLI:

az provider list --query "[].{Provider:namespace, Status:registrationState}" --out table

Для просмотра доступных поставщиков ресурсов можно также использовать следующий командлет PowerShell:

Get-AzureRmResourceProvider -ListAvailable | Select-Object ProviderNamespace, RegistrationState

Проверка версии всех типов ресурсов

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

Новые версии API, представленные в существующих типах ресурсов в глобальной платформе Azure, могут не сразу становиться доступными во всех регионах, национальных облаках и Azure Stack. Чтобы просмотреть список доступных поставщиков ресурсов, типов ресурсов и версий API для облака, можно использовать обозреватель ресурсов на портале Azure. Найдите обозреватель ресурсов в меню "Все службы". В обозревателе ресурсов разверните узел "Поставщики", чтобы просмотреть всех доступных поставщиков ресурсов, их типы ресурсов и версии API в этом облаке.

Чтобы получить список доступных версий API для всех типов ресурсов в заданном облаке в Azure CLI, выполните следующий сценарий:

az provider list --query "[].{namespace:namespace, resourceType:resourceType[]}"

Вы также можете воспользоваться следующим командлетом PowerShell:

Get-AzureRmResourceProvider | select-object ProviderNamespace -ExpandProperty ResourceTypes | ft ProviderNamespace, ResourceTypeName, ApiVersions

Ссылка на расположения ресурсов с помощью параметра

Шаблон всегда развертывается в группе ресурсов, которая размещается в регионе. Помимо собственно развертывания, каждый ресурс в шаблоне также имеет свойство расположения, которое используется для указания региона для развертывания. Чтобы разработать шаблон для обеспечения согласованности в облаке, нужен динамический способ обращения к расположениям ресурсов, так как каждый экземпляр Azure Stack может содержать уникальные имена расположений. Обычно ресурсы развертываются в том же регионе, что и группа ресурсов, но для поддержки таких сценариев, как доступность приложений между регионами, может быть удобнее распределить ресурсы между регионами.

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

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

Функция шаблона [resourceGroup()] возвращает объект, содержащий следующие пары "ключ-значение":

{
  "id": "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}",
  "name": "{resourceGroupName}",
  "location": "{resourceGroupLocation}",
  "tags": {
  },
  "properties": {
    "provisioningState": "{status}"
  }
}

Ссылаясь на ключ расположения объекта в значении defaultValue входного параметра, Azure Resource Manager во время выполнения заменит функцию шаблона [resourceGroup().location] именем расположения группы ресурсов для развертывания шаблона.

"parameters": {
  "location": {
    "type": "string",
    "metadata": {
      "description": "Location the resources will be deployed to."
    },
    "defaultValue": "[resourceGroup().location]"
  }
},
"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "apiVersion": "2015-06-15",
    "name": "storageaccount1",
    "location": "[parameters('location')]",
    ...

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

Отслеживание версий с помощью профилей API

Отслеживание всех доступных поставщиков ресурсов и связанных версий API, которые есть в Azure Stack, может оказаться очень сложной задачей. Например, на момент написания этой статьи последняя версия API для Microsoft.Compute/availabilitySets в Azure — 2018-04-01, тогда как доступная версия API, общая для Azure и Azure Stack, — 2016-03-30. Общая версия API для Microsoft.Storage/storageAccounts, используемая совместно всеми расположениями Azure и Azure Stack, — 2016-01-01, тогда как последняя версия API в Azure — 2018-02-01.

По этой причине в Resource Manager введена концепция профилей API для шаблонов. Без профилей API для каждого ресурса в шаблоне настраивается элемент apiVersion, описывающий версию API для конкретного ресурса.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "metadata": {
          "description": "Location the resources will be deployed to."
      },
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2016-01-01",
      "name": "mystorageaccount",
      "location": "[parameters('location')]",
      "properties": {
        "accountType": "Standard_LRS"
      }
    },
    {
      "type": "Microsoft.Compute/availabilitySets",
      "apiVersion": "2016-03-30",
      "name": "myavailabilityset",
      "location": "[parameters('location')]",
      "properties": {
        "platformFaultDomainCount": 2,
        "platformUpdateDomainCount": 2
      }
    }
  ],
  "outputs": {}
}

Версия профиля API служит своего рода псевдонимом для отдельной версии API на каждый тип ресурсов, общий для Azure и Azure Stack. Вместо указания версии API для каждого ресурса в шаблоне укажите только версию профиля API в новом корневом элементе apiProfile и не указывайте элемент apiVersion для отдельных ресурсов.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "apiProfile": "2018–03-01-hybrid",
    "parameters": {
        "location": {
            "type": "string",
            "metadata": {
                "description": "Location the resources will be deployed to."
            },
            "defaultValue": "[resourceGroup().location]"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "mystorageaccount",
            "location": "[parameters('location')]",
            "properties": {
                "accountType": "Standard_LRS"
            }
        },
        {
            "type": "Microsoft.Compute/availabilitySets",
            "name": "myavailabilityset",
            "location": "[parameters('location')]",
            "properties": {
                "platformFaultDomainCount": 2,
                "platformUpdateDomainCount": 2
            }
        }
    ],
    "outputs": {}
}

Профиль API гарантирует, что версии API будут доступны в разных расположениях, поэтому вам не нужно вручную проверять значения apiVersion, доступные в определенном расположении. Чтобы гарантировать, что версии API, на которые ссылается профиль API, присутствуют в среде Azure Stack, операторы Azure Stack должны поддерживать решение в актуальном состоянии (на основе политики поддержки). Если система не обновлялась более шести месяцев, она считается несовместимой, и среду необходимо обновить.

Профиль API не является обязательным элементом в шаблоне. Даже если вы добавили этот элемент, он будет использоваться только для ресурсов, для которых не указан apiVersion. Этот элемент позволяет выполнять постепенные изменения, но не требует вносить изменения в существующие шаблоны.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "apiProfile": "2018–03-01-hybrid",
    "parameters": {
        "location": {
            "type": "string",
            "metadata": {
                "description": "Location the resources will be deployed to."
            },
            "defaultValue": "[resourceGroup().location]"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2016-01-01",
            "name": "mystorageaccount",
            "location": "[parameters('location')]",
            "properties": {
                "accountType": "Standard_LRS"
            }
        },
        {
            "type": "Microsoft.Compute/availabilitySets",
            "name": "myavailabilityset",
            "location": "[parameters('location')]",
            "properties": {
                "platformFaultDomainCount": 2,
                "platformUpdateDomainCount": 2
            }
        }
    ],
    "outputs": {}
}

Проверка ссылок на конечные точки

Ресурсы могут иметь ссылки на другие службы в платформе. Например, общедоступному IP-адресу может быть назначено общедоступное DNS-имя. Общедоступное облако, национальные облака и решения Azure Stack имеют собственные различающиеся пространства имен конечной точки. В большинстве случаев ресурс требует только наличия префикса в качестве входных данных в шаблоне. Во время выполнения Azure Resource Manager добавляет к нему значение конечной точки. Некоторые значения конечных точек должны быть явно указаны в шаблоне.

Примечание

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

Следующие два примера — типичные пространства имен конечных точек, которые должны быть явно указаны при создании ресурса:

  • Учетные записи хранения (BLOB-объекты, очереди, таблицы и файлы)
  • Строки подключения для баз данных и кэша Azure для Redis

Пространства имен конечных точек также можно использовать в выходных данных шаблона как сведения для пользователя после завершения развертывания. Ниже приведено несколько типичных примеров.

  • Учетные записи хранения (BLOB-объекты, очереди, таблицы и файлы)
  • Строки подключения (MySql, SQLServer, SQLAzure, Custom, NotificationHub, ServiceBus, EventHub, ApiHub, DocDb, RedisCache, PostgreSQL)
  • Диспетчер трафика
  • domainNameLabel для общедоступного IP-адреса
  • Облачные службы

Как правило, не рекомендуется использовать жестко заданные конечные точки в шаблоне. Лучше всего использовать функцию шаблона reference для динамического получения конечных точек. К распространенным примерам жестко задаваемой конечной точки относится пространство имен конечной точки для учетных записей хранения. Каждой учетной записи хранения назначается уникальное полное доменное имя, сформированное путем объединения имени учетной записи хранения с пространством имен конечной точки. Учетная запись хранения BLOB-объектов с именем mystorageaccount1 получает разные полные доменные имена в зависимости от облака:

  • mystorageaccount1.blob.core.windows.net — при создании в глобальном облаке Azure.
  • mystorageaccount1.blob.core.chinacloudapi.cn при создании в Azure, управляемом облаком 21Vianet.

Следующая функция шаблона reference получает пространство имен конечной точки от поставщика ресурсов хранилища:

"diskUri":"[concat(reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))).primaryEndpoints.blob, 'container/myosdisk.vhd')]"

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

Ссылка на существующие ресурсы по уникальному идентификатору

На существующий ресурс можно также ссылаться из той же или другой группы ресурсов, в той же или в другой подписке в одном клиенте в том же облаке. Чтобы получить свойства ресурса, необходимо использовать уникальный идентификатор для самого ресурса. Функция шаблона resourceId извлекает уникальный идентификатор ресурса, например SQL Server, как показано в следующем коде:

"outputs": {
  "resourceId":{
    "type": "string",
    "value": "[resourceId('otherResourceGroup', 'Microsoft.Sql/servers', parameters('serverName'))]"
  }
}

Затем можно использовать функцию resourceId внутри функции шаблона reference для получения свойств базы данных. Возвращаемый объект содержит свойство fullyQualifiedDomainName, которое содержит полное значение конечной точки. Это значение извлекается во время выполнения и предоставляет пространство имен конечной точки для конкретной облачной среды. Чтобы определить строку подключения без жесткого задания пространства имен конечной точки, можно сослаться на свойство возвращаемого объекта напрямую в строке подключения, как показано ниже:

"[concat('Server=tcp:', reference(resourceId('sql', 'Microsoft.Sql/servers', parameters('test')), '2015-05-01-preview').fullyQualifiedDomainName, ',1433;Initial Catalog=', parameters('database'),';User ID=', parameters('username'), ';Password=', parameters('pass'), ';Encrypt=True;')]"

Необходимость учитывать свойства ресурса

Определенные ресурсы в средах Azure Stack имеют уникальные свойства, которые необходимо учитывать в шаблоне.

Проверка доступности образов виртуальных машин

Azure предоставляет широкий выбор образов виртуальных машин. Эти образы создаются и готовятся к развертыванию корпорацией Майкрософт и партнерами. Образы формируют основу для виртуальных машин на платформе. Тем не менее шаблон, согласованный с облаком, должен ссылаться только на параметры (в частности, издателя, предложение и SKU для образов виртуальных машин), доступные для глобальной среды Azure, национальных облаков Azure и решения Azure Stack.

Чтобы получить список доступных образов виртуальных машин в расположении, выполните следующую команду Azure CLI:

az vm image list -all

Тот же список можно получить с помощью командлета Azure PowerShell Get-AzureRmVMImagePublisher, указав расположение с помощью параметра -Location. Пример:

Get-AzureRmVMImagePublisher -Location "West Europe" | Get-AzureRmVMImageOffer | Get-AzureRmVMImageSku | Get-AzureRmVMImage

Эта команда выполняется несколько минут и возвращает все доступные образы в регионе "Западная Европа" глобального облака Azure.

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

В следующем примере кода показан согласованный подход при указании ссылок на издателя, предложение и параметры SKU в шаблонах ARM:

"storageProfile": {
    "imageReference": {
    "publisher": "MicrosoftWindowsServer",
    "offer": "WindowsServer",
    "sku": "2016-Datacenter",
    "version": "latest"
    }
}

Проверка размеров локальных виртуальных машин

Чтобы разработать шаблон для обеспечения согласованности с облаком, необходимо убедиться, что нужный размер виртуальной машины доступен во всех целевых средах. Размеры виртуальных машин — это группы характеристик производительности и возможностей. Некоторые размеры виртуальных машин зависят от оборудования, на котором выполняется виртуальная машина. Например, если вы хотите развернуть виртуальную машину, оптимизированную для GPU, оборудование, на котором выполняется гипервизор, должно включать аппаратные графические процессоры.

Когда корпорация Майкрософт выпускает новый размер виртуальной машины, имеющий определенные аппаратные зависимости, как правило, такой размер виртуальной машины сначала предоставляется в небольшом наборе регионов в облаке Azure. Позднее он становится доступным в других регионах и облаках. Чтобы убедиться, что размер виртуальной машины существует в каждом целевом облаке, можно получить доступные размеры с помощью следующей команды Azure CLI:

az vm list-sizes --location "West Europe"

Для Azure PowerShell:

Get-AzureRmVMSize -Location "West Europe"

Полный список доступных служб см. на странице Доступность продуктов по регионам.

Проверка использования управляемых дисков Azure в Azure Stack

Управляемые диски обрабатывают хранилища для клиента Azure. Вместо явного создания учетной записи хранения и указания URI для виртуального жесткого диска (VHD) можно использовать управляемые диски для неявного выполнения этих действий при развертывании виртуальной машины. Управляемые диски помогают повысить доступность благодаря размещению всех дисков из виртуальных машин в одной группе доступности в разных единицах хранения. Кроме того, существующие виртуальные жесткие диски можно преобразовать из уровня хранилища "Стандартный" в уровень "Премиум", чтобы существенно сократить время простоя.

Несмотря на то, что управляемые диски включены в планы по выпуску для Azure Stack, в настоящее время они не поддерживаются. Тем временем вы можете разрабатывать согласованные с облаком шаблоны для Azure Stack, явно указывая виртуальные жесткие диски с помощью элемента vhd в шаблоне для ресурса виртуальной машины, как показано ниже:

"storageProfile": {
  "imageReference": {
    "publisher": "MicrosoftWindowsServer",
    "offer": "WindowsServer",
    "sku": "[parameters('windowsOSVersion')]",
    "version": "latest"
  },
  "osDisk": {
    "name": "osdisk",
    "vhd": {
      "uri": "[concat(reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), '2015-06-15').primaryEndpoints.blob, 'vhds/osdisk.vhd')]"
    },
    "caching": "ReadWrite",
    "createOption": "FromImage"
  }
}

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

"storageProfile": {
  "imageReference": {
    "publisher": "MicrosoftWindowsServer",
    "offer": "WindowsServer",
    "sku": "[parameters('windowsOSVersion')]",
    "version": "latest"
  },
  "osDisk": {
    "caching": "ReadWrite",
    "createOption": "FromImage"
  }
}

Аналогичные изменения также применяются к дискам данных.

Проверка доступности расширений виртуальной машины в Azure Stack

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

Например, если вы хотите настроить виртуальную машину под управлением Microsoft SQL Server, расширение виртуальной машины может настраивать SQL Server в процессе развертывания шаблона. Рассмотрим, что произойдет, если шаблон развертывания также содержит сервер приложений, настроенный для создания базы данных на виртуальной машине под управлением SQL Server. Помимо использования расширения виртуальной машины для серверов приложений, можно настроить зависимость сервера приложений от успешного возвращения ресурса расширения виртуальной машины SQL Server. Такой подход гарантирует, что виртуальная машина под управлением SQL Server будет настроена и доступна на тот момент, когда сервер приложений получит указание создать базу данных.

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

Проверка доступности расширений виртуальной машины

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

Для получения списка расширений виртуальной машины, доступных для определенного региона (в этом примере myLocation), выполните следующую команду Azure CLI:

az vm extension image list --location myLocation

Вы также можете выполнить командлет Azure PowerShell Get-AzureRmVmImagePublisher и использовать -Location для указания расположения образа виртуальной машины. Пример:

Get-AzureRmVmImagePublisher -Location myLocation | Get-AzureRmVMExtensionImageType | Get-AzureRmVMExtensionImage | Select Type, Version

Проверка доступности версий

Поскольку расширения виртуальной машины являются основными ресурсами Resource Manager, они имеют собственные версии API. Как показано в следующем примере кода, тип расширения виртуальной машины — это вложенный ресурс в поставщике ресурсов Microsoft.Compute.

{
    "type": "Microsoft.Compute/virtualMachines/extensions",
    "apiVersion": "2015-06-15",
    "name": "myExtension",
    "location": "[parameters('location')]",
    ...

Версия API ресурса расширения виртуальной машины должна присутствовать во всех планируемых целевых расположениях шаблона. Зависимость расположений действует аналогично доступности версии API поставщика ресурсов, о которой говорилось выше в разделе "Проверка версии всех типов ресурсов".

Чтобы получить список доступных версий API для ресурса расширения виртуальной машины, используйте командлет Get-AzureRmResourceProvider с поставщиком ресурсов Microsoft.Compute, как показано ниже:

Get-AzureRmResourceProvider -ProviderNamespace "Microsoft.Compute" | Select-Object -ExpandProperty ResourceTypes | Select ResourceTypeName, Locations, ApiVersions | where {$_.ResourceTypeName -eq "virtualMachines/extensions"}

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

Get-AzureRmResourceProvider -ProviderNamespace "Microsoft.Compute" | Select-Object -ExpandProperty ResourceTypes | Select ResourceTypeName, Locations, ApiVersions | where {$_.ResourceTypeName -eq "virtualMachineScaleSets/extensions"}

Каждому конкретному расширению также назначается версия. Эта версия отображается в свойстве typeHandlerVersion расширения виртуальной машины. Убедитесь, что версия, указанная в элементе typeHandlerVersion расширений виртуальной машины в шаблоне, доступна в расположениях, где планируется развернуть шаблон. Например, следующий код указывает версию 1.7:

{
    "type": "extensions",
    "apiVersion": "2016-03-30",
    "name": "MyCustomScriptExtension",
    "location": "[parameters('location')]",
    "dependsOn": [
        "[concat('Microsoft.Compute/virtualMachines/myVM', copyindex())]"
    ],
    "properties": {
        "publisher": "Microsoft.Compute",
        "type": "CustomScriptExtension",
        "typeHandlerVersion": "1.7",
        ...

Чтобы получить список доступных версий для определенного расширения виртуальной машины, используйте командлет Get-AzureRmVMExtensionImage. Следующий пример получает доступные версии расширения виртуальной машины PowerShell DSC (Desired State Configuration) из myLocation:

Get-AzureRmVMExtensionImage -Location myLocation -PublisherName Microsoft.PowerShell -Type DSC | FT

Для получения списка издателей используйте командлет Get-AzureRmVMImagePublisher. Чтобы запросить тип, используйте командлет Get-AzureRmVMExtensionImageType.

Советы по тестированию и автоматизации

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

Ниже показан типичный пример процесса разработки для команды, использующей интегрированную среду разработки (IDE). На разных этапах временной шкалы выполняются разные типы тестов. Здесь два разработчика работают над одним решением, однако этот сценарий в равной степени применим к одному разработчику или большой рабочей группе. Каждый разработчик, как правило, создает локальную копию центрального репозитория, что позволяет разработчикам работать со своей локальной копией, не пересекаясь с другими участниками команды, которые работают над теми же файлами.

Схема, показывающая параллельные модульные тесты и интеграционные тесты в локальных средах разработки, слияние в поток разработки CI/CD с модульными тестами, интеграционными тестами, тестовым развертыванием и окончательным развертыванием.

Примите во внимание следующие советы по тестированию и автоматизации.

  • Используйте средства тестирования. Например, Visual Studio Code и Visual Studio включают IntelliSense и другие компоненты, которые помогут вам проверить шаблоны.
  • Чтобы повысить качество кода во время разработки в локальной интегрированной среде разработки, выполните статический анализ кода с помощью модульных тестов и тестов интеграции.
  • Для еще более эффективной работы в ходе начальной разработки модульные тесты и тесты интеграции должны выдавать предупреждения только при обнаружении ошибки и продолжать выполнение. Таким образом, можно определить проблемы, требующие решения, а также приоритет вносимых изменений. Такой подход также называют разработкой на основе тестирования (TDD).
  • Имейте в виду, что некоторые тесты могут выполняться без подключения к Azure Resource Manager. Другие, такие как тестирование развертывания шаблона, требуют выполнения некоторых действий со стороны Resource Manager, которые не могут происходить в автономном режиме.
  • Тестирование шаблона развертывания с использованием API проверки не тождественно фактическому развертыванию. Кроме того, даже при развертывании шаблона из локального файла все ссылки на вложенные шаблоны в шаблоне извлекаются Resource Manager напрямую, а артефакты, на которые ссылаются расширения виртуальной машины, извлекаются агентом виртуальной машины, работающим на развернутой виртуальной машине.

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