你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

快速入门:创建和发布 Azure 托管应用程序定义

本快速入门简单介绍了如何使用 Azure 托管应用程序。 创建并发布托管应用程序定义,它存储在服务目录中并面向组织的成员。

要将托管应用程序发布到服务目录,请执行以下任务:

  • 创建一个 Azure 资源管理器模板(ARM 模板),用于定义使用托管应用程序部署的资源。
  • 部署托管应用程序时,请定义门户的用户界面元素。
  • 创建包含必需 JSON 文件的 .zip 包。 该 .zip 包文件对于服务目录的托管应用程序定义具有 120 MB 的限制。
  • 发布托管应用程序定义,使其在服务目录中可用。

如果你的托管应用程序定义超过 120 MB,或者出于组织的合规性原因你想要使用自己的存储帐户,请转到快速入门:使用自己的存储来创建和发布 Azure 托管应用程序定义

可以使用 Bicep 开发托管应用程序定义,但必须先将其转换为 ARM 模板 JSON,然后才能在 Azure 中发布定义。 有关详细信息,请转到快速入门:使用 Bicep 创建和发布 Azure 托管应用程序定义

还可以使用 Bicep 从服务目录部署托管应用程序定义。 有关详细信息,请转到快速入门:使用 Bicep 部署 Azure 托管应用程序定义

先决条件

若要完成本快速入门,需要准备好以下各项:

创建 ARM 模板

每个托管应用程序定义均包含一个名为 mainTemplate.json 的文件。 该模板定义了要部署的 Azure 资源,与常规 ARM 模板没有什么不同。

打开 Visual Studio Code,创建一个名称区分大小写的文件 mainTemplate.json 并保存它。

添加以下 JSON 并保存文件。 它定义用于部署应用服务和应用服务计划的资源。 该模板使用具有即用即付成本的应用服务基本计划 (B1)。 有关详细信息,请参阅 Linux 上的 Azure 应用服务定价

{
  "$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."
      }
    }
  },
  "variables": {
    "appServicePlanSku": "B1",
    "appServicePlanCapacity": 1,
    "appServiceName": "[format('{0}{1}', parameters('appServiceNamePrefix'), uniqueString(resourceGroup().id))]",
    "linuxFxVersion": "DOTNETCORE|8.0"
  },
  "resources": [
    {
      "type": "Microsoft.Web/serverfarms",
      "apiVersion": "2023-01-01",
      "name": "[parameters('appServicePlanName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[variables('appServicePlanSku')]",
        "capacity": "[variables('appServicePlanCapacity')]"
      },
      "kind": "linux",
      "properties": {
        "zoneRedundant": false,
        "reserved": true
      }
    },
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2023-01-01",
      "name": "[variables('appServiceName')]",
      "location": "[parameters('location')]",
      "properties": {
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]",
        "httpsOnly": true,
        "redundancyMode": "None",
        "siteConfig": {
          "linuxFxVersion": "[variables('linuxFxVersion')]",
          "minTlsVersion": "1.2",
          "ftpsState": "Disabled"
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]"
      ]
    }
  ],
  "outputs": {
    "appServicePlan": {
      "type": "string",
      "value": "[parameters('appServicePlanName')]"
    },
    "appServiceApp": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.Web/sites', variables('appServiceName')), '2023-01-01').defaultHostName]"
    }
  }
}

定义门户体验

作为发布者,你需要定义创建托管应用程序的门户体验。 createUiDefinition.json 文件生成门户的用户界面。 使用控件元素(如下拉框和文本框)来定义用户如何为每个参数提供输入。

在此例中,用户界面会提示你输入应用服务名称前缀和应用服务计划的名称。 在部署 mainTemplate.json 期间,appServiceName 变量使用 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
          }
        ]
      }
    ],
    "outputs": {
      "location": "[location()]",
      "appServicePlanName": "[steps('webAppSettings').appServicePlanName]",
      "appServiceNamePrefix": "[steps('webAppSettings').appServiceName]"
    }
  }
}

若要了解详细信息,请参阅 CreateUiDefinition 入门

将文件打包

将这两个文件添加到名为 app.zip 的包文件中。 这两个文件必须都位于该 .zip 文件的根级别。 如果文件位于文件夹中,则当你创建托管应用程序定义时,你会收到一条错误消息,指出所需文件不存在。

app.zip 上传到 Azure 存储帐户,以便在部署托管应用程序的定义时使用它。 存储帐户名称在 Azure 中必须是全局唯一的,长度必须为 3-24 个字符,仅包含小写字母和数字。 在命令中,将占位符<pkgstorageaccountname> (包括尖括号 (<>)) 替换为唯一的存储帐户名称。

在 Visual Studio Code 中,打开新的 PowerShell 终端并登录到 Azure 订阅。

Connect-AzAccount

此命令会打开默认浏览器,并提示登录到 Azure。 有关详细信息,请转到使用 Azure PowerShell 登录

New-AzResourceGroup -Name packageStorageGroup -Location westus

$pkgstorageparms = @{
  ResourceGroupName = "packageStorageGroup"
  Name = "<pkgstorageaccountname>"
  Location = "westus"
  SkuName = "Standard_LRS"
  Kind = "StorageV2"
  MinimumTlsVersion = "TLS1_2"
  AllowBlobPublicAccess = $true
  AllowSharedKeyAccess = $false
}

$pkgstorageaccount = New-AzStorageAccount @pkgstorageparms

$pkgstorageparms 变量使用 PowerShell splatting 来提高用于创建新存储帐户的命令中使用的参数值的可读性。 Splatting 可用于使用多个参数值的其他 PowerShell 命令。

创建存储帐户后,将角色分配存储 Blob 数据参与者添加到存储帐户范围中。 分配对 Microsoft Entra 用户帐户的访问权限。 根据 Azure 中的访问级别,你可能需要管理员分配的其他权限。 有关详细信息,请参阅分配用于访问 blob 数据的 Azure 角色使用 Azure 门户分配 Azure 角色

向存储帐户添加角色后,需要几分钟才能在 Azure 中激活。 然后,可以创建创建容器和上传文件所需的上下文。

$pkgstoragecontext = New-AzStorageContext -StorageAccountName $pkgstorageaccount.StorageAccountName -UseConnectedAccount

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

$blobparms = @{
  File = "app.zip"
  Container = "appcontainer"
  Blob = "app.zip"
  Context = $pkgstoragecontext
}

Set-AzStorageBlobContent @blobparms

创建托管应用程序定义

在本部分中,你将从 Microsoft Entra ID 获取标识信息、创建资源组并部署托管应用程序定义。

获取组 ID 和角色定义 ID

下一步是选择用于为客户管理资源的用户、安全组或应用程序。 此标识对受管理资源组的权限与所分配的角色相对应。 角色可以是任何 Azure 内置角色,例如所有者或参与者。

此示例使用安全组,并且 Microsoft Entra 帐户应是组的成员。 若要获取组的对象 ID,请将占位符<managedAppDemo> ((包括尖括号 (<>)) 替换为组的名称。 你将在部署托管应用程序定义时使用此变量的值。

若要创建新的 Microsoft Entra 组,请转到管理 Microsoft Entra 组和组成员身份

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

接下来,获取希望将其访问权限授予用户、组或应用程序的 Azure 内置角色的角色定义 ID。 你将在部署托管应用程序定义时使用此变量的值。

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

发布托管应用程序定义

为托管应用程序定义创建资源组。

New-AzResourceGroup -Name appDefinitionGroup -Location westus

blob 命令将创建一个变量来存储包 .zip 文件的 URL。 该变量用于创建托管应用程序定义的命令。

$blob = Get-AzStorageBlob -Container appcontainer -Blob app.zip -Context $pkgstoragecontext

$publishparms = @{
  Name = "sampleManagedApplication"
  Location = "westus"
  ResourceGroupName = "appDefinitionGroup"
  LockLevel = "ReadOnly"
  DisplayName = "Sample managed application"
  Description = "Sample managed application that deploys web resources"
  Authorization = "${principalid}:$roleid"
  PackageFileUri = $blob.ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri
}

New-AzManagedApplicationDefinition @publishparms

命令完成后,资源组中会有一个托管应用程序定义。

前述示例中使用的部分参数包括:

  • ResourceGroupName:在其中创建托管应用程序定义的资源组的名称。
  • LockLevel:受管理资源组上的 lockLevel 可防止客户对此资源组执行不良操作。 目前,ReadOnly 是唯一受支持的锁定级别。 ReadOnly 指定客户只能读取受管理资源组中存在的资源。 授予对受管理资源组的访问权限的发布者标识不受该锁定级别控制。
  • Authorization:描述用于授予对托管资源组权限的主体 ID 和角色定义 ID。
    • "${principalid}:$roleid" 或者可以为每个变量 "${principalid}:${roleid}" 使用大括号。
    • 使用逗号分隔多个值:"${principalid1}:$roleid1", "${principalid2}:$roleid2"
  • PackageFileUri:包含所需文件的 .zip 包文件的位置。

请确保用户可以看到你的定义

你可以访问托管应用程序定义,但你希望确保组织中的其他用户可以访问它。 至少授予他们对定义的读者角色。 他们可能已从订阅或资源组继承了此级别的访问权限。 若要检查谁有权访问定义并添加用户或组,请参阅使用 Azure 门户分配 Azure 角色

清理资源

如果要部署定义,请继续阅读链接到该文章的“后续步骤”部分来部署定义。

如果已完成托管应用程序定义,则可以删除创建的名为 packageStorageGroupappDefinitionGroup 的资源组。

命令会提示你确认删除资源组。

Remove-AzResourceGroup -Name packageStorageGroup

Remove-AzResourceGroup -Name appDefinitionGroup

后续步骤

已发布托管应用程序定义。 下一步是了解如何部署该定义的实例。