快速入门:创建并发布托管应用程序定义Quickstart: Create and publish a managed application definition

本快速入门简单介绍了如何使用 Azure 托管应用程序This quickstart provides an introduction to working with Azure Managed Applications. 你可以创建和发布适用于组织中成员的托管应用程序。You can create and publish a managed application that is intended for members of your organization.

若要将托管应用程序发布到服务目录,必须执行以下操作:To publish a managed application to your service catalog, you must:

  • 创建一个模板,定义要与托管应用程序一起部署的资源。Create a template that defines the resources to deploy with the managed application.
  • 部署托管应用程序时,请定义门户的用户界面元素。Define the user interface elements for the portal when deploying the managed application.
  • 创建包含必需模板文件的 .zip 包。Create a .zip package that contains the required template files.
  • 确定需要对客户订阅中的资源组具有访问权限的用户、组或应用程序。Decide which user, group, or application needs access to the resource group in the user's subscription.
  • 创建指向 .zip 包并请求标识访问权限的托管应用程序定义。Create the managed application definition that points to the .zip package and requests access for the identity.

创建 ARM 模板Create the ARM template

每个托管应用程序定义均包含一个名为 mainTemplate.json 的文件。Every managed application definition includes a file named mainTemplate.json. 可在其中定义要部署的 Azure 资源。In it, you define the Azure resources to deploy. 该模板与常规的 Azure 资源管理器 (ARM) 模板没有什么不同。The template is no different than a regular Azure Resource Manager (ARM) template.

创建一个名为 mainTemplate.json 的文件。Create a file named mainTemplate.json. 该名称区分大小写。The name is case-sensitive.

将以下 JSON 添加到该文件。Add the following JSON to your file. 它定义用于创建存储帐户的参数,并指定存储帐户的属性。It defines the parameters for creating a storage account, and specifies the properties for the storage account.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "storageAccountNamePrefix": {
            "type": "string"
        },
        "storageAccountType": {
            "type": "string"
        },
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]"
        }
    },
    "variables": {
        "storageAccountEndPoint": "https://core.chinacloudapi.cn/",
        "storageAccountName": "[concat(parameters('storageAccountNamePrefix'), uniqueString(resourceGroup().id))]"
    },
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2019-06-01",
            "name": "[variables('storageAccountName')]",
            "location": "[parameters('location')]",
            "sku": {
                "name": "[parameters('storageAccountType')]"
            },
            "kind": "StorageV2",
            "properties": {}
        }
    ],
    "outputs": {
        "storageEndpoint": {
            "type": "string",
            "value": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), '2019-06-01').primaryEndpoints.blob]"
        }
    }
}

保存 mainTemplate.json 文件。Save the mainTemplate.json file.

定义你的创建体验Define your create experience

作为发布者,你将定义用于创建托管应用程序的门户体验。As a publisher, you define the portal experience for creating the managed application. createUiDefinition.json 文件生成门户界面。The createUiDefinition.json file generates the portal interface. 使用控件元素(包括下拉框、文本框和密码框)来定义用户如何为每个参数提供输入。You define how users provide input for each parameter using control elements including drop-downs, text boxes, and password boxes.

创建一个名为 createUiDefinition.json 的文件(此名称区分大小写)Create a file named createUiDefinition.json (This name is case-sensitive)

将以下起始 JSON 添加到该文件并保存。Add the following starter JSON to the file and save it.

{
   "$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": "storageConfig",
                "label": "Storage settings",
                "subLabel": {
                    "preValidation": "Configure the infrastructure settings",
                    "postValidation": "Done"
                },
                "bladeTitle": "Storage settings",
                "elements": [
                    {
                        "name": "storageAccounts",
                        "type": "Microsoft.Storage.MultiStorageAccountCombo",
                        "label": {
                            "prefix": "Storage account name prefix",
                            "type": "Storage account type"
                        },
                        "defaultValue": {
                            "type": "Standard_LRS"
                        },
                        "constraints": {
                            "allowedTypes": [
                                "Premium_LRS",
                                "Standard_LRS",
                                "Standard_GRS"
                            ]
                        }
                    }
                ]
            }
        ],
        "outputs": {
            "storageAccountNamePrefix": "[steps('storageConfig').storageAccounts.prefix]",
            "storageAccountType": "[steps('storageConfig').storageAccounts.type]",
            "location": "[location()]"
        }
    }
}

若要了解详细信息,请参阅 CreateUiDefinition 入门To learn more, see Get started with CreateUiDefinition.

将文件打包Package the files

将这两个文件添加到名为 app.zip 的 .zip 文件。Add the two files to a .zip file named app.zip. 这两个文件必须都位于该 .zip 文件的根级别。The two files must be at the root level of the .zip file. 如果将它们放在文件夹中,则会在创建托管应用程序定义时收到错误,称所需文件不存在。If you put them in a folder, you receive an error when creating the managed application definition that states the required files aren't present.

将包上传到可从中使用程序包的一个可访问位置。Upload the package to an accessible location from where it can be consumed. 你需要为存储帐户提供一个唯一名称。You'll need to provide a unique name for the storage account.

New-AzResourceGroup -Name storageGroup -Location chinaeast

$storageAccount = New-AzStorageAccount `
  -ResourceGroupName storageGroup `
  -Name "mystorageaccount" `
  -Location chinaeast `
  -SkuName Standard_LRS `
  -Kind StorageV2

$ctx = $storageAccount.Context

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

Set-AzStorageBlobContent `
  -File "D:\myapplications\app.zip" `
  -Container appcontainer `
  -Blob "app.zip" `
  -Context $ctx 

创建托管应用程序定义Create the managed application definition

创建 Azure Active Directory 用户组或应用程序Create an Azure Active Directory user group or application

下一步是选择用于为客户管理资源的用户组、用户或应用程序。The next step is to select a user group, user, or application for managing the resources for the customer. 此标识对托管资源组的权限与所分配的角色相对应。This identity has permissions on the managed resource group according to the role that is assigned. 角色可以是任何基于角色的访问控制 (RBAC) 的内置角色,如 Owner 或 Contributor。The role can be any built-in Role-Based Access Control (RBAC) role like Owner or Contributor. 若要创建新的 Active Directory 用户组,请参阅在 Azure Active Directory 中创建组并添加成员To create a new Active Directory user group, see Create a group and add members in Azure Active Directory.

需要提供用户组的对象 ID 以用于管理资源。You need the object ID of the user group to use for managing the resources.

$groupID=(Get-AzADGroup -DisplayName mygroup).Id

获取角色定义 IDGet the role definition ID

接下来,需要获取希望将其访问权限授予用户、用户组或应用程序的 RBAC 内置角色的角色定义 ID。Next, you need the role definition ID of the RBAC built-in role you want to grant access to the user, user group, or application. 通常,你会使用“Owner”、“Contributor”或“Reader”角色。Typically, you use the Owner or Contributor or Reader role. 以下命令展示了如何获取“Owner”角色的角色定义 ID:The following command shows how to get the role definition ID for the Owner role:

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

创建托管应用程序定义Create the managed application definition

如果还没有用于存储托管应用程序定义的资源组,请立即创建一个:If you don't already have a resource group for storing your managed application definition, create one now:

New-AzResourceGroup -Name appDefinitionGroup -Location chinaeast

现在,创建托管应用程序定义资源。Now, create the managed application definition resource.

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

New-AzManagedApplicationDefinition `
  -Name "ManagedStorage" `
  -Location "chinaeast" `
  -ResourceGroupName appDefinitionGroup `
  -LockLevel ReadOnly `
  -DisplayName "Managed Storage Account" `
  -Description "Managed Azure Storage Account" `
  -Authorization "${groupID}:$ownerID" `
  -PackageFileUri $blob.ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri

命令完成后,资源组中会有一个托管应用程序定义。When the command completes, you have a managed application definition in your resource group.

前述示例中使用的部分参数包括:Some of the parameters used in the preceding example are:

  • 资源组:在其中创建托管应用程序定义的资源组的名称。resource group: The name of the resource group where the managed application definition is created.
  • 锁定级别:在托管资源组上放置的锁的类型。lock level: The type of lock placed on the managed resource group. 它防止客户对此资源组执行不良操作。It prevents the customer from performing undesirable operations on this resource group. 当前,ReadOnly 是唯一受支持的锁级别。Currently, ReadOnly is the only supported lock level. 当指定了 ReadOnly 时,客户只能读取托管资源组中存在的资源。When ReadOnly is specified, the customer can only read the resources present in the managed resource group. 授予对托管资源组的访问权限的发布者标识不受该锁控制。The publisher identities that are granted access to the managed resource group are exempt from the lock.
  • authorizations:描述用于授予对托管资源组权限的主体 ID 和角色定义 ID。authorizations: Describes the principal ID and the role definition ID that are used to grant permission to the managed resource group. 它是以 <principalId>:<roleDefinitionId> 格式指定的。It's specified in the format of <principalId>:<roleDefinitionId>. 如果需要多个值,请以 <principalId1>:<roleDefinitionId1>,<principalId2>:<roleDefinitionId2> 格式指定它们。If more than one value is needed, specify them in the form <principalId1>:<roleDefinitionId1>,<principalId2>:<roleDefinitionId2>. 请用逗号分隔这些值。The values are separated by a comma.
  • 包文件 URI:包含所需文件的 .zip 包的位置。package file URI: The location of a .zip package that contains the required files.

自带符合托管应用程序定义的存储Bring your own storage for the managed application definition

可以选择将托管应用程序定义存储在创建过程中提供的存储帐户中,以便根据自己的法规需求对其位置和访问权限进行完全管理。You can choose to store your managed application definition within a storage account provided by you during creation so that its location and access can be fully managed by you for your regulatory needs.

备注

仅在 ARM 模板或托管应用程序定义的 REST API 部署中支持自带存储。Bring your own storage is only supported with ARM Template or REST API deployments of the managed application definition.

选择存储帐户Select your storage account

必须创建存储帐户才能包含可与服务目录配合使用的托管应用程序定义。You must create a storage account to contain your managed application definition for use with Service Catalog.

复制存储帐户的资源 ID。Copy the storage account's resource ID. 稍后在部署定义时将使用它。It will be used later when deploying the definition.

在存储帐户中设置“设备资源提供程序”的角色分配Set the role assignment for "Appliance Resource Provider" in your storage account

在将托管的应用程序定义部署到存储帐户之前,你必须为“设备资源提供程序” 角色授予参与者权限,以便它可以将定义文件写入存储帐户的容器中。Before your managed application definition can be deployed to your storage account, you must give contributor permissions to the Appliance Resource Provider role so that it can write the definition files to your storage account's container.

  1. Azure 门户中导航到存储帐户。In the Azure portal, navigate to your storage account.
  2. 选择“访问控制(标识和访问管理)”以显示存储帐户的访问控制设置 。Select Access control (IAM) to display the access control settings for the storage account. 选择“角色分配” 选项卡以查看角色分配列表。Select the Role assignments tab to see the list of role assignments.
  3. 在“添加角色分配”窗口中,选择“参与者”角色 。In the Add role assignment window, select the Contributor role.
  4. 在“分配访问权限至” 字段中,选择“Azure AD 用户、组或服务主体” 。From the Assign access to field, select Azure AD user, group, or service principal.
  5. 在“选择”下,搜索“设备资源提供程序”角色,然后将其选中。 Under Select, search for Appliance Resource Provider role and select it.
  6. 保存角色分配。Save the role assignment.

使用 ARM 模板部署托管应用程序定义Deploy the managed application definition with an ARM Template

使用以下 ARM 模板将打包的托管应用程序部署为服务目录中的新托管应用程序定义,其定义文件在你自己的存储帐户中进行存储和维护:Use the following ARM Template to deploy your packaged managed application as a new managed application definition in Service Catalog whose definition files are stored and maintained in your own storage account:

    {
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]"
        },
        "applicationName": {
            "type": "string",
            "metadata": {
                "description": "Managed Application name"
            }
        },
        "storageAccountType": {
      "type": "string",
      "defaultValue": "Standard_LRS",
      "allowedValues": [
        "Standard_LRS",
        "Standard_GRS",
        "Premium_LRS"
      ],
      "metadata": {
        "description": "Storage Account type"
      }
    },
        "definitionStorageResourceID": {
            "type": "string",
            "metadata": {
                "description": "Storage account resource ID for where you're storing your definition"
            }
        },
        "_artifactsLocation": {
            "type": "string",
            "metadata": {
                "description": "The base URI where artifacts required by this template are located."
            }
        }
    },
    "variables": {
        "lockLevel": "None",
        "description": "Sample Managed application definition",
        "displayName": "Sample Managed application definition",
        "managedApplicationDefinitionName": "[parameters('applicationName')]",
        "packageFileUri": "[parameters('_artifactsLocation')]",
        "defLocation": "[parameters('definitionStorageResourceID')]",
        "managedResourceGroupId": "[concat(subscription().id,'/resourceGroups/', concat(parameters('applicationName'),'_managed'))]",
        "applicationDefinitionResourceId": "[resourceId('Microsoft.Solutions/applicationDefinitions',variables('managedApplicationDefinitionName'))]"
    },
    "resources": [
        {
            "type": "Microsoft.Solutions/applicationDefinitions",
            "apiVersion": "2019-07-01",
            "name": "[variables('managedApplicationDefinitionName')]",
            "location": "[parameters('location')]",
            "properties": {
                "lockLevel": "[variables('lockLevel')]",
                "description": "[variables('description')]",
                "displayName": "[variables('displayName')]",
                "packageFileUri": "[variables('packageFileUri')]",
                "storageAccountId": "[variables('defLocation')]"
            }
        }
    ],
    "outputs": {}
}

我们已将名为 storageAccountId 的新属性添加到 applicationDefintion 的属性中,并提了供要在其中存储定义的存储帐户 ID 作为其值:We have added a new property named storageAccountId to your applicationDefintion's properties and provide storage account ID you wish to store your definition in as its value:

可以验证是否已将应用程序定义文件保存在标题为 applicationdefinitions 的容器的已提供的存储帐户中。You can verify that the application definition files are saved in your provided storage account in a container titled applicationdefinitions.

备注

为了增加安全性,可以创建一个托管应用程序定义,并将其存储在启用了加密的 Azure 存储帐户 Blob 中。For added security, you can create a managed applications definition store it in an Azure storage account blob where encryption is enabled. 通过存储帐户的加密选项来加密定义内容。The definition contents are encrypted through the storage account's encryption options. 只有有权访问文件的用户才能查看服务目录中的定义。Only users with permissions to the file can see the definition in Service Catalog.

请确保用户可以看到你的定义Make sure users can see your definition

你可以访问托管应用程序定义,但你希望确保组织中的其他用户可以访问它。You have access to the managed application definition, but you want to make sure other users in your organization can access it. 至少授予他们对定义的读者角色。Grant them at least the Reader role on the definition. 他们可能已从订阅或资源组继承了此级别的访问权限。They may have inherited this level of access from the subscription or resource group. 若要查看谁可以访问定义并添加用户或组,请参阅使用基于角色的访问控制来管理对 Azure 订阅资源的访问权限To check who has access to the definition and add users or groups, see Use Role-Based Access Control to manage access to your Azure subscription resources.

后续步骤Next steps

已发布托管应用程序定义。You've published the managed application definition. 现在,了解如何部署该定义的实例。Now, learn how to deploy an instance of that definition.