Avvio rapido: Creare e pubblicare una definizione di applicazione gestita di Azure

Questo argomento di avvio rapido fornisce un'introduzione all'uso delle applicazioni gestite di Azure. Si crea e si pubblica una definizione di applicazione gestita archiviata nel catalogo dei servizi e destinata ai membri dell'organizzazione.

Per pubblicare un'applicazione gestita nel catalogo di servizi, eseguire le attività seguenti:

  • Creare un modello di Azure Resource Manager che definisce le risorse da distribuire con l'applicazione gestita.
  • Definire gli elementi dell'interfaccia utente per il portale quando si distribuisce l'applicazione gestita.
  • Creare un pacchetto ZIP contenente i file JSON necessari. Il file di pacchetto ZIP ha un limite di 120 MB per la definizione dell'applicazione gestita di un catalogo di servizi.
  • Pubblicare la definizione dell'applicazione gestita in modo che sia disponibile nel catalogo dei servizi.

Se la definizione dell'applicazione gestita è superiore a 120 MB o se si vuole usare il proprio account di archiviazione per motivi di conformità dell'organizzazione, vedere Avvio rapido: Bring your own storage per creare e pubblicare una definizione di applicazione gestita di Azure.

È possibile usare Bicep per sviluppare una definizione di applicazione gestita, ma deve essere convertita in JSON del modello arm prima di poter pubblicare la definizione in Azure. Per altre informazioni, vedere Avvio rapido: Usare Bicep per creare e pubblicare una definizione di applicazione gestita di Azure.

È anche possibile usare Bicep per distribuire una definizione di applicazione gestita dal catalogo dei servizi. Per altre informazioni, vedere Avvio rapido: Usare Bicep per distribuire una definizione di applicazione gestita di Azure.

Prerequisiti

Per completare questa guida introduttiva, sono necessari gli elementi seguenti:

Creare il modello di Resource Manager

Ogni definizione di applicazione gestita include un file denominato mainTemplate.json, Il modello definisce le risorse di Azure da distribuire e non è diverso da un modello di Resource Manager normale.

Aprire Visual Studio Code, creare un file con il nome con distinzione tra maiuscole e minuscole mainTemplate.json e salvarlo.

Aggiungere il codice JSON seguente e salvare il file. Definisce le risorse per distribuire un servizio app, un piano servizio app e un account di archiviazione per l'applicazione. Questo account di archiviazione non viene usato per archiviare la definizione dell'applicazione gestita.

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

Definire l'esperienza del portale

Gli autori definiscono l'esperienza del portale per creare l'applicazione gestita. Il file createUiDefinition.json genera l'interfaccia utente del portale. Si definisce il modo in cui gli utenti forniscono input per ogni parametro usando elementi di controllo come elenchi a discesa e caselle di testo.

In questo esempio, l'interfaccia utente richiede di immettere il prefisso del nome servizio app, il nome del piano servizio app, il prefisso dell'account di archiviazione e il tipo di account di archiviazione. Durante la distribuzione, le variabili in mainTemplate.json usano la uniqueString funzione per aggiungere una stringa di 13 caratteri ai prefissi dei nomi in modo che i nomi siano globalmente univoci in Azure.

Aprire Visual Studio Code, creare un file con il nome con distinzione tra maiuscole e minuscole createUiDefinition.json e salvarlo.

Aggiungere il codice JSON seguente al file e salvarlo.

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

Per altre informazioni, vedere Introduzione a CreateUiDefinition.

Creare il pacchetto dei file

Aggiungere i due file a un file di pacchetto denominato app.zip. I due file devono trovarsi al livello radice del file con estensione zip. Se i file si trovano in una cartella, quando si crea la definizione dell'applicazione gestita, viene visualizzato un errore che indica che i file necessari non sono presenti.

Caricare app.zip in un account di archiviazione di Azure in modo da poterlo usare quando si distribuisce la definizione dell'applicazione gestita. Il nome dell'account di archiviazione deve essere univoco a livello globale in Azure e la lunghezza deve essere di 3-24 caratteri con solo lettere minuscole e numeri. Nel comando sostituire il segnaposto <demostorageaccount> , incluse le parentesi angolari (<>), con il nome dell'account di archiviazione univoco.

In Visual Studio Code aprire un nuovo terminale di PowerShell e accedere alla sottoscrizione di Azure.

Connect-AzAccount

Il comando apre il browser predefinito e chiede di accedere ad Azure. Per altre informazioni, vedere Accedere con 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

Creare la definizione di applicazione gestita

In questa sezione si ottengono informazioni sull'identità da Microsoft Entra ID, si crea un gruppo di risorse e si distribuisce la definizione dell'applicazione gestita.

Ottenere l'ID gruppo e l'ID definizione del ruolo

Il passaggio successivo consiste nel selezionare un utente, un gruppo di sicurezza o un'applicazione per la gestione delle risorse per il cliente. Questa identità dispone delle autorizzazioni per il gruppo di risorse gestite in base al ruolo assegnato. Il ruolo può essere qualsiasi ruolo predefinito di Azure, ad esempio Proprietario o Collaboratore.

Questo esempio usa un gruppo di sicurezza e l'account Microsoft Entra deve essere membro del gruppo. Per ottenere l'ID oggetto del gruppo, sostituire il segnaposto <managedAppDemo> , incluse le parentesi angolari (<>), con il nome del gruppo. Il valore di questa variabile viene usato quando si distribuisce la definizione dell'applicazione gestita.

Per creare un nuovo gruppo Microsoft Entra, passare a Gestisci gruppi di Microsoft Entra e appartenenza a gruppi.

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

Ottenere quindi l'ID definizione del ruolo del ruolo predefinito di Azure a cui si vuole concedere l'accesso all'utente, al gruppo o all'applicazione. Il valore di questa variabile viene usato quando si distribuisce la definizione dell'applicazione gestita.

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

Pubblicare la definizione dell'applicazione gestita

Creare un gruppo di risorse per la definizione dell'applicazione gestita.

New-AzResourceGroup -Name appDefinitionGroup -Location westus3

Il blob comando crea una variabile per archiviare l'URL per il file con estensione zip del pacchetto. Tale variabile viene usata nel comando che crea la definizione dell'applicazione gestita.

$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

Al completamento del comando, è disponibile una definizione dell'applicazione gestita nel gruppo di risorse.

Ecco alcuni parametri usati nell'esempio precedente:

  • ResourceGroupName: nome del gruppo di risorse in cui viene creata la definizione dell'applicazione gestita.
  • LockLevel: nel lockLevel gruppo di risorse gestite impedisce al cliente di eseguire operazioni indesiderate su questo gruppo di risorse. Attualmente, ReadOnly è l'unico livello di blocco supportato. ReadOnly specifica che il cliente può leggere solo le risorse presenti nel gruppo di risorse gestite. Le identità del server di pubblicazione a cui viene concesso l'accesso al gruppo di risorse gestite sono esenti dal livello di blocco.
  • Authorization: descrive l'ID entità e l'ID definizione del ruolo usati per concedere l'autorizzazione al gruppo di risorse gestite.
    • "${principalid}:$roleid" oppure è possibile usare parentesi graffe per ogni variabile "${principalid}:${roleid}".
    • Usare una virgola per separare più valori: "${principalid1}:$roleid1", "${principalid2}:$roleid2".
  • PackageFileUri: percorso di un file di pacchetto con estensione zip contenente i file necessari.

Assicurarsi che gli utenti possano visualizzare la definizione

Si ha accesso alla definizione dell'applicazione gestita, ma si vuole assicurarsi che gli altri utenti nell'organizzazione possano accedervi. Concedere loro almeno il ruolo di Lettore per la definizione. Gli utenti potrebbero aver ereditato questo livello di accesso dalla sottoscrizione o dal gruppo di risorse. Per verificare chi può accedere alla definizione e aggiungere utenti o gruppi, vedere Assegnare ruoli di Azure usando il portale di Azure.

Pulire le risorse

Se si intende distribuire la definizione, continuare con la sezione Passaggi successivi che collega all'articolo per distribuire la definizione.

Se la definizione dell'applicazione gestita è stata completata, è possibile eliminare i gruppi di risorse creati con il nome package Archiviazione Group e appDefinitionGroup.

Il comando chiede di confermare che si vuole rimuovere il gruppo di risorse.

Remove-AzResourceGroup -Name packageStorageGroup

Remove-AzResourceGroup -Name appDefinitionGroup

Passaggi successivi

La definizione di applicazione gestita è stata pubblicata. Il passaggio successivo consiste nell'apprendere come distribuire un'istanza di tale definizione.