Använda länkade och nästlade mallar vid distribution av Azure-resurser

Om du vill distribuera komplexa lösningar kan du dela upp din Azure Resource Manager-mall (ARM-mall) i många relaterade mallar och sedan distribuera dem tillsammans via en huvudmall. De relaterade mallarna kan vara separata filer eller mallsyntaxer som är inbäddade i huvudmallen. Den här artikeln använder termen länkad mall för att referera till en separat mallfil som refereras via en länk från huvudmallen. Den använder termen kapslad mall för att referera till inbäddad mallsyntax i huvudmallen.

För små till medelstora lösningar är en enskild mall enklare att förstå och underhålla. Du kan se alla resurser och värden i en enda fil. I avancerade scenarier kan du använda länkade mallar till att dela upp lösningen i riktade komponenter. Du kan enkelt återanvända dessa mallar för andra scenarier.

En självstudiekurs finns i Självstudie: Distribuera en länkad mall.

Kommentar

För länkade eller kapslade mallar kan du bara ange distributionsläget till Inkrementellt. Huvudmallen kan dock distribueras i fullständigt läge. Om du distribuerar huvudmallen i fullständigt läge och den länkade eller kapslade mallen riktar sig mot samma resursgrupp, inkluderas de resurser som distribueras i den länkade eller kapslade mallen i utvärderingen för distribution i fullständigt läge. Den kombinerade samlingen med resurser som distribueras i huvudmallen och länkade eller kapslade mallar jämförs med de befintliga resurserna i resursgruppen. Alla resurser som inte ingår i den här kombinerade samlingen tas bort.

Om den länkade eller kapslade mallen riktar sig mot en annan resursgrupp använder distributionen inkrementellt läge. Mer information finns i Distributionsomfång.

Dricks

Vi rekommenderar Bicep eftersom det erbjuder samma funktioner som ARM-mallar och syntaxen är enklare att använda. Mer information finns i moduler.

Kapslad mall

Om du vill kapsla en mall lägger du till en distributionsresurs i huvudmallen. I egenskapen template anger du mallsyntaxen.

{
  "$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": "2022-09-01",
      "name": "nestedTemplate1",
      "properties": {
        "mode": "Incremental",
        "template": {
          <nested-template-syntax>
        }
      }
    }
  ]
}

I följande exempel distribueras ett lagringskonto via en kapslad mall.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageAccountName": {
      "type": "string",
      "defaultValue": "[format('{0}{1}', 'store', uniqueString(resourceGroup().id))]"
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-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": "2022-09-01",
              "name": "[parameters('storageAccountName')]",
              "location": "[parameters('location')]",
              "sku": {
                "name": "Standard_LRS"
              },
              "kind": "StorageV2"
            }
          ]
        }
      }
    }
  ]
}

Kapslade resurser kan inte användas i en symbolisk namnmall . I följande mall kan den kapslade lagringskontoresursen inte använda symboliskt namn:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "languageVersion": "2.0",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageAccountName": {
      "type": "string",
      "defaultValue": "[format('{0}{1}', 'storage', uniqueString(resourceGroup().id))]"

    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "resources": {
    "mainStorage": {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2022-09-01",
      "name": "[parameters('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard_LRS"
      },
      "kind": "StorageV2"
    },
    "nestedResource": {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-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": "2022-09-01",
              "name": "[format('{0}nested', parameters('storageAccountName'))]",
              "location": "[parameters('location')]",
              "sku": {
                "name": "Standard_LRS"
              },
              "kind": "StorageV2"
            }
          ]
        }
      }
    }
  }
}

Utvärderingsomfång för uttryck i kapslade mallar

Om du använder en kapslad mall kan du ange om malluttryck ska utvärderas inom omfånget för den överordnade mallen eller den kapslade mallen. Omfånget avgör hur parametrar, variabler och funktioner som resourceGroup och prenumeration löses.

Du anger omfånget via egenskapen expressionEvaluationOptions . Som standard expressionEvaluationOptions är egenskapen inställd på , vilket innebär att outerden använder det överordnade mallomfånget. Ange värdet till inner för att göra så att uttryck utvärderas inom omfånget för den kapslade mallen.

Viktigt!

För languageVersion 2.0är innerstandardvärdet för expressionEvaluationOptions egenskapen . Värdet outer blockeras.

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

Kommentar

När omfånget är inställt på outerkan du inte använda reference funktionen i utdataavsnittet i en kapslad mall för en resurs som du har distribuerat i den kapslade mallen. Om du vill returnera värdena för en distribuerad resurs i en kapslad mall använder inner du antingen omfång eller konverterar din kapslade mall till en länkad mall.

Följande mall visar hur malluttryck matchas enligt omfånget. Den innehåller en variabel med namnet exampleVar som definieras i både den överordnade mallen och den kapslade mallen. Den returnerar värdet för variabeln.

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

Värdet för exampleVar ändringar beroende på värdet för scope egenskapen i expressionEvaluationOptions. I följande tabell visas resultatet för båda omfången.

Utvärderingsomfång Output
Inre från kapslad mall
yttre (eller standard) från en överordnad mall

Följande exempel distribuerar en SQL-server och hämtar en nyckelvalvshemlighet som ska användas för lösenordet. Omfånget är inställt inner på eftersom det dynamiskt skapar nyckelvalvs-ID :t (se adminPassword.reference.keyVault i de yttre mallarna parameters) och skickar det som en parameter till den kapslade mallen.

{
  "$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": "2022-09-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": "[format('sql-{0}sql', uniqueString(resourceGroup().id, 'sql'))]"
          },
          "resources": [
            {
              "type": "Microsoft.Sql/servers",
              "apiVersion": "2022-05-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": {
  }
}

Var försiktig när du använder säkra parametervärden i en kapslad mall. Om du anger omfånget till yttre lagras de säkra värdena som oformaterad text i distributionshistoriken. En användare som visar mallen i distributionshistoriken kan se de säkra värdena. Använd i stället det inre omfånget eller lägg till de resurser som behöver säkra värden i den överordnade mallen.

Följande utdrag visar vilka värden som är säkra och som inte är säkra.

{
  "$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": "2023-03-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": "2022-09-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": "2023-03-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": "2022-09-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": "2023-03-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
                }
              }
            }
          ]
        }
      }
    }
  ]
}

Länkad mall

Om du vill länka en mall lägger du till en distributionsresurs i huvudmallen. I egenskapen templateLink anger du den URI för mallen som ska inkluderas. Följande exempel länkar till en mall som finns i ett lagringskonto.

{
  "$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": "2022-09-01",
      "name": "linkedTemplate",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
          "contentVersion":"1.0.0.0"
        }
      }
    }
  ],
  "outputs": {
  }
}

När du refererar till en länkad mall kan värdet uri för inte vara en lokal fil eller en fil som bara är tillgänglig i det lokala nätverket. Azure Resource Manager måste kunna komma åt mallen. Ange ett URI-värde som kan laddas ned som HTTP eller HTTPS.

Du kan referera till mallar med parametrar som innehåller HTTP eller HTTPS. Ett vanligt mönster är till exempel att använda parametern _artifactsLocation . Du kan ange den länkade mallen med ett uttryck som:

"uri": "[format('{0}/shared/os-disk-parts-md.json{1}', parameters('_artifactsLocation'), parameters('_artifactsLocationSasToken'))]"

Om du länkar till en mall i GitHub använder du den råa URL:en. Länken har formatet : https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-with-templates/quickstart-template/azuredeploy.json. Om du vill hämta raw-länken väljer du Raw.

Screenshot of selecting raw URL in GitHub.

Kommentar

Om du vill distribuera en mall eller referera till en länkad mall som lagras i en privat GitHub-lagringsplats kan du läsa en anpassad lösning som beskrivs i Skapa ett anpassat och säkert Azure Portal-erbjudande. Du kan skapa en Azure-funktion som hämtar GitHub-token från Azure Key Vault.

För länkade mallar kan du kapsla en distribution som inte är symboliskt namn i en mall med symboliskt namn, eller kapsla en symbolisk namndistribution i en icke-symbolisk mall eller kapsla en distribution med symboliskt namn i en annan mall för symboliskt namn, eller tvärtom.

Parametrar för länkad mall

Du kan ange parametrarna för den länkade mallen antingen i en extern fil eller infogad. När du tillhandahåller en extern parameterfil använder du egenskapen parametersLink :

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2022-09-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"
      }
    }
  }
]

Om du vill skicka parametervärden infogade använder du egenskapen parameters .

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2022-09-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')]"
        }
      }
    }
  }
]

Du kan inte använda både infogade parametrar och en länk till en parameterfil. Distributionen misslyckas med ett fel när båda parametersLink och parameters anges.

Använda relativ sökväg för länkade mallar

Egenskapen relativePathMicrosoft.Resources/deployments för gör det enklare att skapa länkade mallar. Den här egenskapen kan användas för att distribuera en fjärransluten mall på en plats i förhållande till den överordnade. Den här funktionen kräver att alla mallfiler mellanlagras och är tillgängliga på en fjärr-URI, till exempel GitHub eller Azure Storage-konto. När huvudmallen anropas med hjälp av en URI från Azure PowerShell eller Azure CLI är den underordnade distributions-URI:n en kombination av den överordnade och relativa sökvägen.

Kommentar

När du skapar en templateSpec paketeras alla mallar som refereras av relativePath egenskapen i templateSpec-resursen av Azure PowerShell eller Azure CLI. Det kräver inte att filerna mellanlagras. Mer information finns i Skapa en mallspecifikation med länkade mallar.

Anta en mappstruktur som den här:

Diagram showing folder structure for Resource Manager linked template relative path.

Följande mall visar hur mainTemplate.json distribuerar nestedChild.json illustreras i föregående bild.

{
  "$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": "2022-09-01",
      "name": "childLinked",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "relativePath": "children/nestedChild.json"
        }
      }
    }
  ],
  "outputs": {}
}

I följande distribution är https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/linked-template-relpath/children/nestedChild.jsonURI:n för den länkade mallen i föregående mall .

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

Om du vill distribuera länkade mallar med relativ sökväg som lagras i ett Azure-lagringskonto använder du parametern QueryString/query-string för att ange den SAS-token som ska användas med parametern TemplateUri. Den här parametern stöds endast av Azure CLI version 2.18 eller senare och Azure PowerShell version 5.4 eller senare.

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

Kontrollera att det inte finns något inledande "?" i QueryString. Distributionen lägger till en när du monterar URI:n för distributionerna.

Mallspecifikationer

I stället för att underhålla dina länkade mallar på en tillgänglig slutpunkt kan du skapa en mallspecifikation som paketera huvudmallen och dess länkade mallar i en enda entitet som du kan distribuera. Mallspecifikationen är en resurs i din Azure-prenumeration. Det gör det enkelt att på ett säkert sätt dela mallen med användare i din organisation. Du använder rollbaserad åtkomstkontroll i Azure (Azure RBAC) för att ge åtkomst till mallspecifikationen.

Mer information finns i:

Beroenden

Precis som med andra resurstyper kan du ange beroenden mellan de kapslade/länkade mallarna. Om resurserna i en kapslad/länkad mall måste distribueras innan resurser i en andra kapslad/länkad mall anger du den andra mallen som är beroende av den första.

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

Du behöver inte ange contentVersion egenskapen för templateLink egenskapen eller parametersLink . Om du inte anger någon contentVersiondistribueras den aktuella versionen av mallen. Om du anger ett värde för innehållsversionen måste det matcha versionen i den länkade mallen. annars misslyckas distributionen med ett fel.

Föregående exempel visade hårdkodade URL-värden för malllänkarna. Den här metoden kan fungera för en enkel mall, men den fungerar inte bra för en stor uppsättning modulära mallar. I stället kan du skapa en statisk variabel som lagrar en bas-URL för huvudmallen och sedan dynamiskt skapa URL:er för de länkade mallarna från den bas-URL:en. Fördelen med den här metoden är att du enkelt kan flytta eller förgrena mallen eftersom du bara behöver ändra den statiska variabeln i huvudmallen. Huvudmallen skickar rätt URI:er i den uppdelade mallen.

I följande exempel visas hur du använder en bas-URL för att skapa två URL:er för länkade mallar (sharedTemplateUrl och 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')]"
}

Du kan också använda deployment() för att hämta bas-URL:en för den aktuella mallen och använda den för att hämta URL:en för andra mallar på samma plats. Den här metoden är användbar om mallplatsen ändras eller om du vill undvika hårdkodade URL:er i mallfilen. Egenskapen templateLink returneras endast när du länkar till en fjärrmall med en URL. Om du använder en lokal mall är den egenskapen inte tillgänglig.

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

I slutändan använder du variabeln i uri egenskapen för en templateLink egenskap.

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

Använda kopia

Om du vill skapa flera instanser av en resurs med en kapslad mall lägger du till elementet copy på resursnivå Microsoft.Resources/deployments . Om omfånget är innerkan du också lägga till kopian i den kapslade mallen.

Följande exempelmall visar hur du använder copy med en kapslad mall.

"resources": [
  {
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2022-09-01",
    "name": "[format('nestedTemplate{0}', 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": "2022-09-01",
            "name": "[format('{0}{1}', 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
            // }
          }
        ]
      }
    }
  }
]

Hämta värden från den länkade mallen

Hämta ett utdatavärde från en länkad mall genom att hämta egenskapsvärdet med syntax som: "[reference('deploymentName').outputs.propertyName.value]".

När du hämtar en utdataegenskap från en länkad mall får egenskapsnamnet inte innehålla ett bindestreck.

Följande exempel visar hur du refererar till en länkad mall och hämtar ett utdatavärde. Den länkade mallen returnerar ett enkelt meddelande. Först den länkade mallen:

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

Huvudmallen distribuerar den länkade mallen och hämtar det returnerade värdet. Observera att den refererar till distributionsresursen efter namn och använder namnet på egenskapen som returneras av den länkade mallen.

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

I följande exempel visas en mall som distribuerar en offentlig IP-adress och returnerar resurs-ID:t för Azure-resursen för den offentliga IP-adressen:

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

Om du vill använda den offentliga IP-adressen från föregående mall när du distribuerar en lastbalanserare länkar du till mallen och deklarerar ett beroende av resursen Microsoft.Resources/deployments . Den offentliga IP-adressen för lastbalanseraren är inställd på utdatavärdet från den länkade mallen.

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

Distributionshistorik

Resource Manager bearbetar varje mall som en separat distribution i distributionshistoriken. En huvudmall med tre länkade eller kapslade mallar visas i distributionshistoriken som:

Screenshot of deployment history in Azure portal.

Du kan använda dessa separata poster i historiken för att hämta utdatavärden efter distributionen. Följande mall skapar en offentlig IP-adress och matar ut IP-adressen:

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

Följande mall länkar till föregående mall. Den skapar tre offentliga IP-adresser.

{
  "$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": "2022-09-01",
      "name": "[format('linkedTemplate{0}', 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": "[format('myip-{0}', copyIndex())]"}
        }
      }
    }
  ]
}

Efter distributionen kan du hämta utdatavärdena med följande PowerShell-skript:

$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)"
}

Eller Azure CLI-skript i ett Bash-gränssnitt:

#!/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

Skydda en extern mall

Även om den länkade mallen måste vara externt tillgänglig behöver den inte vara allmänt tillgänglig för allmänheten. Du kan lägga till mallen i ett privat lagringskonto som endast är tillgängligt för lagringskontots ägare. Sedan skapar du en SAS-token (signatur för delad åtkomst) för att aktivera åtkomst under distributionen. Du lägger till SAS-token i URI:n för den länkade mallen. Även om token skickas som en säker sträng loggas URI:n för den länkade mallen, inklusive SAS-token, i distributionsåtgärderna. Om du vill begränsa exponeringen anger du ett förfallodatum för token.

Parameterfilen kan också begränsas till åtkomst via en SAS-token.

För närvarande kan du inte länka till en mall i ett lagringskonto som finns bakom en Azure Storage-brandvägg.

Viktigt!

I stället för att skydda den länkade mallen med en SAS-token bör du överväga att skapa en mallspecifikation. Mallspecifikationen lagrar på ett säkert sätt huvudmallen och dess länkade mallar som en resurs i din Azure-prenumeration. Du använder Azure RBAC för att ge åtkomst till användare som behöver distribuera mallen.

I följande exempel visas hur du skickar en SAS-token när du länkar till en mall:

{
  "$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": "2022-09-01",
      "name": "linkedTemplate",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[format('{0}{1}', uri(deployment().properties.templateLink.uri, 'helloworld.json'), parameters('containerSasToken'))]",
          "contentVersion": "1.0.0.0"
        }
      }
    }
  ],
  "outputs": {
  }
}

I PowerShell får du en token för containern och distribuerar mallarna med följande kommandon. Observera att parametern containerSasToken definieras i mallen. Det är inte en parameter i New-AzResourceGroupDeployment kommandot.

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

För Azure CLI i ett Bash-gränssnitt får du en token för containern och distribuerar mallarna med följande kod:

#!/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

Exempelmallar

I följande exempel visas vanliga användningsområden för länkade mallar.

Huvudmall Länkad mall beskrivning
Hello World länkad mall Returnerar sträng från länkad mall.
Load Balancer med offentlig IP-adress länkad mall Returnerar offentlig IP-adress från en länkad mall och anger det värdet i lastbalanseraren.
Flera IP-adresser länkad mall Skapar flera offentliga IP-adresser i en länkad mall.

Nästa steg