Guia de início rápido: usar o Bicep para criar e publicar uma definição de Aplicativo Gerenciado do Azure

Este guia de início rápido descreve como usar o Bicep para criar e publicar uma definição de Aplicativo Gerenciado do Azure em seu catálogo de serviços. As definições no seu catálogo de serviços estão disponíveis para os membros da sua organização.

Para criar e publicar uma definição de aplicativo gerenciado em seu catálogo de serviços, execute as seguintes tarefas:

  • Use o Bicep para desenvolver seu modelo e convertê-lo em um modelo do Azure Resource Manager (modelo ARM). O modelo define os recursos do Azure implantados pelo aplicativo gerenciado.
  • Converta Bicep em JSON com o comando Bicep build . Depois que o arquivo é convertido em JSON, é recomendável verificar a precisão do código.
  • Defina os elementos de interface de utilizador para o portal quando implementar a aplicação gerida.
  • Crie um pacote .zip que contenha os arquivos JSON necessários. O arquivo de pacote .zip tem um limite de 120 MB para a definição de aplicativo gerenciado de um catálogo de serviços.
  • Publique a definição de aplicativo gerenciado para que ela esteja disponível em seu catálogo de serviços.

Se sua definição de aplicativo gerenciado tiver mais de 120 MB ou se você quiser usar sua própria conta de armazenamento por motivos de conformidade da sua organização, vá para Guia de início rápido: traga seu próprio armazenamento 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 seu catálogo de serviços. Para obter mais informações, vá para Guia de início rápido: usar o Bicep para implantar uma definição de Aplicativo Gerenciado do Azure.

Pré-requisitos

Para concluir as tarefas neste artigo, você precisa dos seguintes itens:

  • Uma conta do Azure com uma assinatura ativa e permissões para recursos do Microsoft Entra, como usuários, grupos ou entidades de serviço. Se você não tiver uma conta, crie uma conta gratuita antes de começar.
  • Código do Visual Studio com a extensão mais recente das Ferramentas do Azure Resource Manager. Para arquivos Bicep, instale a extensão Bicep para Visual Studio Code.
  • Instale a versão mais recente do Azure PowerShell ou da CLI do Azure.

Criar um arquivo Bicep

Cada definição de aplicação gerida inclui um ficheiro denominado mainTemplate.json. O modelo define os recursos do Azure a serem implantados e não é diferente de um modelo ARM normal. Você pode desenvolver o modelo usando Bicep e, em seguida, converter o arquivo Bicep para JSON.

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

Adicione o seguinte código Bicep e salve o arquivo. Ele define os recursos do aplicativo gerenciado para implantar um Serviço de Aplicativo, um plano do Serviço de Aplicativo e uma conta de armazenamento.

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

@description('Storage account name prefix.')
@maxLength(11)
param storageAccountNamePrefix string

@description('Storage account type allowed values')
@allowed([
  'Premium_LRS'
  'Standard_LRS'
  'Standard_GRS'
])
param storageAccountType string

var appServicePlanSku = 'F1'
var appServicePlanCapacity = 1
var appServiceName = '${appServiceNamePrefix}${uniqueString(resourceGroup().id)}'
var storageAccountName = '${storageAccountNamePrefix}${uniqueString(resourceGroup().id)}'
var appServiceStorageConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};Key=${storageAccount.listKeys().keys[0].value}'

resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: appServicePlanName
  location: location
  sku: {
    name: appServicePlanSku
    capacity: appServicePlanCapacity
  }
}

resource appServiceApp 'Microsoft.Web/sites@2022-03-01' = {
  name: appServiceName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
    siteConfig: {
      appSettings: [
        {
          name: 'AppServiceStorageConnectionString'
          value: appServiceStorageConnectionString
        }
      ]
    }
  }
}

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: storageAccountType
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

output appServicePlan string = appServicePlan.name
output appServiceApp string = appServiceApp.properties.defaultHostName
output storageAccount string = storageAccount.properties.primaryEndpoints.blob

Converter Bicep em JSON

Use o PowerShell ou a CLI do Azure para criar o arquivo mainTemplate.json . Vá para o diretório onde você salvou seu arquivo Bicep e execute o build comando.

bicep build mainTemplate.bicep

Para saber mais, vá para Bicep build.

Depois que o arquivo Bicep é convertido em JSON, seu arquivo mainTemplate.json deve corresponder ao exemplo a seguir. Você pode ter valores diferentes nas metadata propriedades de version e templateHash.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.17.1.54307",
      "templateHash": "1234567891234567890"
    }
  },
  "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]"
    }
  }
}

Defina a sua experiência no portal

Como editor, 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 entrada para cada parâmetro usando elementos de controle, como menus suspensos e caixas de texto.

Neste 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 que diferencia maiúsculas de minúsculas e salve-o.

Adicione o seguinte código JSON 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, vá para Introdução a CreateUiDefinition.

Empacote os ficheiros

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

Carregue app.zip em uma conta de armazenamento do Azure para que você possa usá-lo 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 na sua assinatura do Azure.

Connect-AzAccount

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

Depois de se conectar, execute os seguintes comandos.

New-AzResourceGroup -Name packageStorageRG -Location westus3

$storageAccount = New-AzStorageAccount `
  -ResourceGroupName packageStorageRG `
  -Name "<demostorageaccount>" `
  -Location westus3 `
  -SkuName Standard_LRS `
  -Kind StorageV2 `
  -AllowBlobPublicAccess $true

$ctx = $storageAccount.Context

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

Set-AzStorageBlobContent `
  -File "app.zip" `
  -Container appcontainer `
  -Blob "app.zip" `
  -Context $ctx

Use o comando a seguir para armazenar o URI do arquivo de pacote em uma variável chamada packageuri. Você usa o valor da variável ao implantar a definição de aplicativo gerenciado.

$packageuri=(Get-AzStorageBlob -Container appcontainer -Blob app.zip -Context $ctx).ICloudBlob.StorageUri.PrimaryUri.AbsoluteUri

Criar a definição da aplicação gerida

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 de grupo e ID de definição de função

A próxima etapa é selecionar um usuário, grupo de segurança ou aplicativo para gerenciar os recursos para o cliente. Essa identidade tem permissões no grupo de recursos gerenciado 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 deve ser 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ê usa o valor da variável ao implantar a definição de aplicativo gerenciado.

Para criar um novo grupo do Microsoft Entra, vá para Gerenciar grupos do Microsoft Entra e associação ao grupo.

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

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

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

Criar o modelo de implantação de definição

Use um arquivo Bicep para implantar a definição de aplicativo gerenciado em seu catálogo de serviços.

Abra o Visual Studio Code, crie um arquivo com o nome deployDefinition.bicep e salve-o.

Adicione o seguinte código Bicep e salve o arquivo.

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
      }
    ]
  }
}

Para obter mais informações sobre as propriedades do modelo, vá para Microsoft.Solutions/applicationDefinitions.

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 suportado. ReadOnly Especifica que o cliente só pode ler os recursos presentes no grupo de recursos gerenciados. As identidades de editor às quais é concedido acesso ao grupo de recursos gerenciados são isentas do nível de bloqueio.

Criar o ficheiro de parâmetros

O modelo de implantação da definição de aplicativo gerenciado precisa de entrada para vários parâmetros. O comando deployment solicita os valores ou você pode criar um arquivo de parâmetro para os valores. Neste exemplo, usamos um arquivo de parâmetro para passar os valores de parâmetro para o comando deployment.

No Visual Studio Code, crie um novo arquivo chamado deployDefinition.parameters.json e salve-o.

Adicione o seguinte ao seu arquivo de parâmetros e salve-o. Em seguida, substitua os <placeholder values> colchetes angulares (<>), pelos seus valores.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "managedApplicationDefinitionName": {
      "value": "sampleBicepManagedApplication"
    },
    "packageFileUri": {
      "value": "<placeholder for the packageFileUri>"
    },
    "principalId": {
      "value": "<placeholder for principalid value>"
    },
    "roleId": {
      "value": "<placeholder for roleid value>"
    }
  }
}

A tabela a seguir descreve os valores de parâmetro para a definição de aplicativo gerenciado.

Parâmetro Valor
managedApplicationDefinitionName Nome da definição de aplicativo gerenciado. Para este exemplo, use sampleBicepManagedApplication.
packageFileUri Insira o URI do arquivo de pacote .zip . Use o valor da variável packageuri . O formato é https://yourStorageAccountName.blob.core.windows.net/appcontainer/app.zip.
principalId A ID principal dos editores que precisa de permissões para gerenciar recursos no grupo de recursos gerenciados. Use o valor da variável principalid .
roleId ID de função para permissões para o grupo de recursos gerenciados. Por exemplo, Proprietário, Colaborador, Leitor. Use o valor da variável roleid .

Para obter os valores das variáveis:

  • Azure PowerShell: no PowerShell, digite $variableName para exibir o valor de uma variável.
  • CLI do Azure: em Bash, digite echo $variableName para exibir o valor de uma variável.

Implantar a definição

Quando você implanta a definição do aplicativo gerenciado, ele fica disponível em seu catálogo de serviços. Esse processo não implanta os recursos do aplicativo gerenciado.

Crie um grupo de recursos chamado bicepDefinitionRG e implante a definição de aplicativo gerenciado.

New-AzResourceGroup -Name bicepDefinitionRG -Location westus3

New-AzResourceGroupDeployment `
  -ResourceGroupName bicepDefinitionRG `
  -TemplateFile deployDefinition.bicep `
  -TemplateParameterFile deployDefinition.parameters.json

Verificar os resultados

Execute o seguinte comando para verificar se a definição foi publicada no seu catálogo de serviços.

Get-AzManagedApplicationDefinition -ResourceGroupName bicepDefinitionRG

Get-AzManagedApplicationDefinition lista todas as definições disponíveis no grupo de recursos especificado, como sampleBicepManagedApplication.

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

Tem acesso à definição de aplicação gerida, mas deve verificar se outros utilizadores na sua organização podem aceder à mesma. Conceda-lhes, pelo menos, a função de Leitor na definição. Estes podem ter herdado este nível de acesso através da subscrição ou do grupo de recursos. Para verificar quem tem acesso à definição e adicionar usuários ou grupos, vá para Atribuir funções do Azure usando o portal do Azure.

Clean up resources (Limpar recursos)

Se você vai implantar a definição, continue com a seção Próximas etapas que vincula ao artigo para implantar a definição com o Bicep.

Se você tiver terminado com a definição de aplicativo gerenciado, poderá excluir os grupos de recursos criados chamados packageStorageRG e bicepDefinitionRG.

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

Remove-AzResourceGroup -Name packageStorageRG

Remove-AzResourceGroup -Name bicepDefinitionRG

Próximos passos

Publicou a definição da aplicação gerida. A próxima etapa é aprender a implantar uma instância dessa definição.