Używanie połączonych i zagnieżdżonych szablonów podczas wdrażania zasobów platformy Azure

Aby wdrożyć złożone rozwiązania, możesz podzielić szablon usługi Azure Resource Manager (szablon usługi ARM) na wiele powiązanych szablonów, a następnie wdrożyć je razem za pomocą głównego szablonu. Powiązane szablony mogą być oddzielnymi plikami lub składnią szablonu osadzoną w głównym szablonie. W tym artykule użyto terminu połączony szablon do odwoływania się do oddzielnego pliku szablonu, do którego odwołuje się link z głównego szablonu. Używa on terminu szablonu zagnieżdżonego do odwoływania się do składni osadzonego szablonu w szablonie głównym.

W przypadku małych i średnich rozwiązań łatwiej jest zrozumieć i utrzymywać jeden szablon. Wszystkie zasoby i wartości są widoczne w jednym pliku. W przypadku zaawansowanych scenariuszy połączone szablony umożliwiają podzielenie rozwiązania na składniki przeznaczone do realizacji. Te szablony mogą być bez problemu używane wielokrotnie w innych scenariuszach.

Aby zapoznać się z samouczkiem, zobacz Samouczek: wdrażanie połączonego szablonu.

Uwaga

W przypadku szablonów połączonych lub zagnieżdżonych można ustawić tryb wdrażania tylko na przyrostowy. Jednak szablon główny można wdrożyć w trybie pełnym. Jeśli wdrożysz główny szablon w trybie pełnym, a połączony lub zagnieżdżony szablon jest przeznaczony dla tej samej grupy zasobów, zasoby wdrożone w połączonym lub zagnieżdżonym szablonie zostaną uwzględnione w ocenie wdrożenia w trybie pełnym. Połączona kolekcja zasobów wdrożonych w głównym szablonie i połączonych lub zagnieżdżonych szablonów jest porównywana z istniejącymi zasobami w grupie zasobów. Wszystkie zasoby nieuwzględnione w tej połączonej kolekcji są usuwane.

Jeśli połączony lub zagnieżdżony szablon jest przeznaczony dla innej grupy zasobów, wdrożenie korzysta z trybu przyrostowego.

Porada

Zalecamy Bicep , ponieważ oferuje te same możliwości co szablony usługi ARM, a składnia jest łatwiejsza w użyciu. Aby dowiedzieć się więcej, zobacz moduły.

Szablon zagnieżdżony

Aby zagnieżdżać szablon, dodaj zasób wdrożenia do głównego szablonu. template We właściwości określ składnię szablonu.

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

W poniższym przykładzie konto magazynu jest wdrażane za pomocą szablonu zagnieżdżonego.

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

Zakres obliczania wyrażeń w szablonach zagnieżdżonych

Podczas korzystania z szablonu zagnieżdżonego można określić, czy wyrażenia szablonów mają być oceniane w zakresie szablonu nadrzędnego, czy szablonu zagnieżdżonego. Zakres określa sposób rozpoznawania parametrów, zmiennych i funkcji, takich jak resourceGroup i subskrypcja .

Zakres można ustawić za pomocą expressionEvaluationOptions właściwości . Domyślnie właściwość jest ustawiona expressionEvaluationOptions na outer, co oznacza, że używa zakresu szablonu nadrzędnego. Ustaw wartość , aby spowodować inner obliczanie wyrażeń w zakresie zagnieżdżonego szablonu.

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

Uwaga

Jeśli zakres jest ustawiony na outerwartość , nie można użyć reference funkcji w sekcji danych wyjściowych szablonu zagnieżdżonego dla zasobu wdrożonego w szablonie zagnieżdżonym. Aby zwrócić wartości wdrożonego zasobu w szablonie zagnieżdżonym, użyj inner zakresu lub przekonwertuj zagnieżdżony szablon na połączony szablon.

Poniższy szablon demonstruje sposób rozpoznawania wyrażeń szablonu zgodnie z zakresem. Zawiera zmienną o nazwie exampleVar zdefiniowaną zarówno w szablonie nadrzędnym, jak i w szablonie zagnieżdżonym. Zwraca wartość zmiennej.

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

Wartość exampleVar zmienia się w zależności od wartości scope właściwości w expressionEvaluationOptionspliku . W poniższej tabeli przedstawiono wyniki dla obu zakresów.

Zakres oceny Dane wyjściowe
Wewnętrzny z szablonu zagnieżdżonego
zewnętrzne (lub domyślne) z szablonu nadrzędnego

Poniższy przykład umożliwia wdrożenie serwera SQL i pobranie wpisu tajnego magazynu kluczy do użycia dla hasła. Zakres jest ustawiony na inner wartość , ponieważ dynamicznie tworzy identyfikator magazynu kluczy (zobacz adminPassword.reference.keyVault w szablonach parameterszewnętrznych) i przekazuje go jako parametr do zagnieżdżonego szablonu.

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

Podczas używania bezpiecznych wartości parametrów w szablonie zagnieżdżonym należy zachować ostrożność. Jeśli ustawisz zakres na zewnętrzny, bezpieczne wartości są przechowywane jako zwykły tekst w historii wdrażania. Użytkownik wyświetlający szablon w historii wdrażania może zobaczyć bezpieczne wartości. Zamiast tego należy użyć zakresu wewnętrznego lub dodać do szablonu nadrzędnego zasoby, które wymagają bezpiecznych wartości.

Poniższy fragment pokazuje, które wartości są bezpieczne i które nie są bezpieczne.

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

Szablon połączony

Aby połączyć szablon, dodaj zasób wdrożenia do głównego szablonu. templateLink We właściwości określ identyfikator URI szablonu do uwzględnienia. Poniższy przykład zawiera linki do szablonu, który znajduje się na koncie magazynu.

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

Podczas odwoływania się do połączonego szablonu wartość uri nie może być plikiem lokalnym ani plikiem dostępnym tylko w sieci lokalnej. Usługa Azure Resource Manager musi mieć dostęp do szablonu. Podaj wartość identyfikatora URI, która może być pobierana jako HTTP lub HTTPS.

Możesz odwoływać się do szablonów przy użyciu parametrów zawierających protokół HTTP lub HTTPS. Na przykład typowym wzorcem jest użycie parametru _artifactsLocation . Połączony szablon można ustawić za pomocą wyrażenia, takiego jak:

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

Jeśli łączysz się z szablonem w usłudze GitHub, użyj nieprzetworzonego adresu URL. Link ma format: https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-with-templates/quickstart-template/azuredeploy.json. Aby uzyskać nieprzetworzone łącze, wybierz pozycję Nieprzetworzone.

Wybieranie nieprzetworzonego adresu URL

Uwaga

Aby wdrożyć szablon lub odwołać się do połączonego szablonu przechowywanego w prywatnym repozytorium GitHub, zobacz rozwiązanie niestandardowe udokumentowane w temacie Tworzenie oferty niestandardowej i bezpiecznej witryny Azure Portal. Możesz utworzyć funkcję platformy Azure, która ściąga token usługi GitHub z usługi Azure Key Vault.

Parametry połączonego szablonu

Parametry połączonego szablonu można podać w pliku zewnętrznym lub wbudowanym. Podczas podawania pliku parametrów zewnętrznych użyj parametersLink właściwości :

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

Aby przekazać wbudowane wartości parametrów parameters , użyj właściwości .

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

Nie można użyć zarówno parametrów wbudowanych, jak i linku do pliku parametrów. Wdrożenie kończy się niepowodzeniem z powodu błędu, gdy określono oba parametersLink te elementy i parameters .

Używanie ścieżki względnej dla połączonych szablonów

Właściwość relativePath ułatwia tworzenie połączonych Microsoft.Resources/deployments szablonów. Tej właściwości można użyć do wdrożenia zdalnego połączonego szablonu w lokalizacji względem elementu nadrzędnego. Ta funkcja wymaga, aby wszystkie pliki szablonów można było przygotować i udostępnić w zdalnym identyfikatorze URI, takim jak GitHub lub konto usługi Azure Storage. Gdy główny szablon jest wywoływany przy użyciu identyfikatora URI z Azure PowerShell lub interfejsu wiersza polecenia platformy Azure, identyfikator URI wdrożenia podrzędnego jest kombinacją elementu nadrzędnego i parametru relativePath.

Uwaga

Podczas tworzenia szablonuSpec wszystkie szablony, do których odwołuje się relativePath właściwość, są pakowane w zasób templateSpec przez Azure PowerShell lub interfejs wiersza polecenia platformy Azure. Nie wymaga on przygotowania plików. Aby uzyskać więcej informacji, zobacz Tworzenie specyfikacji szablonu za pomocą połączonych szablonów.

Załóżmy, że struktura folderów wygląda następująco:

ścieżka względna połączonego szablonu usługi Resource Manager

Poniższy szablon przedstawia sposób wdrażania pliku mainTemplate.jsonzagnieżdżonego plikuChild.json przedstawionego na powyższym obrazie.

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

W poniższym wdrożeniu identyfikator URI połączonego szablonu w poprzednim szablonie to 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"

Aby wdrożyć połączone szablony ze ścieżką względną przechowywaną na koncie usługi Azure Storage, użyj parametru QueryString/query-string , aby określić token SAS, który ma być używany z parametrem TemplateUri. Ten parametr jest obsługiwany tylko przez interfejs wiersza polecenia platformy Azure w wersji 2.18 lub nowszej i Azure PowerShell w wersji 5.4 lub nowszej.

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

Upewnij się, że w elemecie QueryString nie ma wiodącego ciągu "?". Wdrożenie dodaje jeden podczas składania identyfikatora URI dla wdrożeń.

Specyfikacje szablonu

Zamiast utrzymywać połączone szablony w dostępnym punkcie końcowym, możesz utworzyć specyfikację szablonu , która pakuje główny szablon i jego połączone szablony w pojedynczą jednostkę, którą można wdrożyć. Specyfikacja szablonu to zasób w subskrypcji platformy Azure. Ułatwia bezpieczne udostępnianie szablonu użytkownikom w organizacji. Aby udzielić dostępu do specyfikacji szablonu, należy użyć kontroli dostępu opartej na rolach (RBAC) platformy Azure. Ta funkcja jest obecnie dostępna w wersji zapoznawczej.

Aby uzyskać więcej informacji, zobacz:

Zależności

Podobnie jak w przypadku innych typów zasobów, można ustawić zależności między zagnieżdżonym/połączonymi szablonami. Jeśli zasoby w jednym zagnieżdżonym/połączonym szablonie muszą zostać wdrożone przed użyciem zasobów w drugim zagnieżdżonym/połączonym szablonie, ustaw drugi szablon zależny od pierwszego.

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

Nie musisz podawać contentVersion właściwości dla templateLink właściwości lub parametersLink . Jeśli nie podasz elementu contentVersion, zostanie wdrożona bieżąca wersja szablonu. Jeśli podasz wartość wersji zawartości, musi być zgodna z wersją w połączonym szablonie; w przeciwnym razie wdrożenie kończy się niepowodzeniem z powodu błędu.

W poprzednich przykładach pokazano trwale zakodowane wartości adresów URL dla linków szablonu. Takie podejście może działać w przypadku prostego szablonu, ale nie działa dobrze w przypadku dużego zestawu szablonów modułowych. Zamiast tego możesz utworzyć zmienną statyczną, która przechowuje podstawowy adres URL głównego szablonu, a następnie dynamicznie tworzyć adresy URL połączonych szablonów na podstawie tego podstawowego adresu URL. Zaletą tego podejścia jest możliwość łatwego przenoszenia lub rozwidlenia szablonu, ponieważ musisz zmienić tylko zmienną statyczną w głównym szablonie. Główny szablon przekazuje poprawne identyfikatory URI w całym zdekompilowany szablon.

W poniższym przykładzie pokazano, jak za pomocą podstawowego adresu URL utworzyć dwa adresy URL dla połączonych szablonów (sharedTemplateUrl i 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')]"
}

Możesz również użyć metody deployment(), aby uzyskać podstawowy adres URL bieżącego szablonu i użyć go do pobrania adresu URL dla innych szablonów w tej samej lokalizacji. Takie podejście jest przydatne, jeśli lokalizacja szablonu ulegnie zmianie lub chcesz uniknąć twardych adresów URL kodowania w pliku szablonu. Właściwość templateLink jest zwracana tylko w przypadku łączenia z szablonem zdalnym przy użyciu adresu URL. Jeśli używasz szablonu lokalnego, ta właściwość nie jest dostępna.

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

Ostatecznie należy użyć zmiennej templateLink we uri właściwości właściwości .

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

Korzystanie z kopii

Aby utworzyć wiele wystąpień zasobu z zagnieżdżonym szablonem, dodaj copy element na poziomie Microsoft.Resources/deployments zasobu. Jeśli zakres to inner, możesz dodać kopię w szablonie zagnieżdżonym.

Poniższy przykładowy szablon pokazuje, jak używać z copy zagnieżdżonym szablonem.

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

Pobieranie wartości z połączonego szablonu

Aby uzyskać wartość wyjściową z połączonego szablonu, pobierz wartość właściwości ze składnią, na przykład: "[reference('deploymentName').outputs.propertyName.value]".

Podczas pobierania właściwości wyjściowej z połączonego szablonu nazwa właściwości nie może zawierać kreski.

W poniższych przykładach pokazano, jak odwoływać się do połączonego szablonu i pobierać wartość wyjściową. Połączony szablon zwraca prosty komunikat. Najpierw połączony szablon:

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

Główny szablon wdraża połączony szablon i pobiera zwróconą wartość. Zwróć uwagę, że odwołuje się on do zasobu wdrożenia według nazwy i używa nazwy właściwości zwróconej przez połączony szablon.

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

W poniższym przykładzie przedstawiono szablon, który wdraża publiczny adres IP i zwraca identyfikator zasobu platformy Azure dla tego publicznego adresu 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": "eastus",
      "properties": {
        "publicIPAddressVersion": "IPv4",
        "publicIPAllocationMethod": "Dynamic",
        "idleTimeoutInMinutes": 4
      },
      "dependsOn": []
    }
  ],
  "outputs": {
    "resourceID": {
      "type": "string",
      "value": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddresses_name'))]"
    }
  }
}

Aby użyć publicznego adresu IP z poprzedniego szablonu podczas wdrażania modułu równoważenia obciążenia, połącz się z szablonem i zadeklaruj zależność od Microsoft.Resources/deployments zasobu. Publiczny adres IP modułu równoważenia obciążenia jest ustawiony na wartość wyjściową z połączonego szablonu.

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

Historia wdrożenia

Resource Manager przetwarza każdy szablon jako oddzielne wdrożenie w historii wdrożenia. Główny szablon z trzema połączonymi lub zagnieżdżonym szablonem jest wyświetlany w historii wdrożenia jako:

Historia wdrożenia

Możesz użyć tych oddzielnych wpisów w historii, aby pobrać wartości wyjściowe po wdrożeniu. Poniższy szablon tworzy publiczny adres IP i zwraca adres 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]"
    }
  }
}

Poniższy szablon zawiera linki do poprzedniego szablonu. Tworzy trzy publiczne adresy IP.

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

Po wdrożeniu można pobrać wartości wyjściowe za pomocą następującego skryptu programu PowerShell:

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

Lub skrypt interfejsu wiersza polecenia platformy Azure w powłoce powłoki powłoki 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

Zabezpieczanie szablonu zewnętrznego

Chociaż połączony szablon musi być dostępny zewnętrznie, nie musi być ogólnie dostępny dla społeczeństwa. Szablon można dodać do prywatnego konta magazynu, które jest dostępne tylko dla właściciela konta magazynu. Następnie utworzysz token sygnatury dostępu współdzielonego (SAS), aby włączyć dostęp podczas wdrażania. Do identyfikatora URI połączonego szablonu dodaje się ten token SYGNATURy dostępu współdzielonego. Mimo że token jest przekazywany jako bezpieczny ciąg, identyfikator URI połączonego szablonu, w tym token SAS, jest rejestrowany w operacjach wdrażania. Aby ograniczyć ekspozycję, ustaw wygaśnięcie tokenu.

Plik parametrów może być również ograniczony do dostępu za pośrednictwem tokenu SAS.

Obecnie nie można połączyć się z szablonem na koncie magazynu, które znajduje się za zaporą usługi Azure Storage.

Ważne

Zamiast zabezpieczać połączony szablon przy użyciu tokenu sygnatury dostępu współdzielonego, rozważ utworzenie specyfikacji szablonu. Specyfikacja szablonu bezpiecznie przechowuje główny szablon i jego połączone szablony jako zasób w subskrypcji platformy Azure. Kontrola dostępu oparta na rolach platformy Azure umożliwia udzielanie dostępu użytkownikom, którzy muszą wdrożyć szablon.

W poniższym przykładzie pokazano, jak przekazać token SAS podczas łączenia z szablonem:

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

W programie PowerShell uzyskasz token dla kontenera i wdrożysz szablony przy użyciu następujących poleceń. Zwróć uwagę, że containerSasToken parametr jest zdefiniowany w szablonie. Nie jest to parametr w poleceniu New-AzResourceGroupDeployment .

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

W przypadku interfejsu wiersza polecenia platformy Azure w powłoce powłoki Bash otrzymasz token dla kontenera i wdrożysz szablony przy użyciu następującego kodu:

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

Przykładowe szablony

W poniższych przykładach przedstawiono typowe zastosowania połączonych szablonów.

Szablon główny Szablon połączony Opis
Hello world połączony szablon Zwraca ciąg z połączonego szablonu.
Load Balancer z publicznym adresem IP połączony szablon Zwraca publiczny adres IP z połączonego szablonu i ustawia wartość w module równoważenia obciążenia.
Wiele adresów IP połączony szablon Tworzy kilka publicznych adresów IP w szablonie połączonym.

Następne kroki