Uso di modelli collegati nella distribuzione di risorse di AzureUsing linked templates when deploying Azure resources

Per distribuire una soluzione, è possibile usare un modello singolo o un modello principale con più modelli collegati.To deploy your solution, you can use either a single template or a main template with multiple linked templates. 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 singolo file.You are able to 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.

Modelli collegati

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",
          <inline-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 incorporando 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 embedding an inline template in the main template.

Modello inlineInline template

Per incorporare il modello collegato, usare la proprietà template e includere il modello.To embed the linked template, use the template property and include the template.

"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",
        "parameters": {},
        "variables": {},
        "resources": [
          {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageName')]",
            "apiVersion": "2015-06-15",
            "location": "West US",
            "properties": {
              "accountType": "Standard_LRS"
            }
          }
        ]
      },
      "parameters": {}
    }
  }
]

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

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 potrebbe funzionare per un modello semplice ma non funziona correttamente in caso di uso di un ampio set di modelli modulari.This approach might work for a simple template but it does not 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, ad esempio a causa del controllo delle versioni, o si vuole evitare la codifica di URL nel file del modello.This approach is useful if your template location changes (maybe due to versioning) or you want to avoid hard coding URLs in the template file.

"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 padre distribuisce il modello collegato e ottiene il valore restituito.The parent 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, è possibile accertarsi di distribuire il modello collegato prima di queste risorse.Therefore, when other resources require an output value from the linked template, you can make sure the linked template is deployed before them. Viceversa, quando il modello collegato dipende da altre risorse, è possibile accertarsi di distribuire le altre risorse prima di questo modello.Or, when the linked template relies on other resources, you can 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 nella cronologia di distribuzioneLinked templates in deployment history

Resource Manager elabora ogni modello collegato come distribuzione distinta nella cronologia di distribuzione.Resource Manager processes each linked template as a separate deployment in the deployment history. Un modello padre con tre modelli collegati viene quindi visualizzato nella cronologia di distribuzione come segue:Therefore, a parent template with three linked 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 does not 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": {
  }
}

Nella PowerShell, ottenere un token per il contenitore e distribuire i modelli con:In PowerShell, you get a token for the container and deploy the templates with:

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

Hello World dal modello collegatoHello World from linked template

Per distribuire il modello padre e il modello collegato, usare PowerShell:To deploy the parent template and linked template, use PowerShell:

New-AzureRmResourceGroupDeployment `
  -ResourceGroupName examplegroup `
  -TemplateUri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/helloworldparent.json

Oppure l'interfaccia della riga di comando di Azure:Or, Azure CLI:

az group deployment create \
  -g examplegroup \
  --template-uri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/helloworldparent.json

Load Balancer con indirizzo IP pubblico nel modello collegatoLoad Balancer with public IP address in linked template

Per distribuire il modello padre e il modello collegato, usare PowerShell:To deploy the parent template and linked template, use PowerShell:

New-AzureRmResourceGroupDeployment `
  -ResourceGroupName examplegroup `
  -TemplateUri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/linkedtemplates/public-ip-parentloadbalancer.json

Oppure l'interfaccia della riga di comando di Azure:Or, Azure CLI:

az group deployment create \
  -g examplegroup \
  --template-uri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/linkedtemplates/public-ip-parentloadbalancer.json

Più indirizzi IP pubblici nel modello collegatoMultiple public IP addresses in linked template

Per distribuire il modello padre e il modello collegato, usare PowerShell:To deploy the parent template and linked template, use PowerShell:

New-AzureRmResourceGroupDeployment `
  -ResourceGroupName examplegroup `
  -TemplateUri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/linkedtemplates/static-public-ip-parent.json

Oppure l'interfaccia della riga di comando di Azure:Or, Azure CLI:

az group deployment create \
  -g examplegroup \
  --template-uri https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/linkedtemplates/static-public-ip-parent.json

Passaggi successiviNext steps