Publish a managed application for internal consumption

You can create and publish Azure managed applications that are intended for members of your organization. For example, an IT department can publish managed applications that ensure compliance with organizational standards. These managed applications are available through the service catalog, not the Azure marketplace.

To publish a managed application for the 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.
  • 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.
  • Create the managed application definition that points to the .zip package and requests access for the identity.

For this article, your managed application contains only a storage account. It is intended to illustrate the steps of publishing a managed application. For complete examples, see Sample projects for Azure managed applications.

Create the resource template

Every managed application definition contains a file named mainTemplate.json. In it, you define the Azure resources to provision. The template is no different than a regular Resource Manager template.

Create a file named mainTemplate.json. The name is case-sensitive.

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": "",
    "contentVersion": "",
    "parameters": {
        "storageAccountNamePrefix": {
            "type": "string"
        "storageAccountType": {
            "type": "string"
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]"
    "variables": {
        "storageAccountName": "[concat(parameters('storageAccountNamePrefix'), uniqueString('storage'))]"
    "resources": [
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageAccountName')]",
            "apiVersion": "2016-01-01",
            "location": "[parameters('location')]",
            "sku": {
                "name": "[parameters('storageAccountType')]"
            "kind": "Storage",
            "properties": {}
    "outputs": {
        "storageEndpoint": {
            "type": "string",
            "value": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), '2016-01-01').primaryEndpoints.blob]"

Save the mainTemplate.json file.

Create the user interface definition

The Azure portal uses the createUiDefinition.json file to generate the user interface for users who create the managed application. You define how users provide input for each parameter. You can use options like a drop-down list, text box, password box, and other input tools. To learn how to create a UI definition file for a managed application, see Get started with CreateUiDefinition.

Create a file named createUiDefinition.json. The name is case-sensitive.

Add the following JSON to the file.

    "$schema": "",
    "handler": "Microsoft.Compute.MultiVm",
    "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": [
        "outputs": {
            "storageAccountNamePrefix": "[steps('storageConfig').storageAccounts.prefix]",
            "storageAccountType": "[steps('storageConfig').storageAccounts.type]",
            "location": "[location()]"

Save the createUIDefinition.json file.

Package the files

Add the two files to a .zip file named 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 are not present.

Upload the package to an accessible location from where it can be consumed.

New-AzureRmResourceGroup -Name storageGroup -Location eastus
$storageAccount = New-AzureRmStorageAccount -ResourceGroupName storageGroup `
  -Name "mystorageaccount" `
  -Location eastus `
  -SkuName Standard_LRS `
  -Kind Storage `
  -EnableEncryptionService Blob

$ctx = $storageAccount.Context

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

Set-AzureStorageBlobContent -File "D:\myapplications\" `
  -Container appcontainer `
  -Blob "" `
  -Context $ctx 

Create the managed application definition

Create an Azure Active Directory user group or application

The next step is to select a user group or application for managing the resources on behalf of the customer. This user group or application has permissions on the managed resource group according to the role that is assigned. The role can be any built-in Role-Based Access Control (RBAC) role like Owner or Contributor. You also can give an individual user permission to manage the resources, but typically you assign this permission to a user group. To create a new Active Directory user group, see Create a group and add members in Azure Active Directory.

You need the object ID of the user group to use for managing the resources.

Get group ID

Get the role definition 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. Typically, you use the Owner or Contributor or Reader role. The following command shows how to get the role definition ID for the Owner role:

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

Create the managed application definition

If you do not already have a resource group for storing your managed application definition, create one now:

New-AzureRmResourceGroup -Name appDefinitionGroup -Location westcentralus

Now, create the managed application definition resource.

$blob = Get-AzureStorageBlob -Container appcontainer -Blob -Context $ctx

New-AzureRmManagedApplicationDefinition `
  -Name "ManagedStorage" `
  -Location "westcentralus" `
  -ResourceGroupName appDefinitionGroup `
  -LockLevel ReadOnly `
  -DisplayName "Managed Storage Account" `
  -Description "Managed Azure Storage Account" `
  -Authorization "<group-id>:$ownerID" `
  -PackageFileUri $blob.ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri

Create the managed application by using the portal

Now, let's use the portal to deploy the managed application. You see the user interface you created in the package.

  1. Go to the Azure portal. Select + New and search for service catalog.

    Search service catalog

  2. Select Service Catalog Managed Application.

    Select service catalog

  3. Select Create.

    Select create

  4. Find the managed application you want to create from the list of available solutions, and select it. Select Create.

    Find the managed application

  5. Provide basic information that is required for the managed application. Specify the subscription and a new resource group to contain the managed application. Select West Central US for location. When done, select OK.

    Provide managed application parameters

  6. Provide values that are specific to the resources in the managed application. When done, select OK.

    Provide resource parameters

  7. The template validates the values you provided. If validation succeeds, select OK to start the deployment.

    Validate managed application

After the deployment finishes, the managed application exists in a resource group named applicationGroup. The storage account exists in a resource group named applicationGroup plus a hashed string value.

Next steps