Início Rápido: Criar e publicar a definição de um aplicativo gerenciado do Azure

Este guia de início rápido fornece uma introdução para trabalhar com Aplicativos Gerenciados do Azure. Você cria e publica uma definição de aplicativo gerenciado que é armazenada em seu catálogo de serviços e destina-se a membros da sua organização.

Para publicar um aplicativo gerenciado no catálogo de serviços, execute as seguintes tarefas:

  • Crie um modelo do ARM (Azure Resource Manager) que defina os recursos a serem implantados com o aplicativo gerenciado.
  • Defina os elementos da interface do usuário para o portal ao implantar o aplicativo gerenciado.
  • Crie um pacote .zip que contenha os arquivos JSON necessários. O arquivo do pacote .zip tem um limite de 120 MB para uma definição de aplicativo gerenciado do catálogo de serviços.
  • Publique a definição de aplicativo gerenciado para que ela esteja disponível no catálogo de serviços.

Se a definição do aplicativo gerenciado for superior a 120 MB ou se você quiser usar sua própria conta de armazenamento por motivos de conformidade da sua organização, acesse Início Rápido: Traga seu próprio armazenamento para criar e publicar uma definição de Aplicativo Gerenciado do Azure.

Você pode usar o Bicep para desenvolver uma definição de aplicativo gerenciado, mas ela deve ser convertida em um modelo do ARM JSON antes de publicar a definição no Azure. Para obter mais informações, vá para Início Rápido: usar o Bicep para criar e publicar uma definição de Aplicativo Gerenciado do Azure.

Você também pode usar o Bicep para implantar uma definição de aplicativo gerenciado do catálogo de serviços. Para obter mais informações, vá para Início Rápido: Usar o Bicep para implantar uma definição de Aplicativo Gerenciado do Azure.

Pré-requisitos

Para concluir este início rápido, você precisará dos seguintes itens:

Criar um modelo do ARM

Cada definição de aplicativo gerenciado contém um arquivo chamado mainTemplate.json. O modelo define os recursos do Azure a serem implantados e não é diferente de um modelo normal do ARM.

Abra o Visual Studio Code, crie um arquivo com o nome mainTemplate.json diferenciando maiúsculas de minúsculas e salve-o.

Adicione o JSON a seguir e salve o arquivo. Ele define os recursos para implantar um Serviço de Aplicativo, um plano de Serviço de Aplicativo e uma conta de armazenamento para o aplicativo. Essa conta de armazenamento não é usada para armazenar a definição de aplicativo gerenciado.

{
  "$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]"
    }
  }
}

Definir a sua experiência do portal

Como publicador, você define a experiência do portal para criar o aplicativo gerenciado. O arquivo createUiDefinition.json gera a interface do usuário do portal. Você define como os usuários fornecem a entrada para cada parâmetro usando elementos de controle, incluindo menus suspensos e caixas de texto.

Nesse exemplo, a interface do usuário solicita que você insira o prefixo do nome do Serviço de Aplicativo, o nome do plano do Serviço de Aplicativo, o prefixo da conta de armazenamento e o tipo de conta de armazenamento. Durante a implantação, as variáveis em mainTemplate.json usam a uniqueString função para acrescentar uma cadeia de caracteres de 13 caracteres aos prefixos de nome para que os nomes sejam globalmente exclusivos no Azure.

Abra o Visual Studio Code, crie um arquivo com o nome createUiDefinition.json diferenciando maiúsculas de minúsculas e salve-o.

Adicione o código JSON a seguir ao arquivo e salve-o.

{
  "$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]"
    }
  }
}

Para saber mais, consulte Introdução a CreateUiDefinition.

Empacote os arquivos

Adicione os dois arquivos a um arquivo de pacote chamado app.zip. Os dois arquivos precisam estar no nível raiz do arquivo .zip. Se você colocar os arquivos em uma pasta, receberá um erro indicando que os arquivos necessários não estão presentes ao criar a definição de aplicativo gerenciado.

Carregue o arquivo app.zip em uma conta de armazenamento do Azure para que você possa usá-la ao implantar a definição do aplicativo gerenciado. O nome da conta de armazenamento deve ser globalmente exclusivo no Azure e o comprimento deve ser de 3 a 24 caracteres com apenas letras minúsculas e números. No comando, substitua o espaço reservado <demostorageaccount>, incluindo os colchetes angulares (<>), pelo nome exclusivo da conta de armazenamento.

No Visual Studio Code, abra um novo terminal do PowerShell e entre em sua assinatura do Azure.

Connect-AzAccount

O comando abre o navegador padrão e solicita que você entre no Azure. Para obter mais informações, vá para Entrar com o Azure PowerShell.

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

Criar a definição de aplicativo gerenciado

Nesta seção, você obtém informações de identidade do Microsoft Entra ID, cria um grupo de recursos e implanta a definição de aplicativo gerenciado.

Obter ID do grupo e ID de definição de função

A próxima etapa é selecionar um grupo de segurança, um usuário ou um aplicativo para gerenciar os recursos para o cliente. Essa identidade tem permissões no grupo de recursos gerenciados de acordo com a função atribuída. A função pode ser qualquer função interna do Azure, como Proprietário ou Colaborador.

Este exemplo usa um grupo de segurança e sua conta do Microsoft Entra deverá ser um membro do grupo. Para obter a ID do objeto do grupo, substitua o espaço reservado <managedAppDemo> incluindo os colchetes angulares (<>) pelo nome do grupo. Você usará o valor dessa variável ao implantar a definição de aplicativo gerenciado.

Para criar um novo grupo do Microsoft Entra, acesse Gerenciar grupos do Microsoft Entra e associação de grupos.

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

Em seguida, obtenha a ID de definição de função da função interna do Azure que deseja para conceder acesso ao usuário, grupo ou aplicativo. Você usará o valor dessa variável ao implantar a definição de aplicativo gerenciado.

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

Publicar a definição de aplicativo gerenciado

Crie um grupo de recursos para sua definição de aplicativo gerenciado.

New-AzResourceGroup -Name appDefinitionGroup -Location westus3

O comando blob cria uma variável para armazenar a URL do arquivo .zip do pacote. Essa variável é usada no comando que cria a definição do aplicativo gerenciado.

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

New-AzManagedApplicationDefinition `
  -Name "sampleManagedApplication" `
  -Location "westus3" `
  -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

Quando o comando for concluído, você tem uma definição de aplicativo gerenciado no seu grupo de recursos.

Alguns dos parâmetros usados no exemplo anterior são:

  • ResourceGroupName: O nome do grupo de recursos no qual a definição de aplicativo gerenciado é criada.
  • LockLevel: O lockLevel no grupo de recursos gerenciados impede que o cliente execute operações indesejáveis nesse grupo de recursos. Atualmente, ReadOnly é o único nível de bloqueio com suporte. ReadOnly especifica que o cliente pode ler somente os recursos presentes no grupo de recursos gerenciados. As identidades do publicador que concedem acesso ao grupo de recursos gerenciado são isentas do nível de bloqueio.
  • Authorization: descreve a ID da entidade e a ID de definição de função que são usadas para conceder permissão ao grupo de recursos gerenciados.
    • "${principalid}:$roleid" também é possível usar chaves para cada variável "${principalid}:${roleid}".
    • Use uma vírgula para separar valores: "${principalid1}:$roleid1", "${principalid2}:$roleid2".
  • PackageFileUri: o local de um arquivo do pacote .zip que contém os arquivos necessários.

Verifique se os usuários podem ver sua definição

Você tem acesso à definição de aplicativo gerenciado, mas você deve certificar-se de que outros usuários na sua organização podem acessá-lo. Conceda a eles pelo menos a função de Leitor para a definição. Eles podem ter herdado esse nível de acesso da assinatura ou grupo de recursos. Para verificar quem tem acesso à definição e adicionar usuários ou grupos, confira Atribuir funções do Azure usando o portal do Azure.

Limpar recursos

Se estiver planejando implantar a definição, prossiga para a seção Próximas etapas, que inclui um link para o artigo para implantar a definição.

Se tiver terminado a definição do aplicativo gerenciado, você pode excluir os grupos de recursos que criou com os nomes packageStorageGroup e appDefinitionGroup.

O comando solicita que você confirme se deseja remover o grupo de recursos.

Remove-AzResourceGroup -Name packageStorageGroup

Remove-AzResourceGroup -Name appDefinitionGroup

Próximas etapas

Você publicou a definição de aplicativo gerenciado. A próxima etapa é aprender a implantar uma instância dessa definição.