Краткое руководство. Создание и публикация определения управляемого приложения Azure с помощью собственного хранилища

В этом кратком руководстве приведены общие сведения о том, как использовать собственное хранилище (BYOS) для управляемого приложения Azure. Вы создаете и публикуете определение управляемого приложения в каталоге служб для членов вашей организации. При использовании собственной учетной записи хранения определение управляемого приложения может превышать ограничение на 120-МБ каталога служб.

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

  • Создайте шаблон Azure Resource Manager (шаблон ARM), определяющий ресурсы Azure, развернутые управляемым приложением.
  • Определите элементы пользовательского интерфейса для портала при развертывании управляемого приложения.
  • Создайте ZIP-пакет, содержащий необходимые JSON-файлы.
  • Создайте учетную запись хранения, в которой хранится определение управляемого приложения.
  • Разверните определение управляемого приложения в собственной учетной записи хранения, чтобы она была доступна в каталоге служб.

Если определение управляемого приложения меньше 120 МБ и вы не хотите использовать собственную учетную запись хранения, перейдите в краткое руководство. Создание и публикация определения управляемого приложения Azure.

Вы можете использовать Bicep для разработки определения управляемого приложения, но его необходимо преобразовать в json шаблона ARM, прежде чем опубликовать определение в Azure. Дополнительные сведения см. в кратком руководстве. Использование Bicep для создания и публикации определения управляемого приложения Azure.

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

Необходимые компоненты

Для работы с этим кратким руководством вам потребуется следующее:

Создание шаблона ARM

В каждом определении управляемого приложения указан файл с именем mainTemplate.json. Шаблон определяет ресурсы Azure для развертывания и не отличается от обычного шаблона ARM.

Откройте Visual Studio Code, создайте файл с именем mainTemplate.json (с учетом регистра) и сохраните его.

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

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    },
    "appServicePlanName": {
      "type": "string",
      "maxLength": 40,
      "metadata": {
        "description": "App Service plan name."
      }
    },
    "appServiceNamePrefix": {
      "type": "string",
      "maxLength": 47,
      "metadata": {
        "description": "App Service name prefix."
      }
    },
    "storageAccountNamePrefix": {
      "type": "string",
      "maxLength": 11,
      "metadata": {
        "description": "Storage account name prefix."
      }
    },
    "storageAccountType": {
      "type": "string",
      "allowedValues": [
        "Premium_LRS",
        "Standard_LRS",
        "Standard_GRS"
      ],
      "metadata": {
        "description": "Storage account type allowed values"
      }
    }
  },
  "variables": {
    "appServicePlanSku": "F1",
    "appServicePlanCapacity": 1,
    "appServiceName": "[format('{0}{1}', parameters('appServiceNamePrefix'), uniqueString(resourceGroup().id))]",
    "storageAccountName": "[format('{0}{1}', parameters('storageAccountNamePrefix'), uniqueString(resourceGroup().id))]"
  },
  "resources": [
    {
      "type": "Microsoft.Web/serverfarms",
      "apiVersion": "2022-03-01",
      "name": "[parameters('appServicePlanName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[variables('appServicePlanSku')]",
        "capacity": "[variables('appServicePlanCapacity')]"
      }
    },
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2022-03-01",
      "name": "[variables('appServiceName')]",
      "location": "[parameters('location')]",
      "properties": {
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]",
        "httpsOnly": true,
        "siteConfig": {
          "appSettings": [
            {
              "name": "AppServiceStorageConnectionString",
              "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};Key={2}', variables('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2022-09-01').keys[0].value)]"
            }
          ]
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]",
        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
      ]
    },
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2022-09-01",
      "name": "[variables('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[parameters('storageAccountType')]"
      },
      "kind": "StorageV2",
      "properties": {
        "accessTier": "Hot"
      }
    }
  ],
  "outputs": {
    "appServicePlan": {
      "type": "string",
      "value": "[parameters('appServicePlanName')]"
    },
    "appServiceApp": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.Web/sites', variables('appServiceName')), '2022-03-01').defaultHostName]"
    },
    "storageAccount": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2022-09-01').primaryEndpoints.blob]"
    }
  }
}

Определение интерфейса портала

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

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

Откройте Visual Studio Code, создайте файл с именем createUiDefinition.json (с учетом регистра) и сохраните его.

Добавьте следующий код JSON в файл и сохраните его.

{
  "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#",
  "handler": "Microsoft.Azure.CreateUIDef",
  "version": "0.1.2-preview",
  "parameters": {
    "basics": [
      {}
    ],
    "steps": [
      {
        "name": "webAppSettings",
        "label": "Web App settings",
        "subLabel": {
          "preValidation": "Configure the web app settings",
          "postValidation": "Completed"
        },
        "elements": [
          {
            "name": "appServicePlanName",
            "type": "Microsoft.Common.TextBox",
            "label": "App Service plan name",
            "placeholder": "App Service plan name",
            "defaultValue": "",
            "toolTip": "Use alphanumeric characters or hyphens with a maximum of 40 characters.",
            "constraints": {
              "required": true,
              "regex": "^[a-z0-9A-Z-]{1,40}$",
              "validationMessage": "Only alphanumeric characters or hyphens are allowed, with a maximum of 40 characters."
            },
            "visible": true
          },
          {
            "name": "appServiceName",
            "type": "Microsoft.Common.TextBox",
            "label": "App Service name prefix",
            "placeholder": "App Service name prefix",
            "defaultValue": "",
            "toolTip": "Use alphanumeric characters or hyphens with minimum of 2 characters and maximum of 47 characters.",
            "constraints": {
              "required": true,
              "regex": "^[a-z0-9A-Z-]{2,47}$",
              "validationMessage": "Only alphanumeric characters or hyphens are allowed, with a minimum of 2 characters and maximum of 47 characters."
            },
            "visible": true
          }
        ]
      },
      {
        "name": "storageConfig",
        "label": "Storage settings",
        "subLabel": {
          "preValidation": "Configure the storage settings",
          "postValidation": "Completed"
        },
        "elements": [
          {
            "name": "storageAccounts",
            "type": "Microsoft.Storage.MultiStorageAccountCombo",
            "label": {
              "prefix": "Storage account name prefix",
              "type": "Storage account type"
            },
            "toolTip": {
              "prefix": "Enter maximum of 11 lowercase letters or numbers.",
              "type": "Available choices are Standard_LRS, Standard_GRS, and Premium_LRS."
            },
            "defaultValue": {
              "type": "Standard_LRS"
            },
            "constraints": {
              "allowedTypes": [
                "Premium_LRS",
                "Standard_LRS",
                "Standard_GRS"
              ]
            },
            "visible": true
          }
        ]
      }
    ],
    "outputs": {
      "location": "[location()]",
      "appServicePlanName": "[steps('webAppSettings').appServicePlanName]",
      "appServiceNamePrefix": "[steps('webAppSettings').appServiceName]",
      "storageAccountNamePrefix": "[steps('storageConfig').storageAccounts.prefix]",
      "storageAccountType": "[steps('storageConfig').storageAccounts.type]"
    }
  }
}

Дополнительные сведения см. в разделе "Начало работы с CreateUiDefinition".

Упаковка файлов

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

Отправьте app.zip в учетную запись хранения Azure, чтобы ее можно было использовать при развертывании определения управляемого приложения. Имя учетной записи хранения должно быть глобально уникальным в Azure, а его длина должна составлять 3–24 символа (допускаются только строчные буквы и цифры). В команде замените заполнитель <demostorageaccount> , включая угловые скобки (<>), на имя уникальной учетной записи хранения.

New-AzResourceGroup -Name packageStorageGroup -Location westus3

$storageAccount = New-AzStorageAccount `
  -ResourceGroupName packageStorageGroup `
  -Name "<demostorageaccount>" `
  -Location westus3 `
  -SkuName Standard_LRS `
  -Kind StorageV2

$ctx = $storageAccount.Context

New-AzStorageContainer -Name appcontainer -Context $ctx -Permission blob

Set-AzStorageBlobContent `
  -File "app.zip" `
  -Container appcontainer `
  -Blob "app.zip" `
  -Context $ctx

Используйте следующую команду, чтобы сохранить универсальный код ресурса (URI) файла пакета в переменной с именем packageuri. Значение переменной используется при развертывании определения управляемого приложения.

$packageuri=(Get-AzStorageBlob -Container appcontainer -Blob app.zip -Context $ctx).ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri

Предоставление собственного хранилища для определения управляемого приложения

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

Примечание.

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

Создание учетной записи хранения

Создайте учетную запись хранения для определения управляемого приложения. Имя учетной записи хранения должно быть глобально уникальным в Azure, а его длина должна составлять 3–24 символа (допускаются только строчные буквы и цифры).

В этом примере показано создание группы ресурсов с именем byosDefinitionStorageGroup. В команде замените заполнитель <definitionstorage> , включая угловые скобки (<>), на имя уникальной учетной записи хранения.

New-AzResourceGroup -Name byosDefinitionStorageGroup -Location westus3

New-AzStorageAccount `
  -ResourceGroupName byosDefinitionStorageGroup `
  -Name "<definitionstorage>" `
  -Location westus3 `
  -SkuName Standard_LRS `
  -Kind StorageV2

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

$storageid = (Get-AzStorageAccount -ResourceGroupName byosDefinitionStorageGroup -Name <definitionstorage>).Id

Назначение ролей для учетной записи хранения

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

Для настройки назначения роли можно использовать переменные. В этом примере используется переменная $storageid , созданная на предыдущем шаге, и создается $arpid переменная.

$arpid = (Get-AzADServicePrincipal -SearchString "Appliance Resource Provider").Id

New-AzRoleAssignment -ObjectId $arpid `
-RoleDefinitionName Contributor `
-Scope $storageid

Поставщик ресурсов устройства — это субъект-служба в клиенте Microsoft Entra. В портал Azure можно проверить, зарегистрировано ли оно, перейдя в приложения Microsoft Entra ID>Enterprise и изменив фильтр поиска на приложения Майкрософт. Найдите Поставщик ресурсов устройства. Если он не найден, зарегистрируйтеMicrosoft.Solutions поставщика ресурсов.

Получение идентификатора группы и идентификатора определения роли

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

В этом примере используется группа безопасности, а учетная запись Microsoft Entra должна быть членом группы. Чтобы получить идентификатор объекта группы, замените заполнитель <managedAppDemo> , включая угловые скобки (<>), именем группы. Значение переменной используется при развертывании определения управляемого приложения.

Чтобы создать новую группу Microsoft Entra, перейдите к разделу "Управление группами Microsoft Entra" и членством в группах.

$principalid=(Get-AzADGroup -DisplayName <managedAppDemo>).Id

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

$roleid=(Get-AzRoleDefinition -Name Owner).Id

Создание шаблона развертывания определения

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

Откройте Visual Studio Code, создайте файл с именем deployDefinition.bicep и сохраните его.

Добавьте следующий код Bicep и сохраните файл.

param location string = resourceGroup().location

@description('Name of the managed application definition.')
param managedApplicationDefinitionName string

@description('Resource ID for the bring your own storage account where the definition is stored.')
param definitionStorageResourceID string

@description('The URI of the .zip package file.')
param packageFileUri string

@description('Publishers Principal ID that needs permissions to manage resources in the managed resource group.')
param principalId string

@description('Role ID for permissions to the managed resource group.')
param roleId string

var definitionLockLevel = 'ReadOnly'
var definitionDisplayName = 'Sample BYOS managed application'
var definitionDescription = 'Sample BYOS managed application that deploys web resources'

resource managedApplicationDefinition 'Microsoft.Solutions/applicationDefinitions@2021-07-01' = {
  name: managedApplicationDefinitionName
  location: location
  properties: {
    lockLevel: definitionLockLevel
    description: definitionDescription
    displayName: definitionDisplayName
    packageFileUri: packageFileUri
    storageAccountId: definitionStorageResourceID
    authorizations: [
      {
        principalId: principalId
        roleDefinitionId: roleId
      }
    ]
  }
}

Дополнительные сведения о свойствах шаблона см. в разделе Microsoft.Solutions/applicationDefinitions.

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

Создание файла параметров

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

В Visual Studio Code создайте файл с именем deployDefinition.parameters.json и сохраните его.

Добавьте следующий код в файл параметров и сохраните его. Затем замените <placeholder values> включаемые угловые скобки (<>) значениями.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "managedApplicationDefinitionName": {
      "value": "<placeholder for managed application name>"
    },
    "definitionStorageResourceID": {
      "value": "<placeholder for you storage account ID>"
    },
    "packageFileUri": {
      "value": "<placeholder for the packageFileUri>"
    },
    "principalId": {
      "value": "<placeholder for principalid value>"
    },
    "roleId": {
      "value": "<placeholder for roleid value>"
    }
  }
}

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

Параметр Значение
managedApplicationDefinitionName Имя определения управляемого приложения. В этом примере используйте sampleByosManagedApplication.
definitionStorageResourceID Идентификатор ресурса для учетной записи хранения, в которой хранится определение. storageid Используйте значение переменной.
packageFileUri Введите универсальный код ресурса (URI) для ZIP-файла пакета. packageuri Используйте значение переменной. Формат — https://yourStorageAccountName.blob.core.windows.net/appcontainer/app.zip.
principalId Идентификатор субъекта-издателя, которому требуются разрешения на управление ресурсами в управляемой группе ресурсов. principalid Используйте значение переменной.
roleId Идентификатор роли для разрешений для управляемой группы ресурсов. Например, владелец, участник, читатель. roleid Используйте значение переменной.

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

  • Azure PowerShell: в PowerShell введите $variableName значение переменной.
  • Azure CLI: в Bash введите echo $variableName значение переменной.

Развертывание определения

При развертывании определения управляемого приложения он становится доступным в каталоге служб. Этот процесс не развертывает ресурсы управляемого приложения.

Создайте группу ресурсов с именем byosAppDefinitionGroup и разверните определение управляемого приложения в учетной записи хранения.

New-AzResourceGroup -Name byosAppDefinitionGroup -Location westus3

New-AzResourceGroupDeployment `
  -ResourceGroupName byosAppDefinitionGroup `
  -TemplateFile deployDefinition.bicep `
  -TemplateParameterFile deployDefinition.parameters.json

Проверка хранилища файлов определений

Во время развертывания свойство шаблона storageAccountId использует идентификатор ресурса учетной записи хранения и создает контейнер с именем applicationdefinitions (с учетом регистра). Файлы из ZIP-файла пакета, указанного во время развертывания, хранятся в новом контейнере.

Чтобы убедиться, что файлы определения управляемого приложения хранятся в контейнере учетной записи хранения, можно использовать следующие команды. В команде замените заполнитель <definitionstorage> , включая угловые скобки (<>), на имя уникальной учетной записи хранения.

Get-AzStorageAccount -ResourceGroupName byosDefinitionStorageGroup -Name <definitionstorage> |
Get-AzStorageContainer -Name applicationdefinitions |
Get-AzStorageBlob | Select-Object -Property Name | Format-List

Примечание.

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

Убедитесь, что пользователи могут получить доступ к определению

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

Очистка ресурсов

Если вы собираетесь развернуть определение, перейдите к разделу "Дальнейшие действия ", который ссылается на статью для развертывания определения.

Если вы завершите работу с определением управляемого приложения, можно удалить созданные вами группы ресурсов с именем package служба хранилища Group, byosDefinition служба хранилища Group и byosAppDefinitionGroup.

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

Remove-AzResourceGroup -Name packageStorageGroup

Remove-AzResourceGroup -Name byosAppDefinitionGroup

Remove-AzResourceGroup -Name byosDefinitionStorageGroup

Следующие шаги

Вы опубликовали определение управляемого приложения. Теперь можно приступать к развертыванию экземпляра этого определения.