Uso di modelli collegati e annidati nella distribuzione di risorse di AzureUsing linked and nested templates when deploying Azure resources

Per distribuire la soluzione, è possibile usare un modello singolo o un modello principale con molti modelli correlati.To deploy your solution, you can use either a single template or a main template with many related templates. Il modello correlato può essere un file separato collegato dal modello principale o un modello che viene annidato all'interno del modello principale.The related template can be either a separate file that is linked to from the main template, or a template that is nested within the main template.

Per le piccole e medie soluzioni, un modello singolo è più facile da comprendere e gestire.For small to medium solutions, a single template is easier to understand and maintain. È possibile vedere tutti i valori e le risorse in un unico file.You can see all the resources and values in a single file. Per gli scenari avanzati, i modelli collegati consentono di suddividere la soluzione in componenti di destinazione, oltre che di riutilizzare i modelli.For advanced scenarios, linked templates enable you to break down the solution into targeted components, and reuse templates.

Quando si usa un modello collegato, si crea un modello principale che riceve i valori dei parametri durante la distribuzione.When using linked template, you create a main template that receives the parameter values during deployment. Il modello principale contiene tutti i modelli collegati e passa i valori a tali modelli in base alle esigenze.The main template contains all the linked templates and passes values to those templates as needed.

Per stabilire un collegamento a un altro modello, aggiungere una risorsa deployments al modello principale.To link to another template, add a deployments resource to your main template.

"resources": [
  {
      "apiVersion": "2017-05-10",
      "name": "linkedTemplate",
      "type": "Microsoft.Resources/deployments",
      "properties": {
          "mode": "Incremental",
          <nested-template-or-external-template>
      }
  }
]

Le proprietà fornite per la risorsa di distribuzione variano in base al fatto che si stia stabilendo un collegamento a un modello esterno o annidando un modello inline nel modello principale.The properties you provide for the deployment resource vary based on whether you are linking to an external template or nesting an inline template in the main template.

Modello annidatoNested template

Per annidare il modello all'interno del modello principale, usare la proprietà template e specificare la sintassi del modello.To nest the template within the main template, use the template property and specify the template syntax.

"resources": [
  {
    "apiVersion": "2017-05-10",
    "name": "nestedTemplate",
    "type": "Microsoft.Resources/deployments",
    "properties": {
      "mode": "Incremental",
      "template": {
        "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "resources": [
          {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageName')]",
            "apiVersion": "2015-06-15",
            "location": "West US",
            "properties": {
              "accountType": "Standard_LRS"
            }
          }
        ]
      }
    }
  }
]

Nota

Per i modelli annidati non è possibile usare i parametri o le variabili definiti all'interno del modello annidato.For nested templates, you cannot use parameters or variables that are defined within the nested template. È possibile usare i parametri e variabili dal modello principale.You can use parameters and variables from the main template. Nell'esempio precedente [variables('storageName')] recupera un valore dal modello principale e non dal modello annidato.In the preceding example, [variables('storageName')] retrieves a value from the main template, not the nested template. Questa restrizione non è valida per i modelli esterni.This restriction does not apply to external templates.

Non è possibile usare la funzione reference nella sezione outputs di un modello annidato.You cannot use the reference function in the outputs section of a nested template. Per restituire i valori per una risorsa distribuita in un modello annidato, convertire il modello annidato in un modello collegato.To return the values for a deployed resource in a nested template, convert your nested template to a linked template.

Per il modello annidato è necessario specificare le stesse proprietà del modello standard.The nested template requires the same properties as a standard template.

Modello esterno e parametri esterniExternal template and external parameters

Per collegare un modello esterno e un file di parametri, usare templateLink e parametersLink.To link to an external template and parameter file, use templateLink and parametersLink. Quando si stabilisce un collegamento a un modello, il servizio Resource Manager deve potervi accedere.When linking to a template, the Resource Manager service must be able to access it. Non è possibile specificare un file locale o un file disponibile solo nella rete locale.You cannot specify a local file or a file that is only available on your local network. È possibile fornire solo un valore URI che includa http o https.You can only provide a URI value that includes either http or https. È possibile inserire il modello collegato in un account di archiviazione e usare l'URI per tale elemento.One option is to place your linked template in a storage account, and use the URI for that item.

"resources": [
  {
     "apiVersion": "2017-05-10",
     "name": "linkedTemplate",
     "type": "Microsoft.Resources/deployments",
     "properties": {
       "mode": "incremental",
       "templateLink": {
          "uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
          "contentVersion":"1.0.0.0"
       },
       "parametersLink": {
          "uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.parameters.json",
          "contentVersion":"1.0.0.0"
       }
     }
  }
]

Non è necessario specificare la proprietà contentVersion per il modello o i parametri.You don't have to provide the contentVersion property for the template or parameters. Se non si specifica un valore per la versione del contenuto, viene distribuita la versione corrente del modello.If you don't provide a content version value, the current version of the template is deployed. Se si specifica un valore per la versione del contenuto, questa deve corrispondere alla versione del modello collegato. In caso contrario, la distribuzione ha esito negativo con un errore.If you provide a value for content version, it must match the version in the linked template; otherwise, the deployment fails with an error.

Modello esterno e parametri inlineExternal template and inline parameters

In alternativa, è possibile fornire il parametro inline.Or, you can provide the parameter inline. Per passare un valore dal modello principale al modello collegato, usare parameters.To pass a value from the main template to the linked template, use parameters.

"resources": [
  {
     "apiVersion": "2017-05-10",
     "name": "linkedTemplate",
     "type": "Microsoft.Resources/deployments",
     "properties": {
       "mode": "incremental",
       "templateLink": {
          "uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
          "contentVersion":"1.0.0.0"
       },
       "parameters": {
          "StorageAccountName":{"value": "[parameters('StorageAccountName')]"}
        }
     }
  }
]

Negli esempi precedenti sono illustrati i valori di URL hard-coded per i collegamenti del modello.The previous examples showed hard-coded URL values for the template links. Questo approccio può funzionare per un modello semplice, ma non funziona correttamente se si usa un set di grandi dimensioni di modelli modulari.This approach might work for a simple template but it doesn't work well when working with a large set of modular templates. In alternativa, è possibile creare una variabile statica contenente un URL di base per il modello principale e quindi creare dinamicamente gli URL per i modelli collegati da tale URL di base.Instead, you can create a static variable that stores a base URL for the main template and then dynamically create URLs for the linked templates from that base URL. Il vantaggio di questo approccio è rappresentato dal fatto che risulta più semplice spostare o scomporre il modello perché è sufficiente modificare la variabile statica nel modello principale.The benefit of this approach is you can easily move or fork the template because you only need to change the static variable in the main template. Il modello principale passa gli URI corretti a tutto il modello scomposto.The main template passes the correct URIs throughout the decomposed template.

Nell'esempio seguente viene illustrato come usare un URL di base per creare due URL per i modelli collegati (sharedTemplateUrl e vmTemplate).The following example shows how to use a base URL to create two URLs for linked templates (sharedTemplateUrl and vmTemplate).

"variables": {
    "templateBaseUrl": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/postgresql-on-ubuntu/",
    "sharedTemplateUrl": "[concat(variables('templateBaseUrl'), 'shared-resources.json')]",
    "vmTemplateUrl": "[concat(variables('templateBaseUrl'), 'database-2disk-resources.json')]"
}

È inoltre possibile usare deployment () per ottenere l'URL di base per il modello corrente e usarlo per ottenere l'URL per altri modelli nello stesso percorso.You can also use deployment() to get the base URL for the current template, and use that to get the URL for other templates in the same location. Questo approccio è utile se la posizione del modello cambia o si vuole evitare la codifica di URL nel file del modello.This approach is useful if your template location changes or you want to avoid hard coding URLs in the template file. La proprietà templateLink viene restituita solo durante il collegamento a un modello remoto con un URL.The templateLink property is only returned when linking to a remote template with a URL. Se si usa un modello locale, tale proprietà non è disponibile.If you're using a local template, that property isn't available.

"variables": {
    "sharedTemplateUrl": "[uri(deployment().properties.templateLink.uri, 'shared-resources.json')]"
}

Ottenere valori dal modello collegatoGet values from linked template

Per ottenere un valore di output da un modello collegato, recuperare il valore della proprietà con una sintassi analoga a: "[reference('<name-of-deployment>').outputs.<property-name>.value]".To get an output value from a linked template, retrieve the property value with syntax like: "[reference('<name-of-deployment>').outputs.<property-name>.value]".

Gli esempi seguenti illustrano come fare riferimento a un modello collegato e recuperare un valore di output.The following examples demonstrate how to reference a linked template and retrieve an output value. Il modello collegato restituisce un messaggio semplice.The linked template returns a simple message.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {},
    "resources": [],
    "outputs": {
        "greetingMessage": {
            "value": "Hello World",
            "type" : "string"
        }
    }
}

Il modello principale distribuisce il modello collegato e ottiene il valore restituito.The main template deploys the linked template and gets the returned value. Si noti che fa riferimento alla risorsa di distribuzione in base al nome e usa il nome della proprietà restituito dal modello collegato.Notice that it references the deployment resource by name, and it uses the name of the property returned by the linked template.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {},
    "resources": [
        {
            "apiVersion": "2017-05-10",
            "name": "linkedTemplate",
            "type": "Microsoft.Resources/deployments",
            "properties": {
                "mode": "incremental",
                "templateLink": {
                    "uri": "[uri(deployment().properties.templateLink.uri, 'helloworld.json')]",
                    "contentVersion": "1.0.0.0"
                }
            }
        }
    ],
    "outputs": {
        "messageFromLinkedTemplate": {
            "type": "string",
            "value": "[reference('linkedTemplate').outputs.greetingMessage.value]"
        }
    }
}

Come altri tipi di risorse, è possibile impostare le dipendenze tra il modello collegato e altre risorse.Like other resource types, you can set dependencies between the linked template and other resources. Pertanto, quando le altre risorse richiedono un valore di output presente nel modello collegato, accertarsi di distribuire il modello collegato prima di queste risorse.Therefore, when other resources require an output value from the linked template, make sure the linked template is deployed before them. Viceversa, quando il modello collegato dipende da altre risorse, accertarsi di distribuire le altre risorse prima di questo modello.Or, when the linked template relies on other resources, make sure other resources are deployed before the linked template.

L'esempio seguente mostra un modello che distribuisce un indirizzo IP pubblico e restituisce l'ID di risorsa:The following example shows a template that deploys a public IP address and returns the resource ID:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "publicIPAddresses_name": {
            "type": "string"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Network/publicIPAddresses",
            "name": "[parameters('publicIPAddresses_name')]",
            "apiVersion": "2017-06-01",
            "location": "eastus",
            "properties": {
                "publicIPAddressVersion": "IPv4",
                "publicIPAllocationMethod": "Dynamic",
                "idleTimeoutInMinutes": 4
            },
            "dependsOn": []
        }
    ],
    "outputs": {
        "resourceID": {
            "type": "string",
            "value": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddresses_name'))]"
        }
    }
}

Per usare l'indirizzo IP pubblico del modello precedente, quando si distribuisce un servizio di bilanciamento del carico, stabilire un collegamento al modello e aggiungere una dipendenza nella risorsa di distribuzione.To use the public IP address from the preceding template when deploying a load balancer, link to the template and add a dependency on the deployment resource. L'indirizzo IP pubblico nel servizio di bilanciamento del carico è impostato sul valore di output del modello collegato.The public IP address on the load balancer is set to the output value from the linked template.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "loadBalancers_name": {
            "defaultValue": "mylb",
            "type": "string"
        },
        "publicIPAddresses_name": {
            "defaultValue": "myip",
            "type": "string"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Network/loadBalancers",
            "name": "[parameters('loadBalancers_name')]",
            "apiVersion": "2017-06-01",
            "location": "eastus",
            "properties": {
                "frontendIPConfigurations": [
                    {
                        "name": "LoadBalancerFrontEnd",
                        "properties": {
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIPAddress": {
                                "id": "[reference('linkedTemplate').outputs.resourceID.value]"
                            }
                        }
                    }
                ],
                "backendAddressPools": [],
                "loadBalancingRules": [],
                "probes": [],
                "inboundNatRules": [],
                "outboundNatRules": [],
                "inboundNatPools": []
            },
            "dependsOn": [
                "linkedTemplate"
            ]
        },
        {
            "apiVersion": "2017-05-10",
            "name": "linkedTemplate",
            "type": "Microsoft.Resources/deployments",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                    "uri": "[uri(deployment().properties.templateLink.uri, 'publicip.json')]",
                    "contentVersion": "1.0.0.0"
                },
                "parameters":{
                    "publicIPAddresses_name":{"value": "[parameters('publicIPAddresses_name')]"}
                }
            }
        }
    ]
}

Modelli collegati e annidati nella cronologia di distribuzioneLinked and nested templates in deployment history

Resource Manager elabora ogni modello come distribuzione distinta nella cronologia di distribuzione.Resource Manager processes each template as a separate deployment in the deployment history. Un modello principale con tre modelli collegati o annidati viene pertanto visualizzato nella cronologia di distribuzione come segue:Therefore, a main template with three linked or nested templates appears in the deployment history as:

Cronologia di distribuzione

È possibile usare queste voci distinte nella cronologia per recuperare i valori di output dopo la distribuzione.You can use these separate entries in the history to retrieve output values after the deployment. Il modello seguente crea un indirizzo IP pubblico e restituisce l'indirizzo IP:The following template creates a public IP address and outputs the IP address:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "publicIPAddresses_name": {
            "type": "string"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Network/publicIPAddresses",
            "name": "[parameters('publicIPAddresses_name')]",
            "apiVersion": "2017-06-01",
            "location": "southcentralus",
            "properties": {
                "publicIPAddressVersion": "IPv4",
                "publicIPAllocationMethod": "Static",
                "idleTimeoutInMinutes": 4,
                "dnsSettings": {
                    "domainNameLabel": "[concat(parameters('publicIPAddresses_name'), uniqueString(resourceGroup().id))]"
                }
            },
            "dependsOn": []
        }
    ],
    "outputs": {
        "returnedIPAddress": {
            "type": "string",
            "value": "[reference(parameters('publicIPAddresses_name')).ipAddress]"
        }
    }
}

Il modello seguente stabilisce un collegamento al modello precedente.The following template links to the preceding template. Crea tre indirizzi IP pubblici.It creates three public IP addresses.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
    },
    "variables": {},
    "resources": [
        {
            "apiVersion": "2017-05-10",
            "name": "[concat('linkedTemplate', copyIndex())]",
            "type": "Microsoft.Resources/deployments",
            "properties": {
              "mode": "Incremental",
              "templateLink": {
                "uri": "[uri(deployment().properties.templateLink.uri, 'static-public-ip.json')]",
                "contentVersion": "1.0.0.0"
              },
              "parameters":{
                  "publicIPAddresses_name":{"value": "[concat('myip-', copyIndex())]"}
              }
            },
            "copy": {
                "count": 3,
                "name": "ip-loop"
            }
        }
    ]
}

Dopo la distribuzione, è possibile recuperare i valori di output con lo script di PowerShell seguente:After the deployment, you can retrieve the output values with the following PowerShell script:

$loopCount = 3
for ($i = 0; $i -lt $loopCount; $i++)
{
    $name = 'linkedTemplate' + $i;
    $deployment = Get-AzureRmResourceGroupDeployment -ResourceGroupName examplegroup -Name $name
    Write-Output "deployment $($deployment.DeploymentName) returned $($deployment.Outputs.returnedIPAddress.value)"
}

In alternativa, usare lo script dell'interfaccia della riga di comando di Azure:Or, Azure CLI script:

for i in 0 1 2;
do
    name="linkedTemplate$i";
    deployment=$(az group deployment show -g examplegroup -n $name);
    ip=$(echo $deployment | jq .properties.outputs.returnedIPAddress.value);
    echo "deployment $name returned $ip";
done

Protezione di un modello esternoSecuring an external template

Anche se il modello collegato deve essere disponibile esternamente, non è necessario che sia pubblicamente disponibile.Although the linked template must be externally available, it doesn't need to be generally available to the public. È possibile aggiungere il modello a un account di archiviazione privato accessibile solo al proprietario dell'account di archiviazione.You can add your template to a private storage account that is accessible to only the storage account owner. Creare quindi un token di firma di accesso condiviso per consentire l'accesso durante la distribuzione.Then, you create a shared access signature (SAS) token to enable access during deployment. Aggiungere il token con firma di accesso condiviso all'URI del modello collegato.You add that SAS token to the URI for the linked template. Anche se il token viene passato come stringa sicura, l'URI del modello collegato, incluso il token di firma di accesso condiviso, è registrato nelle operazioni di distribuzione.Even though the token is passed in as a secure string, the URI of the linked template, including the SAS token, is logged in the deployment operations. Per limitare l'esposizione, impostare una scadenza per il token.To limit exposure, set an expiration for the token.

È anche possibile limitare l'accesso al file dei parametri solo tramite un token di firma di accesso condiviso.The parameter file can also be limited to access through a SAS token.

L'esempio seguente mostra come passare un token di firma di accesso condiviso quando si stabilisce un collegamento a un modello:The following example shows how to pass a SAS token when linking to a template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "containerSasToken": { "type": "string" }
  },
  "resources": [
    {
      "apiVersion": "2017-05-10",
      "name": "linkedTemplate",
      "type": "Microsoft.Resources/deployments",
      "properties": {
        "mode": "incremental",
        "templateLink": {
          "uri": "[concat(uri(deployment().properties.templateLink.uri, 'helloworld.json'), parameters('containerSasToken'))]",
          "contentVersion": "1.0.0.0"
        }
      }
    }
  ],
  "outputs": {
  }
}

In PowerShell ottenere un token per il contenitore e distribuire i modelli con i comandi seguenti.In PowerShell, you get a token for the container and deploy the templates with the following commands. Si noti che il parametro containerSasToken è definito nel modello.Notice that the containerSasToken parameter is defined in the template. Non è un parametro del comando New-AzureRmResourceGroupDeployment.It isn't a parameter in the New-AzureRmResourceGroupDeployment command.

Set-AzureRmCurrentStorageAccount -ResourceGroupName ManageGroup -Name storagecontosotemplates
$token = New-AzureStorageContainerSASToken -Name templates -Permission r -ExpiryTime (Get-Date).AddMinutes(30.0)
$url = (Get-AzureStorageBlob -Container templates -Blob parent.json).ICloudBlob.uri.AbsoluteUri
New-AzureRmResourceGroupDeployment -ResourceGroupName ExampleGroup -TemplateUri ($url + $token) -containerSasToken $token

Nell'interfaccia della riga di comando di Azure ottenere un token per il contenitore e distribuire i modelli con il codice seguente:In Azure CLI, you get a token for the container and deploy the templates with the following code:

expiretime=$(date -u -d '30 minutes' +%Y-%m-%dT%H:%MZ)
connection=$(az storage account show-connection-string \
    --resource-group ManageGroup \
    --name storagecontosotemplates \
    --query connectionString)
token=$(az storage container generate-sas \
    --name templates \
    --expiry $expiretime \
    --permissions r \
    --output tsv \
    --connection-string $connection)
url=$(az storage blob url \
    --container-name templates \
    --name parent.json \
    --output tsv \
    --connection-string $connection)
parameter='{"containerSasToken":{"value":"?'$token'"}}'
az group deployment create --resource-group ExampleGroup --template-uri $url?$token --parameters $parameter

Modelli di esempioExample templates

Gli esempi seguenti mostrano gli usi più frequenti dei modelli collegati.The following examples show common uses of linked templates.

Modello principaleMain template Modello collegatoLinked template DESCRIZIONEDescription
Hello WorldHello World Modello collegatolinked template Restituisce una stringa dal modello collegato.Returns string from linked template.
Load Balancer con indirizzo IP pubblicoLoad Balancer with public IP address Modello collegatolinked template Restituisce l'indirizzo IP pubblico dal modello collegato e imposta tale valore nel servizio di bilanciamento del carico.Returns public IP address from linked template and sets that value in load balancer.
Indirizzi IP multipliMultiple IP addresses Modello collegatolinked template Crea diversi indirizzi IP pubblici nel modello collegato.Creates several public IP addresses in linked template.

Passaggi successiviNext steps