Uso di modelli collegati e annidati durante la distribuzione di risorse di Azure

Per distribuire soluzioni complesse, è possibile suddividere il modello di Azure Resource Manager (modello di ARM) in molti modelli correlati e quindi distribuirli insieme tramite un modello principale. I modelli correlati possono essere file separati o sintassi dei modelli incorporati all'interno del modello principale. Questo articolo usa il termine modello collegato per fare riferimento a un file di modello separato a cui viene fatto riferimento tramite un collegamento del modello principale. Usa il termine modello annidato per fare riferimento alla sintassi del modello incorporato all'interno del modello principale.

Per le soluzioni di piccole e medie dimensioni, un singolo modello è più facile da comprendere e gestire. È possibile visualizzare tutte le risorse e i valori in un singolo file. Per gli scenari avanzati, i modelli collegati consentono di suddividere la soluzione in componenti mirati. È possibile riutilizzare facilmente questi modelli per altri scenari.

Per un'esercitazione, vedere Esercitazione: Distribuire un modello collegato.

Nota

Per i modelli collegati o annidati, è possibile impostare solo la modalità di distribuzione su Incrementale. Tuttavia, il modello principale può essere distribuito in modalità completa. Se si distribuisce il modello principale in modalità completa e il modello collegato o annidato è destinato allo stesso gruppo di risorse, le risorse distribuite nel modello collegato o annidato vengono incluse nella valutazione per la distribuzione in modalità completa. La raccolta combinata di risorse distribuite nel modello principale e nei modelli collegati o annidati viene confrontata con le risorse esistenti nel gruppo di risorse. Tutte le risorse non incluse in questa raccolta combinata vengono eliminate.

Se il modello collegato o annidato è destinato a un gruppo di risorse diverso, la distribuzione usa la modalità incrementale.

Modello annidato

Per annidare un modello, aggiungere una risorsa di distribuzione al modello principale. Nella proprietà template specificare la sintassi del modello.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedTemplate1",
      "properties": {
        "mode": "Incremental",
        "template": {
          <nested-template-syntax>
        }
      }
    }
  ],
  "outputs": {
  }
}

L'esempio seguente distribuisce un account di archiviazione tramite un modello annidato.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageAccountName": {
      "type": "string"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedTemplate1",
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "type": "Microsoft.Storage/storageAccounts",
              "apiVersion": "2021-04-01",
              "name": "[parameters('storageAccountName')]",
              "location": "West US",
              "sku": {
                "name": "Standard_LRS"
              },
              "kind": "StorageV2"
            }
          ]
        }
      }
    }
  ],
  "outputs": {
  }
}

Ambito di valutazione delle espressioni nei modelli annidati

Quando si usa un modello annidato, è possibile specificare se le espressioni di modello vengono valutate nell'ambito del modello padre o del modello annidato. L'ambito determina la modalità di risoluzione di parametri, variabili e funzioni come resourceGroupe subscription.

Impostare l'ambito tramite la expressionEvaluationOptions proprietà. Per impostazione predefinita, expressionEvaluationOptions la proprietà è impostata su , il outer che significa che usa l'ambito del modello padre. Impostare il valore su inner per fare in modo che le espressioni siano valutate nell'ambito del modello annidato.

{
  "type": "Microsoft.Resources/deployments",
  "apiVersion": "2021-04-01",
  "name": "nestedTemplate1",
  "properties": {
    "expressionEvaluationOptions": {
      "scope": "inner"
    },
  ...

Nota

Quando l'ambito è impostato su , non è possibile usare la funzione nella sezione output di un modello annidato per una risorsa distribuita outerreference nel modello annidato. Per restituire i valori di una risorsa distribuita in un modello annidato, usare l'ambito o convertire il modello inner annidato in un modello collegato.

Il modello seguente mostra come le espressioni di modello vengono risolte in base all'ambito. Contiene una variabile denominata definita sia nel modello padre che exampleVar nel modello annidato. Restituisce il valore della variabile.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
  },
  "variables": {
    "exampleVar": "from parent template"
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "nestedTemplate1",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "variables": {
            "exampleVar": "from nested template"
          },
          "resources": [
          ],
          "outputs": {
            "testVar": {
              "type": "string",
              "value": "[variables('exampleVar')]"
            }
          }
        }
      }
    }
  ],
  "outputs": {
    "messageFromLinkedTemplate": {
      "type": "string",
      "value": "[reference('nestedTemplate1').outputs.testVar.value]"
    }
  }
}

Il valore di exampleVar cambia a seconda del valore della proprietà in scopeexpressionEvaluationOptions . La tabella seguente mostra i risultati per entrambi gli ambiti.

Ambito di valutazione Output
interno da modello annidato
esterno (o predefinito) da modello padre

L'esempio seguente distribuisce un server SQL chiave e recupera un segreto del vault delle chiavi da usare per la password. L'ambito è impostato su perché crea dinamicamente l'ID del vault delle chiavi (vedere i modelli esterni) e lo passa come parametro inneradminPassword.reference.keyVault al modello parameters annidato.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "The location where the resources will be deployed."
      }
    },
    "vaultName": {
      "type": "string",
      "metadata": {
        "description": "The name of the keyvault that contains the secret."
      }
    },
    "secretName": {
      "type": "string",
      "metadata": {
        "description": "The name of the secret."
      }
    },
    "vaultResourceGroupName": {
      "type": "string",
      "metadata": {
        "description": "The name of the resource group that contains the keyvault."
      }
    },
    "vaultSubscription": {
      "type": "string",
      "defaultValue": "[subscription().subscriptionId]",
      "metadata": {
        "description": "The name of the subscription that contains the keyvault."
      }
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "dynamicSecret",
      "properties": {
        "mode": "Incremental",
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "parameters": {
          "location": {
            "value": "[parameters('location')]"
          },
          "adminLogin": {
            "value": "ghuser"
          },
          "adminPassword": {
            "reference": {
              "keyVault": {
                "id": "[resourceId(parameters('vaultSubscription'), parameters('vaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]"
              },
              "secretName": "[parameters('secretName')]"
            }
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {
            "adminLogin": {
              "type": "string"
            },
            "adminPassword": {
              "type": "securestring"
            },
            "location": {
              "type": "string"
            }
          },
          "variables": {
            "sqlServerName": "[concat('sql-', uniqueString(resourceGroup().id, 'sql'))]"
          },
          "resources": [
            {
              "type": "Microsoft.Sql/servers",
              "apiVersion": "2021-02-01-preview",
              "name": "[variables('sqlServerName')]",
              "location": "[parameters('location')]",
              "properties": {
                "administratorLogin": "[parameters('adminLogin')]",
                "administratorLoginPassword": "[parameters('adminPassword')]"
              }
            }
          ],
          "outputs": {
            "sqlFQDN": {
              "type": "string",
              "value": "[reference(variables('sqlServerName')).fullyQualifiedDomainName]"
            }
          }
        }
      }
    }
  ],
  "outputs": {
  }
}

Prestare attenzione quando si usano valori di parametro sicuri in un modello annidato. Se si imposta l'ambito su outer, i valori sicuri vengono archiviati come testo normale nella cronologia della distribuzione. Un utente che visualizza il modello nella cronologia di distribuzione potrebbe visualizzare i valori sicuri. Usare invece l'ambito interno o aggiungere al modello padre le risorse che necessitano di valori sicuri.

L'estratto seguente mostra quali valori sono sicuri e quali non sono sicuri.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Username for the Virtual Machine."
      }
    },
    "adminPasswordOrKey": {
      "type": "securestring",
      "metadata": {
        "description": "SSH Key or password for the Virtual Machine. SSH key is recommended."
      }
    }
  },
  ...
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2021-04-01",
      "name": "mainTemplate",
      "properties": {
        ...
        "osProfile": {
          "computerName": "mainTemplate",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPasswordOrKey')]" // Yes, secure because resource is in parent template
        }
      }
    },
    {
      "name": "outer",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "outer"
        },
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "resources": [
            {
              "type": "Microsoft.Compute/virtualMachines",
              "apiVersion": "2021-04-01",
              "name": "outer",
              "properties": {
                ...
                "osProfile": {
                  "computerName": "outer",
                  "adminUsername": "[parameters('adminUsername')]",
                  "adminPassword": "[parameters('adminPasswordOrKey')]" // No, not secure because resource is in nested template with outer scope
                }
              }
            }
          ]
        }
      }
    },
    {
      "name": "inner",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
        "mode": "Incremental",
        "parameters": {
          "adminPasswordOrKey": {
              "value": "[parameters('adminPasswordOrKey')]"
          },
          "adminUsername": {
              "value": "[parameters('adminUsername')]"
          }
        },
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {
            "adminUsername": {
              "type": "string",
              "metadata": {
                "description": "Username for the Virtual Machine."
              }
            },
            "adminPasswordOrKey": {
              "type": "securestring",
              "metadata": {
                "description": "SSH Key or password for the Virtual Machine. SSH key is recommended."
              }
            }
          },
          "resources": [
            {
              "type": "Microsoft.Compute/virtualMachines",
              "apiVersion": "2021-04-01",
              "name": "inner",
              "properties": {
                ...
                "osProfile": {
                  "computerName": "inner",
                  "adminUsername": "[parameters('adminUsername')]",
                  "adminPassword": "[parameters('adminPasswordOrKey')]" // Yes, secure because resource is in nested template and scope is inner
                }
              }
            }
          ]
        }
      }
    }
  ]
}

Modello collegato

Per collegare un modello, aggiungere una risorsa distribuzioni al modello principale. Nella proprietà templateLink specificare l'URI del modello da includere. L'esempio seguente è un collegamento a un modello in un account di archiviazione.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "linkedTemplate",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
          "contentVersion":"1.0.0.0"
        }
      }
    }
  ],
  "outputs": {
  }
}

Quando si fa riferimento a un modello collegato, il valore di non può essere un file locale o un file disponibile solo uri nella rete locale. Azure Resource Manager deve essere in grado di accedere al modello. Specificare un valore URI scaricabile come HTTP o HTTPS.

È possibile fare riferimento ai modelli usando parametri che includono HTTP o HTTPS. Ad esempio, un criterio comune è usare il _artifactsLocation parametro. È possibile impostare il modello collegato con un'espressione come:

"uri": "[concat(parameters('_artifactsLocation'), '/shared/os-disk-parts-md.json', parameters('_artifactsLocationSasToken'))]"

Se si sta collegando un modello in GitHub, usare l'URL non elaborato. Il collegamento ha il formato: https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-with-templates/quickstart-template/azuredeploy.json . Per ottenere il collegamento non elaborato, selezionare Non elaborato.

Select raw URL

Nota

Per distribuire un modello o fare riferimento a un modello collegato archiviato in un GitHub privato, vedere una soluzione personalizzata documentata in un blog di MVP. È possibile configurare una funzione di Azure come proxy per creare l'URL necessario per accedere a un file di modello in un GitHub privato.

Parametri per il modello collegato

È possibile specificare i parametri per il modello collegato in un file esterno o in linea. Quando si fornisce un file di parametri esterni, usare la parametersLink proprietà:

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2021-04-01",
    "name": "linkedTemplate",
    "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"
      }
    }
  }
]

Per passare i valori dei parametri inline, usare la parameters proprietà .

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2021-04-01",
    "name": "linkedTemplate",
    "properties": {
      "mode": "Incremental",
      "templateLink": {
        "uri": "https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
        "contentVersion": "1.0.0.0"
      },
      "parameters": {
        "storageAccountName": {
          "value": "[parameters('storageAccountName')]"
        }
      }
    }
  }
]

Non è possibile usare sia i parametri inline che un collegamento a un file di parametri. La distribuzione non riesce con un errore quando vengono specificati entrambi parametersLinkparameters e .

Usare il percorso relativo per i modelli collegati

La relativePath proprietà di semplifica la creazione di modelli Microsoft.Resources/deployments collegati. Questa proprietà può essere usata per distribuire un modello collegato remoto in una posizione relativa all'elemento padre. Questa caratteristica richiede che tutti i file di modello siano a fasi e siano disponibili in un URI remoto, ad esempio un GitHub o un account di archiviazione di Azure. Quando il modello principale viene chiamato usando un URI di Azure PowerShell o dell'interfaccia della riga di comando di Azure, l'URI di distribuzione figlio è una combinazione del percorso padre e relativo.

Nota

Quando si crea un templateSpec, tutti i modelli a cui fa riferimento la proprietà vengono confezionati nella risorsa templateSpec da Azure PowerShell o dall'interfaccia della riga di relativePath comando di Azure. Non è necessario che i file siano a fasi. Per altre informazioni, vedere Creare una specifica di modello con modelli collegati.

Si supponga di avere una struttura di cartelle simile alla seguente:

resource manager linked template relative path

Il modello seguente mostra come mainTemplate.json distribuisce nestedChild.json illustrato nell'immagine precedente.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "functions": [],
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "childLinked",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "relativePath": "children/nestedChild.json"
        }
      }
    }
  ],
  "outputs": {}
}

Nella distribuzione seguente l'URI del modello collegato nel modello precedente è https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/linked-template-relpath/children/nestedChild.json .

New-AzResourceGroupDeployment `
  -Name linkedTemplateWithRelativePath `
  -ResourceGroupName "myResourceGroup" `
  -TemplateUri "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/linked-template-relpath/mainTemplate.json"

Per distribuire modelli collegati con percorso relativo archiviato in un account di archiviazione di Azure, usare il parametro per specificare il token di firma di accesso condiviso da QueryString/query-string usare con il parametro TemplateUri. Questo parametro è supportato solo da Azure CLI versione 2.18 o successiva e Azure PowerShell versione 5.4 o successiva.

New-AzResourceGroupDeployment `
  -Name linkedTemplateWithRelativePath `
  -ResourceGroupName "myResourceGroup" `
  -TemplateUri "https://stage20210126.blob.core.windows.net/template-staging/mainTemplate.json" `
  -QueryString $sasToken

Assicurarsi che non sia presente alcun "?" iniziale in QueryString. La distribuzione ne aggiunge uno quando si assembla l'URI per le distribuzioni.

Specifiche dei modelli

Invece di mantenere i modelli collegati in un endpoint accessibile, è possibile creare una specifica di modello che consente di creare un pacchetto del modello principale e dei modelli collegati in una singola entità che è possibile distribuire. La specifica del modello è una risorsa nella sottoscrizione di Azure. Semplifica la condivisione sicura del modello con gli utenti dell'organizzazione. Usare il controllo dell'accesso basato sui ruoli di Azure per concedere l'accesso alla specifica del modello. Questa funzionalità è attualmente in anteprima.

Per altre informazioni, vedere:

Dipendenze

Come per altri tipi di risorse, è possibile impostare le dipendenze tra i modelli annidati/collegati. Se le risorse in un modello annidato/collegato devono essere distribuite prima delle risorse in un secondo modello annidato/collegato, impostare il secondo modello dipendente dal primo.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "linkedTemplate1",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[uri(deployment().properties.templateLink.uri, 'firstresources.json')]",
          "contentVersion": "1.0.0.0"
        }
      }
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "linkedTemplate2",
      "dependsOn": [
        "[resourceId('Microsoft.Resources/deployments', 'linkedTemplate1')]"
      ],
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[uri(deployment().properties.templateLink.uri, 'secondresources.json')]",
          "contentVersion": "1.0.0.0"
        }
      }
    }
  ]
}

contentVersion

Non è necessario fornire la proprietà contentVersion per la proprietà o templateLinkparametersLink . Se non si specifica , viene distribuita la contentVersion versione corrente del modello. Se si specifica un valore per la versione del contenuto, deve corrispondere alla versione nel modello collegato. in caso contrario, la distribuzione non riesce con un errore.

Gli esempi precedenti mostravano valori URL hard-coded per i collegamenti ai modelli. Questo approccio potrebbe funzionare per un modello semplice, ma non funziona bene per un set di modelli modulari di grandi dimensioni. È invece possibile creare una variabile statica che archivia un URL di base per il modello principale e quindi creare dinamicamente URL per i modelli collegati da tale URL di base. Il vantaggio di questo approccio è che è possibile spostare o fork facilmente il modello perché è necessario modificare solo la variabile statica nel modello principale. Il modello principale passa gli URI corretti in tutto il modello scomposto.

L'esempio seguente mostra come usare un URL di base per creare due URL per i modelli collegati ( sharedTemplateUrl e vmTemplateUrl ).

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

È anche possibile usare deployment() per ottenere l'URL di base per il modello corrente e usarlo per ottenere l'URL di altri modelli nella stessa posizione. Questo approccio è utile se il percorso del modello cambia o se si vogliono evitare URL hard coding nel file modello. La templateLink proprietà viene restituita solo quando si esegue il collegamento a un modello remoto con un URL. Se si usa un modello locale, questa proprietà non è disponibile.

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

In definitiva, si userebbe la variabile nella uri proprietà di una templateLink proprietà.

"templateLink": {
 "uri": "[variables('sharedTemplateUrl')]",
 "contentVersion":"1.0.0.0"
}

Uso della copia

Per creare più istanze di una risorsa con un modello annidato, aggiungere copy l'elemento a livello della Microsoft.Resources/deployments risorsa. In caso contrario, se l'ambito inner è , è possibile aggiungere la copia all'interno del modello annidato.

Il modello di esempio seguente mostra come usare copy un modello annidato.

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2021-04-01",
    "name": "[concat('nestedTemplate', copyIndex())]",
    // yes, copy works here
    "copy": {
      "name": "storagecopy",
      "count": 2
    },
    "properties": {
      "mode": "Incremental",
      "expressionEvaluationOptions": {
        "scope": "inner"
      },
      "template": {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "resources": [
          {
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2021-04-01",
            "name": "[concat(variables('storageName'), copyIndex())]",
            "location": "West US",
            "sku": {
              "name": "Standard_LRS"
            },
            "kind": "StorageV2"
            // Copy works here when scope is inner
            // But, when scope is default or outer, you get an error
            // "copy": {
            //   "name": "storagecopy",
            //   "count": 2
            // }
          }
        ]
      }
    }
  }
]

Ottenere valori dal modello collegato

Per ottenere un valore di output da un modello collegato, recuperare il valore della proprietà con la sintassi seguente: "[reference('deploymentName').outputs.propertyName.value]" .

Quando si riceve una proprietà di output da un modello collegato, il nome della proprietà non deve includere un trattino.

Gli esempi seguenti illustrano come fare riferimento a un modello collegato e recuperare un valore di output. Il modello collegato restituisce un messaggio semplice. Prima di tutto, il modello collegato:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-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. Si noti che fa riferimento alla risorsa di distribuzione in base al nome e usa il nome della proprietà restituita dal modello collegato.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {},
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "linkedTemplate",
      "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]"
    }
  }
}

L'esempio seguente mostra un modello che distribuisce un indirizzo IP pubblico e restituisce l'ID risorsa della risorsa di Azure per tale indirizzo IP pubblico:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "publicIPAddresses_name": {
      "type": "string"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2021-02-01",
      "name": "[parameters('publicIPAddresses_name')]",
      "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 durante la distribuzione di un servizio di bilanciamento del carico, creare un collegamento al modello e dichiarare una dipendenza dalla Microsoft.Resources/deployments risorsa. L'indirizzo IP pubblico nel servizio di bilanciamento del carico è impostato sul valore di output del modello collegato.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-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",
      "apiVersion": "2021-02-01",
      "name": "[parameters('loadBalancers_name')]",
      "location": "eastus",
      "properties": {
        "frontendIPConfigurations": [
          {
            "name": "LoadBalancerFrontEnd",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[reference('linkedTemplate').outputs.resourceID.value]"
              }
            }
          }
        ],
        "backendAddressPools": [],
        "loadBalancingRules": [],
        "probes": [],
        "inboundNatRules": [],
        "outboundNatRules": [],
        "inboundNatPools": []
      },
      "dependsOn": [
        "[resourceId('Microsoft.Resources/deployments', 'linkedTemplate')]"
      ]
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "linkedTemplate",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[uri(deployment().properties.templateLink.uri, 'public-ip.json')]",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "publicIPAddresses_name": { "value": "[parameters('publicIPAddresses_name')]" }
        }
      }
    }
  ]
}

Cronologia distribuzione

Gestione risorse elabora ogni modello come distribuzione separata nella cronologia di distribuzione. Un modello principale con tre modelli collegati o annidati viene visualizzato nella cronologia della distribuzione come:

Deployment history

È possibile usare queste voci distinte nella cronologia per recuperare i valori di output dopo la distribuzione. Il modello seguente crea un indirizzo IP pubblico e restituisce l'indirizzo IP:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "publicIPAddresses_name": {
      "type": "string"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2021-02-01",
      "name": "[parameters('publicIPAddresses_name')]",
      "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 è un collegamento al modello precedente. Crea tre indirizzi IP pubblici.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "[concat('linkedTemplate', copyIndex())]",
      "copy": {
        "count": 3,
        "name": "ip-loop"
      },
      "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())]"}
        }
      }
    }
  ]
}

Dopo la distribuzione, è possibile recuperare i valori di output con lo script di PowerShell seguente:

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

Oppure, script dell'interfaccia della riga di comando di Azure in una shell Bash:

#!/bin/bash

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

Protezione di un modello esterno

Anche se il modello collegato deve essere disponibile esternamente, non deve essere in genere disponibile per il pubblico. È possibile aggiungere il modello a un account di archiviazione privato accessibile solo al proprietario dell'account di archiviazione. Creare quindi un token di firma di accesso condiviso per abilitare l'accesso durante la distribuzione. Aggiungere il token di firma di accesso condiviso all'URI per il modello collegato. Anche se il token viene passato come stringa sicura, l'URI del modello collegato, incluso il token di firma di accesso condiviso, viene registrato nelle operazioni di distribuzione. Per limitare l'esposizione, impostare una scadenza per il token.

Il file dei parametri può anche essere limitato all'accesso tramite un token di firma di accesso condiviso.

Attualmente non è possibile creare un collegamento a un modello in un account di archiviazione dietro un firewall Archiviazione di Azure sicurezza.

Importante

Invece di proteggere il modello collegato con un token di firma di accesso condiviso, è consigliabile creare una specifica del modello. La specifica del modello archivia in modo sicuro il modello principale e i relativi modelli collegati come risorsa nella sottoscrizione di Azure. Usare il controllo degli accessi in base al ruolo di Azure per concedere l'accesso agli utenti che devono distribuire il modello.

L'esempio seguente mostra come passare un token di firma di accesso condiviso durante il collegamento a un modello:

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

In PowerShell si ottiene un token per il contenitore e si distribuiscono i modelli con i comandi seguenti. Si noti containerSasToken che il parametro è definito nel modello. Non è un parametro nel New-AzResourceGroupDeployment comando.

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

Per l'interfaccia della riga di comando di Azure in una shell Bash, si ottiene un token per il contenitore e si distribuiscono i modelli con il codice seguente:

#!/bin/bash

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 deployment group create --resource-group ExampleGroup --template-uri $url?$token --parameters $parameter

Modelli di esempio

Gli esempi seguenti mostrano gli usi comuni dei modelli collegati.

Modello principale Modello collegato Descrizione
Salve, mondo modello collegato Restituisce una stringa dal modello collegato.
Bilanciamento del carico con indirizzo IP pubblico modello collegato Restituisce l'indirizzo IP pubblico dal modello collegato e imposta tale valore nel servizio di bilanciamento del carico.
Più indirizzi IP modello collegato Crea diversi indirizzi IP pubblici nel modello collegato.

Passaggi successivi

  • Per un'esercitazione, vedere Esercitazione: Distribuire un modello collegato.
  • Per informazioni sulla definizione dell'ordine di distribuzione per le risorse, vedere Definire l'ordine di distribuzione delle risorse nei modelli ARM distribuzione.
  • Per informazioni su come definire una risorsa ma crearne molte istanze, vedere Iterazione delle risorse nei modelli ARM risorse.
  • Per istruzioni sulla configurazione di un modello in un account di archiviazione e sulla generazione di un token di firma di accesso condiviso, vedere Distribuire risorse con modelli di ARM e Azure PowerShell o Distribuire risorse con modelli di ARM e l'interfaccia della riga di comando di Azure.