Procedure consigliate per la creazione di modelli di Azure Resource ManagerBest practices for creating Azure Resource Manager templates

Le linee guida seguenti consentono di creare modelli di Azure Resource Manager affidabili e facili da usare;These guidelines can help you create Azure Resource Manager templates that are reliable and easy to use. sono quindi da considerare solo come suggerimentiThe guidelines are only suggestions. e non come requisiti assoluti, salvo diversa indicazione.They are not requirements, except where noted. I diversi scenari potrebbero richiedere una variazione rispetto agli approcci o esempi seguenti.Your scenario might require a variation of one of the following approaches or examples.

Nomi di risorseResource names

In genere vengono usati tre tipi di nomi di risorse in Resource Manager:Generally, you work with three types of resource names in Resource Manager:

  • Nomi di risorse che devono essere univoci.Resource names that must be unique.
  • Nomi di risorse che non devono necessariamente essere univoci, ma che si desidera rendano possibile l'identificazione di una risorsa in base al contesto.Resource names that are not required to be unique, but you choose to provide a name that can help you identify a resource based on context.
  • Nomi di risorse che possono essere generici.Resource names that can be generic.

    Per informazioni sulle restrizioni relative ai nomi di risorse, vedere Recommended naming conventions for Azure resources(Convenzioni di denominazione consigliate per le risorse di Azure).For information about resource name restrictions, see Recommended naming conventions for Azure resources.

Nomi di risorse univociUnique resource names

È necessario fornire un nome univoco per qualsiasi tipo di risorsa con un endpoint di accesso ai dati.You must provide a unique resource name for any resource type that has a data access endpoint. Alcuni tipi di risorse comuni che richiedono un nome univoco includono:Some common resource types that require a unique name include:

  • Archiviazione di Azure1Azure Storage1
  • Funzionalità app Web del servizio app di AzureWeb Apps feature of Azure App Service
  • SQL ServerSQL Server
  • Insieme di credenziali chiave AzureAzure Key Vault
  • Cache Redis di AzureAzure Redis Cache
  • Azure BatchAzure Batch
  • Gestione traffico di AzureAzure Traffic Manager
  • Ricerca di AzureAzure Search
  • HDInsight di AzureAzure HDInsight

1 I nomi di account di archiviazione devono essere formati da lettere minuscole, un massimo di 24 caratteri e non devono includere alcun segno meno.1 Storage account names also must be lowercase, 24 characters or less, and not have any hyphens.

Se si specifica un parametro per un nome di risorsa, è necessario indicare un nome univoco durante la distribuzione.If you provide a parameter for a resource name, you must provide a unique name when you deploy the resource. In alternativa, è possibile creare una variabile che usi la funzione uniqueString() per generare un nome.Optionally, you can create a variable that uses the uniqueString() function to generate a name.

È spesso opportuno aggiungere un prefisso o un suffisso al risultato di uniqueString.You also might want to add a prefix or suffix to the uniqueString result. La modifica del nome univoco consente di identificare più facilmente il tipo di risorsa in base al nome.Modifying the unique name can help you more easily identify the resource type from the name. Ad esempio, è possibile generare un nome univoco per un account di archiviazione usando la variabile seguente:For example, you can generate a unique name for a storage account by using the following variable:

"variables": {
    "storageAccountName": "[concat(uniqueString(resourceGroup().id),'storage')]"
}

Nomi di risorse per l'identificazioneResource names for identification

Si tratta di risorse cui si desidera attribuire un nome, ma di cui non è necessario garantire l'univocità.Some resource types you might want to name, but their names do not have to be unique. Per questi tipi di risorse, è sufficiente indicare un nome che identifichi il contesto e il tipo di risorsa.For these resource types, you can provide a name that identifies both the resource context and the resource type. È opportuno attribuire un nome descrittivo che ne faciliti il riconoscimento in un elenco di risorse.Provide a descriptive name that helps you identify the resource in a list of resources. Se è necessario modificare il nome della risorsa durante le distribuzioni, usare un parametro per il nome:If you need to use a different resource name for different deployments, you can use a parameter for the name:

"parameters": {
    "vmName": { 
        "type": "string",
        "defaultValue": "demoLinuxVM",
        "metadata": {
            "description": "The name of the VM to create."
        }
    }
}

Se non è necessario modificare il nome durante la distribuzione, usare una variabile:If you do not need to pass in a name during deployment, you can use a variable:

"variables": {
    "vmName": "demoLinuxVM"
}

In alternativa si può usare un valore hardcoded:You also can use a hard-coded value:

{
  "type": "Microsoft.Compute/virtualMachines",
  "name": "demoLinuxVM",
  ...
}

Nomi di risorse genericiGeneric resource names

Per i tipi di risorse in gran parte accessibili tramite un'altra risorsa, è possibile usare un nome generico che sia hardcoded nel modello.For resource types that you mostly access through a different resource, you can use a generic name that is hard-coded in the template. Ad esempio, è possibile impostare un nome generico e standard per le regole del firewall in SQL server:For example, you can set a standard, generic name for firewall rules on a SQL server:

{
    "type": "firewallrules",
    "name": "AllowAllWindowsAzureIps",
    ...
}

parametersParameters

Le informazioni seguenti possono essere utili quando si usano parametri:The following information can be helpful when you work with parameters:

  • Ridurre al minimo l'uso di parametri.Minimize your use of parameters. Se possibile, usare una variabile o un valore letterale.Whenever possible, use a variable or a literal value. Specificare parametri solo per questi scenari:Use parameters only for these scenarios:

    • Impostazioni da variare in base all'ambiente (ad esempio SKU, dimensioni o capacità).Settings that you want to use variations of according to environment (SKU, size, capacity).
    • Nomi di risorse da specificare per facilitare l'identificazione.Resource names that you want to specify for easy identification.
    • Valori usati spesso per completare altre attività (ad esempio nome utente amministratore).Values that you use frequently to complete other tasks (such as an admin user name).
    • Segreti (ad esempio password).Secrets (such as passwords).
    • Il numero o la matrice di valori da usare durante la creazione di più istanze di un tipo di risorsa.The number or array of values to use when you create multiple instances of a resource type.
  • Usare la notazione Camel per i nomi dei parametri.Use camel case for parameter names.
  • Indicare una descrizione nei metadati per ogni parametro:Provide a description of every parameter in the metadata:

    "parameters": {
        "storageAccountType": {
            "type": "string",
            "metadata": {
                "description": "The type of the new storage account created to store the VM disks."
            }
        }
    }
    
  • Definire i valori predefiniti per i parametri (ad eccezione delle password e delle chiavi SSH):Define default values for parameters (except for passwords and SSH keys):

    "parameters": {
         "storageAccountType": {
             "type": "string",
             "defaultValue": "Standard_GRS",
             "metadata": {
                 "description": "The type of the new storage account created to store the VM disks."
             }
         }
    }
    
  • Usare SecureString per tutte le password e i segreti:Use SecureString for all passwords and secrets:

    "parameters": {
        "secretValue": {
            "type": "securestring",
            "metadata": {
                "description": "The value of the secret to store in the vault."
            }
        }
    }
    
  • Quando possibile, evitare di usare un parametro per specificare la posizione.Whenever possible, don't use a parameter to specify location. Usare invece la proprietà location del gruppo di risorse.Instead, use the location property of the resource group. Usando l'espressione resourceGroup().location per tutte le risorse, le risorse nel modello verranno distribuite nella stessa posizione del gruppo di risorse:By using the resourceGroup().location expression for all your resources, resources in the template are deployed in the same location as the resource group:

    "resources": [
      {
          "name": "[variables('storageAccountName')]",
          "type": "Microsoft.Storage/storageAccounts",
          "apiVersion": "2016-01-01",
          "location": "[resourceGroup().location]",
          ...
      }
    ]
    

    Se un tipo di risorsa è supportato solo in un numero limitato di posizioni, provare a specificare una posizione valida direttamente nel modello.If a resource type is supported in only a limited number of locations, you might want to specify a valid location directly in the template. Se è necessario usare un parametro location, condividere per quanto possibile il relativo valore con le risorse che potrebbero essere nella stessa posizione.If you must use a location parameter, share that parameter value as much as possible with resources that are likely to be in the same location. Questo approccio permette di ridurre al minimo il numero di volte in cui gli utenti devono dare informazioni sulla posizione.This minimizes the number of times users are asked to provide location information.

  • Evitare di usare un parametro o una variabile per la versione dell'API per un tipo di risorsa.Avoid using a parameter or variable for the API version for a resource type. I valori e le proprietà delle risorse possono variare in base al numero di versione.Resource properties and values can vary by version number. Quando la versione dell'API è impostata su un parametro o una variabile, IntelliSense negli editor di codice non può determinare lo schema corretto.IntelliSense in a code editor cannot determine the correct schema when the API version is set to a parameter or variable. Impostare invece la versione dell'API come hardcoded nel modello.Instead, hard-code the API version in the template.

variablesVariables

Le informazioni seguenti possono essere utili quando si usano variabili:The following information can be helpful when you work with variables:

  • Usare le variabili per i valori da usare più volte in un modello.Use variables for values that you need to use more than once in a template. Se un valore viene usato una sola volta, un valore hardcoded facilita la lettura del modello.If a value is used only once, a hard-coded value makes your template easier to read.
  • Non è possibile usare la funzione reference nella sezione variables del modello.You cannot use the reference function in the variables section of the template. La funzione reference deriva il proprio valore dallo stato di runtime della risorsa,The reference function derives its value from the resource's runtime state. ma le variabili vengono risolte durante l'analisi iniziale del modello.However, variables are resolved during the initial parsing of the template. Costruire invece valori che richiedono la funzione reference direttamente nella sezione resources o outputs del modello.Construct values that need the reference function directly in the resources or outputs section of the template.
  • Includere le variabili per i nomi di risorse che devono essere univoci, come illustrato in Nomi di risorse.Include variables for resource names that must be unique, as described in Resource names.
  • È possibile raggruppare le variabili in oggetti complessi.You can group variables into complex objects. È possibile fare riferimento a un valore da un oggetto complesso nel formato variable.subentry.Use the variable.subentry format to reference a value from a complex object. Il raggruppamento delle variabili consente di tenere traccia delle variabili correlateGrouping variables can help you track related variables. e migliora la leggibilità del modello.It also improves readability of the template. Ad esempio:Here's an example:

    "variables": {
        "storage": {
            "name": "[concat(uniqueString(resourceGroup().id),'storage')]",
            "type": "Standard_LRS"
        }
    },
    "resources": [
      {
          "type": "Microsoft.Storage/storageAccounts",
          "name": "[variables('storage').name]",
          "apiVersion": "2016-01-01",
          "location": "[resourceGroup().location]",
          "sku": {
              "name": "[variables('storage').type]"
          },
          ...
      }
    ]
    

    Nota

    Un oggetto complesso non può contenere un'espressione che fa riferimento a un valore da un oggetto complesso.A complex object cannot contain an expression that references a value from a complex object. A questo scopo, definire una variabile separata.Define a separate variable for this purpose.

    Per esempi avanzati di uso di oggetti complessi come variabili, vedere Condividere lo stato tra modelli di Azure Resource Manager.For advanced examples of using complex objects as variables, see Share state in Azure Resource Manager templates.

RisorseResources

Le informazioni seguenti possono essere utili quando si usano le risorse:The following information can be helpful when you work with resources:

  • Specificare comments per ogni risorsa nel modello per consentire ad altri collaboratori di comprendere lo scopo della risorsa:To help other contributors understand the purpose of the resource, specify comments for each resource in the template:

    "resources": [
      {
          "name": "[variables('storageAccountName')]",
          "type": "Microsoft.Storage/storageAccounts",
          "apiVersion": "2016-01-01",
          "location": "[resourceGroup().location]",
          "comments": "This storage account is used to store the VM disks.",
          ...
      }
    ]
    
  • È possibile usare i tag per aggiungere metadati alle risorse.You can use tags to add metadata to resources. Usare i metadati per aumentare le informazioni sulle risorse.Use metadata to add information about your resources. Ad esempio, è possibile aggiungere metadati per registrare i dettagli di fatturazione di una risorsa.For example, you can add metadata to record billing details for a resource. Per altre informazioni, vedere Uso dei tag per organizzare le risorse di Azure.For more information, see Using tags to organize your Azure resources.

  • Se si usa un endpoint pubblico nel modello, come ad esempio un endpoint pubblico di archiviazione BLOB di Azure, non impostare come hardcoded lo spazio dei nomi.If you use a public endpoint in your template (such as an Azure Blob storage public endpoint), do not hard-code the namespace. Usare la funzione reference per recuperare lo spazio dei nomi in modo dinamico.Use the reference function to dynamically retrieve the namespace. Questo approccio consente di distribuire il modello in ambienti diversi dello spazio dei nomi pubblico senza dover modificare manualmente l'endpoint nel modello.You can use this approach to deploy the template to different public namespace environments without manually changing the endpoint in the template. Impostare la versione dell'API sulla stessa versione in uso per l'account di archiviazione nel modello:Set the API version to the same version that you are using for the storage account in your template:

    "osDisk": {
        "name": "osdisk",
        "vhd": {
            "uri": "[concat(reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), '2016-01-01').primaryEndpoints.blob, variables('vmStorageAccountContainerName'), '/',variables('OSDiskName'),'.vhd')]"
        }
    }
    

    Se l'account di archiviazione viene distribuito nello stesso modello creato, non è necessario specificare lo spazio dei nomi del provider quando si fa riferimento alla risorsa.If the storage account is deployed in the same template that you are creating, you do not need to specify the provider namespace when you reference the resource. La sintassi semplificata è:This is the simplified syntax:

    "osDisk": {
        "name": "osdisk",
        "vhd": {
            "uri": "[concat(reference(variables('storageAccountName'), '2016-01-01').primaryEndpoints.blob, variables('vmStorageAccountContainerName'), '/',variables('OSDiskName'),'.vhd')]"
        }
    }
    

    Se nel modello sono presenti altri valori configurati per usare uno spazio dei nomi pubblico, modificarli in modo da riflettere la stessa funzione reference.If you have other values in your template that are configured to use a public namespace, change these values to reflect the same reference function. Ad esempio, è possibile impostare la proprietà storageUri del profilo di diagnostica della macchina virtuale:For example, you can set the storageUri property of the virtual machine diagnostics profile:

    "diagnosticsProfile": {
        "bootDiagnostics": {
            "enabled": "true",
            "storageUri": "[reference(concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), '2016-01-01').primaryEndpoints.blob]"
        }
    }
    

    È anche possibile fare riferimento a un account di archiviazione in un gruppo di risorse diverso:You also can reference an existing storage account that is in a different resource group:

    "osDisk": {
        "name": "osdisk", 
        "vhd": {
            "uri":"[concat(reference(resourceId(parameters('existingResourceGroup'), 'Microsoft.Storage/storageAccounts/', parameters('existingStorageAccountName')), '2016-01-01').primaryEndpoints.blob,  variables('vmStorageAccountContainerName'), '/', variables('OSDiskName'),'.vhd')]"
        }
    }
    
  • Assegnare indirizzi IP pubblici a una macchina virtuale solo se richiesto per un'applicazione.Assign public IP addresses to a virtual machine only when an application requires it. Per connettersi a una macchina virtuale (VM) per il debug o per la gestione o a scopi amministrativi, usare le regole NAT in ingresso, un gateway di rete virtuale o un jumpbox.To connect to a virtual machine (VM) for debugging, or for management or administrative purposes, use inbound NAT rules, a virtual network gateway, or a jumpbox.

    Per altre informazioni sulla connessione alle macchine virtuali, vedere:For more information about connecting to virtual machines, see:

  • La proprietà domainNameLabel deve essere univoca per gli indirizzi IP pubblici.The domainNameLabel property for public IP addresses must be unique. Il valore domainNameLabel deve avere una lunghezza compresa tra 3 e 63 caratteri e seguire le regole specificate dall'espressione regolare seguente: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$.The domainNameLabel value must be between 3 and 63 characters long, and follow the rules specified by this regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. Dato che la funzione uniqueString genera una stringa lunga 13 caratteri, il parametro dnsPrefixString non deve superare 50 caratteri:Because the uniqueString function generates a string that is 13 characters long, the dnsPrefixString parameter is limited to 50 characters:

    "parameters": {
        "dnsPrefixString": {
            "type": "string",
            "maxLength": 50,
            "metadata": {
                "description": "The DNS label for the public IP address. It must be lowercase. It should match the following regular expression, or it will raise an error: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$"
            }
        }
    },
    "variables": {
        "dnsPrefix": "[concat(parameters('dnsPrefixString'),uniquestring(resourceGroup().id))]"
    }
    
  • Quando si aggiunge una password a un'estensione di script personalizzato, usare la proprietà commandToExecute nella proprietà protectedSettings:When you add a password to a custom script extension, use the commandToExecute property in the protectedSettings property:

    "properties": {
        "publisher": "Microsoft.Azure.Extensions",
        "type": "CustomScript",
        "typeHandlerVersion": "2.0",
        "autoUpgradeMinorVersion": true,
        "settings": {
            "fileUris": [
                "[concat(variables('template').assets, '/lamp-app/install_lamp.sh')]"
            ]
        },
        "protectedSettings": {
            "commandToExecute": "[concat('sh install_lamp.sh ', parameters('mySqlPassword'))]"
        }
    }
    

    Nota

    Per garantire che i segreti passati come parametri a macchine virtuali ed estensioni siano crittografati, usare la proprietà protectedSettings delle estensioni pertinenti.To ensure that secrets are encrypted when they are passed as parameters to VMs and extensions, use the protectedSettings property of the relevant extensions.

outputsOutputs

Se viene usato un modello per creare indirizzi IP pubblici, deve includere una sezione outputs che restituisca i dettagli dell'indirizzo IP e del nome di dominio completo (FQDN).If you use a template to create public IP addresses, include an outputs section that returns details of the IP address and the fully qualified domain name (FQDN). Questi valori di output consentiranno di recuperare facilmente i dettagli sugli indirizzi IP pubblici e sugli FQDN dopo la distribuzione.You can use output values to easily retrieve details about public IP addresses and FQDNs after deployment. Quando si fa riferimento alla risorsa, usare la versione dell'API impiegata per crearla:When you reference the resource, use the API version that you used to create it:

"outputs": {
    "fqdn": {
        "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',parameters('publicIPAddressName')), '2016-07-01').dnsSettings.fqdn]",
        "type": "string"
    },
    "ipaddress": {
        "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',parameters('publicIPAddressName')), '2016-07-01').ipAddress]",
        "type": "string"
    }
}

Modello singolo o modelli annidatiSingle template vs. nested templates

Per distribuire la soluzione, è possibile usare un modello singolo o un modello principale con più modelli annidati.To deploy your solution, you can use either a single template or a main template with multiple nested templates. I modelli annidati sono comuni per scenari più avanzati.Nested templates are common for more advanced scenarios. L'uso di un modello annidato presenta i vantaggi seguenti:Using a nested template gives you the following advantages:

  • È possibile scomporre la soluzione in componenti di destinazione.You can break down a solution into targeted components.
  • È possibile riusare i modelli annidati con modelli principali diversi.You can reuse nested templates with different main templates.

Quando si decide di scomporre la progettazione del modello in più modelli annidati, le linee guida seguenti ne consentono la standardizzazione.If you choose to use nested templates, the following guidelines can help you standardize your template design. Queste linee guida si basano sui criteri di progettazione per modelli di Azure Resource Manager.These guidelines are based on patterns for designing Azure Resource Manager templates. La progettazione consigliata include i modelli seguenti:We recommend a design that has the following templates:

  • Modello principale (azuredeploy.json).Main template (azuredeploy.json). Da usare per i parametri di input.Use for the input parameters.
  • Modello di risorse condivise.Shared resources template. Da usare per distribuire le risorse condivise da tutte le altre risorse (ad esempio, rete virtuale e set di disponibilità).Use to deploy shared resources that all other resources use (for example, virtual network and availability sets). L'espressione dependsOn deve essere usata per assicurarsi che questo modello venga distribuito prima degli altri.Use the dependsOn expression to ensure that this template is deployed before other templates.
  • Modello di risorse facoltative.Optional resources template. Da usare per distribuire risorse in modo condizionale in base a un parametro, ad esempio un jumpbox.Use to conditionally deploy resources based on a parameter (for example, a jumpbox).
  • Modello di risorse membro.Member resources template. Ogni tipo di istanza all'interno di un livello di applicazione prevede una propria configurazione.Each instance type within an application tier has its own configuration. All'interno di un livello, è possibile definire diversi tipi di istanza.Within a tier, you can define different instance types. Ad esempio, la prima istanza crea un cluster mentre le altre vengono aggiunte al cluster esistente. Ogni tipo di istanza avrà un proprio modello di distribuzione.(For example, the first instance creates a cluster, and additional instances are added to the existing cluster.) Each instance type has its own deployment template.
  • Script.Scripts. Per ogni tipo di istanza sono applicabili script ampiamente riutilizzabili, come ad esempio quelli di inizializzazione e formattazione di dischi aggiuntivi.Widely reusable scripts are applicable for each instance type (for example, initialize and format additional disks). Gli script personalizzati vengono creati per scopi di personalizzazione specifici e variano in base al tipo di istanza.Custom scripts that you create for a specific customization purpose are different, based on the instance type.

Modello annidato

Per altre informazioni, vedere Uso di modelli collegati con Azure Resource Manager.For more information, see Use linked templates with Azure Resource Manager.

È possibile collegarsi in modo condizionale ai modelli annidati usando un parametroYou can use a parameter to conditionally link to nested templates. che diventa parte dell'URI per il modello:The parameter becomes part of the URI for the template:

"parameters": {
    "newOrExisting": {
        "type": "String",
        "allowedValues": [
            "new",
            "existing"
        ]
    }
},
"variables": {
    "templatelink": "[concat('https://raw.githubusercontent.com/Contoso/Templates/master/',parameters('newOrExisting'),'StorageAccount.json')]"
},
"resources": [
    {
        "apiVersion": "2015-01-01",
        "name": "nestedTemplate",
        "type": "Microsoft.Resources/deployments",
        "properties": {
            "mode": "incremental",
            "templateLink": {
                "uri": "[variables('templatelink')]",
                "contentVersion": "1.0.0.0"
            },
            "parameters": {
            }
        }
    }
]

Formato del modelloTemplate format

È consigliabile passare il modello tramite un validator JSON.It's a good practice to pass your template through a JSON validator. Un validator può aiutare a rimuovere virgole, parentesi e parentesi quadre estranee che potrebbero causare un errore durante la distribuzione.A validator can help you remove extraneous commas, parentheses, and brackets that might cause an error during deployment. Provare JSONlint o un pacchetto linter per l'ambiente di modifica preferito (Visual Studio Code, Atom, Sublime Text, Visual Studio).Try JSONLint or a linter package for your favorite editing environment (Visual Studio Code, Atom, Sublime Text, Visual Studio).

È anche consigliabile formattare il codice JSON per una migliore leggibilità.It's also a good idea to format your JSON for better readability. È possibile usare un pacchetto formattatore JSON per l'editor locale.You can use a JSON formatter package for your local editor. In Visual Studio formattare il documento con Ctrl+K, Ctrl+D.In Visual Studio, to format the document, press Ctrl+K, Ctrl+D. In Visual Studio Code, usare Alt+Shift+F.In Visual Studio Code, press Alt+Shift+F. Se l'editor locale non formatta il documento, è possibile usare un formattatore online.If your local editor doesn't format the document, you can use an online formatter.

Passaggi successiviNext steps