Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
此快速入门介绍如何使用 Bicep 以在服务目录中创建和发布 Azure 托管应用程序定义。 你的服务目录中的定义可供组织成员使用。
若要创建托管应用程序定义并将其发布到服务目录,请执行以下任务:
- 使用 Bicep 开发模板,并将其转换为 Azure 资源管理器模板(ARM 模板)。 该模板定义托管应用程序部署的 Azure 资源。
- 使用 Bicep
build
命令将 Bicep 转换为 JSON。 将文件转换为 JSON 后,请验证代码的准确性。 - 部署托管应用程序时,请定义门户的用户界面元素。
- 创建包含必需 JSON 文件的 .zip 包。 该 .zip 包文件对于服务目录的托管应用程序定义具有 120 MB 的限制。
- 发布托管应用程序定义,使其在服务目录中可用。
如果你的托管应用程序定义超过 120 MB,或者出于组织的合规性原因你想要使用自己的存储帐户,请转到快速入门:使用自己的存储来创建和发布 Azure 托管应用程序定义。
还可以使用 Bicep 从服务目录部署托管应用程序定义。 有关详细信息,请转到快速入门:使用 Bicep 部署 Azure 托管应用程序定义。
若要完成本文中的任务,需要准备好以下项:
- 具有活动订阅且有权访问 Microsoft Entra 资源(如用户、组或服务主体)的 Azure 帐户。 如果没有帐户,请在开始之前创建一个试用版帐户。
- 包含最新 Azure 资源管理器工具扩展的 Visual Studio Code。 对于 Bicep 文件,请安装适用于 Visual Studio Code 的 Bicep 扩展。
- 安装最新版本的 Azure PowerShell 或 Azure CLI。
每个托管应用程序定义均包含一个名为 mainTemplate.json 的文件。 该模板定义了要部署的 Azure 资源,与常规 ARM 模板没有什么不同。 可以使用 Bicep 开发模板,然后将 Bicep 文件转换为 JSON。
打开 Visual Studio Code,创建一个名称区分大小写的文件 mainTemplate.bicep 并保存它。
添加以下 Bicep 代码并保存文件。 它定义用于部署应用程序服务、应用服务计划和存储帐户的托管应用程序资源。
param location string = resourceGroup().location
@description('App Service plan name.')
@maxLength(40)
param appServicePlanName string
@description('App Service name prefix.')
@maxLength(47)
param appServiceNamePrefix string
var appServicePlanSku = 'B1'
var appServicePlanCapacity = 1
var appServiceName = '${appServiceNamePrefix}${uniqueString(resourceGroup().id)}'
var linuxFxVersion = 'DOTNETCORE|8.0'
resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
name: appServicePlanName
location: location
sku: {
name: appServicePlanSku
capacity: appServicePlanCapacity
}
kind: 'linux'
properties: {
zoneRedundant: false
reserved: true
}
}
resource appService 'Microsoft.Web/sites@2023-01-01' = {
name: appServiceName
location: location
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
redundancyMode: 'None'
siteConfig: {
linuxFxVersion: linuxFxVersion
minTlsVersion: '1.2'
ftpsState: 'Disabled'
}
}
}
output appServicePlan string = appServicePlanName
output appServiceApp string = appService.properties.defaultHostName
使用 PowerShell 或 Azure CLI 生成 mainTemplate.json 文件。 转到用于保存 Bicep 文件的目录,然后运行 build
命令。
bicep build mainTemplate.bicep
若要了解详细信息,请转到 Bicep 生成。
将 Bicep 文件转换为 JSON 后,mainTemplate.json 文件应与以下示例一致。 但 metadata
属性中的 version
和 templateHash
值可能不同。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.30.3.12046",
"templateHash": "16466621031230437685"
}
},
"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 -Environment AzureChinaCloud
此命令会打开默认浏览器,并提示登录到 Azure。 有关详细信息,请转到使用 Azure PowerShell 登录。
连接后,运行以下命令。
New-AzResourceGroup -Name packageStorageGroup -Location chinanorth3
$pkgstorageparms = @{
ResourceGroupName = "packageStorageGroup"
Name = "<pkgstorageaccountname>"
Location = "chinanorth3"
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 中激活。 然后,可以创建创建容器和上传文件所需的上下文。
$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
使用以下命令将包文件的 URI 存储在名为 packageuri
的变量中。 将在部署托管应用程序定义时使用该变量的值。
$packageuri=(Get-AzStorageBlob -Container appcontainer -Blob app.zip -Context $pkgstoragecontext).ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri
在本部分中,你将从 Microsoft Entra ID 获取标识信息、创建资源组并部署托管应用程序定义。
下一步是选择用于为客户管理资源的用户、安全组或应用程序。 此标识对受管理资源组的权限与所分配的角色相对应。 角色可以是任何 Azure 内置角色,例如所有者或参与者。
此示例使用安全组,并且 Microsoft Entra 帐户应是组的成员。 若要获取组的对象 ID,请将占位符<managedAppDemo>
((包括尖括号 (<>
)) 替换为组的名称。 将在部署托管应用程序定义时使用该变量的值。
若要创建新的 Microsoft Entra 组,请转到管理 Microsoft Entra 组和组成员身份。
$principalid=(Get-AzADGroup -DisplayName <managedAppDemo>).Id
接下来,获取希望将其访问权限授予用户、组或应用程序的 Azure 内置角色的角色定义 ID。 将在部署托管应用程序定义时使用该变量的值。
$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('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 Bicep managed application'
var definitionDescription = 'Sample Bicep 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
authorizations: [
{
principalId: principalId
roleDefinitionId: roleId
}
]
}
}
有关模板属性的详细信息,请转到 Microsoft.Solutions/applicationDefinitions。
受管理资源组上的 lockLevel
可防止客户对此资源组执行不良操作。 目前,ReadOnly
是唯一受支持的锁定级别。 ReadOnly
指定客户只能读取受管理资源组中存在的资源。 授予对受管理资源组的访问权限的发布者标识不受该锁定级别控制。
托管应用程序定义的部署模板需要用户输入多个参数。 部署命令会提示输入值,你也可以为值创建参数文件。 在此示例中,我们使用参数文件将参数值传递给部署命令。
在 Visual Studio Code 中,创建名为 deployDefinition-parameters.bicepparam 的新文件并保存它。
将以下内容添加到参数文件并保存它。 然后,将 <placeholder values>
(包括大括号(<>
)) 替换为你的值。
using './deployDefinition.bicep'
param managedApplicationDefinitionName = 'sampleBicepManagedApplication'
param packageFileUri = '<placeholder for the packageFileUri>'
param principalId = '<placeholder for principalid value>'
param roleId = '<placeholder for roleid value>'
下表描述了托管应用程序定义的参数值。
参数 | 值 |
---|---|
managedApplicationDefinitionName |
托管应用程序定义的名称。 对于此例,请使用 sampleBicepManagedApplication。 |
packageFileUri |
输入 .zip 包文件的 URI。 使用 packageuri 变量的值。 |
principalId |
需要权限来管理受管理资源组中的资源的发布者主体 ID。 使用 principalid 变量的值。 |
roleId |
对受管理资源组具有访问权限的角色 ID。 例如“所有者”、“参与者”、“读者”。 使用 roleid 变量的值。 |
若要获取变量值,请执行以下操作:
- Azure PowerShell:在 PowerShell 中,输入
$variableName
以显示变量的值。 - Azure CLI:在 Bash 中,输入
echo $variableName
以显示变量的值。
部署托管应用程序的定义时,它将在服务目录中可用。 此过程不会部署托管应用程序的资源。
创建一个名为 bicepDefinitionGroup 的资源组并部署托管应用程序定义。
New-AzResourceGroup -Name bicepDefinitionGroup -Location chinanorth3
$deployparms = @{
ResourceGroupName = "bicepDefinitionGroup"
TemplateFile = "deployDefinition.bicep"
TemplateParameterFile = "deployDefinition-parameters.bicepparam"
Name = "deployDefinition"
}
New-AzResourceGroupDeployment @deployparms
运行以下命令,验证定义是否在服务目录中发布。
Get-AzManagedApplicationDefinition -ResourceGroupName bicepDefinitionGroup
Get-AzManagedApplicationDefinition
列出了指定资源组中的所有可用定义,例如 sampleBicepManagedApplication。
你可以访问托管应用程序定义,但你希望确保组织中的其他用户可以访问它。 至少授予他们对定义的读者角色。 他们可能已从订阅或资源组继承了此级别的访问权限。 若要检查谁有权访问定义并添加用户或组,请转到使用 Azure 门户分配 Azure 角色。
如果要部署定义,请继续阅读链接到使用 Bicep 部署定义的文章的后续步骤部分。
如果已完成托管应用程序定义,则可以删除创建的名为 packageStorageGroup 和 bicepDefinitionGroup 的资源组。
命令会提示你确认删除资源组。
Remove-AzResourceGroup -Name packageStorageGroup
Remove-AzResourceGroup -Name bicepDefinitionGroup
已发布托管应用程序定义。 下一步是了解如何部署该定义的实例。