Azure kaynaklarını dağıtırken bağlı ve iç içe şablonları kullanma

Karmaşık çözümleri dağıtmak için Azure Resource Manager şablonunuzu (ARM şablonu) birçok ilgili şablona bölebilir ve sonra bunları bir ana şablon aracılığıyla birlikte dağıtabilirsiniz. İlgili şablonlar, ana şablona eklenmiş ayrı dosyalar veya şablon söz dizimi olabilir. Bu makalede, ana şablondan bir bağlantı aracılığıyla başvuruda bulunılan ayrı bir şablon dosyasına başvurmak için bağlantılı şablon terimi kullanılır. Ana şablon içindeki eklenmiş şablon söz dizimine başvurmak için iç içe şablon terimini kullanır.

Küçük ve orta ölçekli çözümler için tek bir şablonun anlaşılması ve bakımının yapılması daha kolay olacaktır. Tüm kaynakları ve değerleri tek bir dosyada görebilirsiniz. Gelişmiş senaryolarda bağlantılı şablonlar çözümü hedeflenen bileşenlere ayırmanıza sağlar. Bu şablonları diğer senaryolar için kolayca yeniden kullanabilirsiniz.

Öğretici için bkz . Öğretici: Bağlantılı şablon dağıtma.

Not

Bağlantılı veya iç içe yerleştirilmiş şablonlar için dağıtım modunu yalnızca Artımlı olarak ayarlayabilirsiniz. Ancak, ana şablon tam modda dağıtılabilir. Ana şablonu tam modda dağıtırsanız ve bağlantılı veya iç içe yerleştirilmiş şablon aynı kaynak grubunu hedeflerse, bağlantılı veya iç içe yerleştirilmiş şablonda dağıtılan kaynaklar tam mod dağıtımı için değerlendirmeye dahil edilir. Ana şablona ve bağlantılı veya iç içe yerleştirilmiş şablonlara dağıtılan kaynakların birleştirilmiş koleksiyonu, kaynak grubundaki mevcut kaynaklarla karşılaştırılır. Bu birleştirilmiş koleksiyona dahil olmayan tüm kaynaklar silinir.

Bağlantılı veya iç içe yerleştirilmiş şablon farklı bir kaynak grubunu hedeflerse, bu dağıtım artımlı modu kullanır. Daha fazla bilgi için bkz . Dağıtım Kapsamı.

İpucu

ARM şablonlarıyla aynı özellikleri sunduğundan ve söz diziminin kullanımı daha kolay olduğundan Bicep'i öneririz. Daha fazla bilgi edinmek için bkz . modüller.

İç içe yerleştirilmiş şablon

Bir şablonu iç içe yerleştirmek için ana şablonunuza bir dağıtım kaynağı ekleyin. özelliğinde template şablon söz dizimini belirtin.

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

Aşağıdaki örnek, iç içe geçmiş bir şablon aracılığıyla bir depolama hesabı dağıtır.

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

İç içe kaynaklar sembolik ad şablonunda kullanılamaz. Aşağıdaki şablonda, iç içe depolama hesabı kaynağı sembolik ad kullanamaz:

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

İç içe şablonlardaki ifade değerlendirme kapsamı

İç içe yerleştirilmiş şablon kullanırken şablon ifadelerinin ana şablon kapsamında mı yoksa iç içe yerleştirilmiş şablon kapsamında mı değerlendirileceğini belirtebilirsiniz. Kapsam, resourceGroup ve abonelik gibi parametrelerin, değişkenlerin ve işlevlerin nasıl çözümleneceğini belirler.

Kapsamı özelliği aracılığıyla expressionEvaluationOptions ayarlarsınız. Varsayılan olarak, expressionEvaluationOptions özelliği olarak outerayarlanır ve bu da üst şablon kapsamını kullandığı anlamına gelir. İfadelerin iç içe şablon kapsamında değerlendirilmesine neden olmak için değerini inner olarak ayarlayın.

Önemli

için languageVersion 2.0özelliğinin expressionEvaluationOptions varsayılan değeridir inner. Değer outer engellenir.

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

Not

Kapsam olarak outerayarlandığında, iç içe şablonda dağıtmış olduğunuz bir kaynak için iç içe bir şablonun çıkışlar bölümündeki işlevini kullanamazsınız reference . İç içe yerleştirilmiş bir şablonda dağıtılan bir kaynağın değerlerini döndürmek için kapsamı kullanın inner veya iç içe şablonunuzu bağlı bir şablona dönüştürün.

Aşağıdaki şablon, şablon ifadelerinin kapsama göre nasıl çözüldüğünü gösterir. Hem üst şablonda hem de iç içe yerleştirilmiş şablonda tanımlanan adlı exampleVar bir değişken içerir. Değişkenin değerini döndürür.

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

içindeki özelliğinin exampleVarexpressionEvaluationOptionsdeğerine bağlı olarak değeri scope değişir. Aşağıdaki tabloda her iki kapsamın sonuçları gösterilmektedir.

Değerlendirme kapsamı Çıktı
iç içe şablondan
dış (veya varsayılan) üst şablondan

Aşağıdaki örnek bir SQL sunucusu dağıtır ve parola için kullanılacak bir anahtar kasası gizli dizisini alır. Kapsam olarak ayarlanır inner çünkü anahtar kasası kimliğini dinamik olarak oluşturur (dış şablonlara parametersbakınadminPassword.reference.keyVault) ve bunu iç içe şablona parametre olarak geçirir.

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

İç içe yerleştirilmiş bir şablonda güvenli parametre değerlerini kullanırken dikkatli olun. Kapsamı dış olarak ayarlarsanız, güvenli değerler dağıtım geçmişinde düz metin olarak depolanır. Şablonu dağıtım geçmişinde görüntüleyen bir kullanıcı güvenli değerleri görebilir. Bunun yerine iç kapsamı kullanın veya üst şablona güvenli değerlere ihtiyaç duyan kaynakları ekleyin.

Aşağıdaki alıntı hangi değerlerin güvenli olduğunu ve hangilerinin güvenli olmadığını gösterir.

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

Bağlantılı şablon

Bir şablonu bağlamak için ana şablonunuza bir dağıtım kaynağı ekleyin. özelliğinde templateLink , eklenecek şablonun URI'sini belirtin. Aşağıdaki örnek, depolama hesabındaki bir şablona bağlanır.

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

Bağlı bir şablona başvururken değeri uri yerel bir dosya veya yalnızca yerel ağınızda kullanılabilen bir dosya olamaz. Azure Resource Manager'ın şablona erişebilmesi gerekir. HTTP veya HTTPS olarak indirilebilen bir URI değeri sağlayın.

HTTP veya HTTPS içeren parametreleri kullanarak şablonlara başvurabilirsiniz. Örneğin, ortak bir desen parametresini kullanmaktır _artifactsLocation . Bağlı şablonu aşağıdaki gibi bir ifadeyle ayarlayabilirsiniz:

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

GitHub'da bir şablona bağlanıyorsanız ham URL'yi kullanın. Bağlantı şu biçimdedir: https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-with-templates/quickstart-template/azuredeploy.json. Ham bağlantıyı almak için Ham'ı seçin.

Screenshot of selecting raw URL in GitHub.

Not

Özel GitHub deposunda depolanan bir şablonu dağıtmak veya bağlı bir şablona başvurmak için Özel ve Güvenli Azure Portal Teklifi Oluşturma bölümünde belgelenen özel bir çözüme bakın. GitHub belirtecini Azure Key Vault'un dışına çeken bir Azure işlevi oluşturabilirsiniz.

Bağlantılı şablonlar için, sembolik olmayan bir dağıtımı sembolik ad şablonunun içine iç içe alabilir veya sembolik ad dağıtımlarını sembolik olmayan bir şablonun içine iç içe alabilir veya sembolik ad dağıtımlarını başka bir sembolik ad şablonunun içine iç içe yerleştirebilirsiniz veya tam tersi de geçerlidir.

Bağlı şablon için parametreler

Bağlantılı şablonunuzun parametrelerini bir dış dosyada veya satır içinde sağlayabilirsiniz. Dış parametre dosyası sağlarken şu parametersLink özelliği kullanın:

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

Parametre değerlerini satır içinde geçirmek için özelliğini kullanın 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')]"
        }
      }
    }
  }
]

Hem satır içi parametreleri hem de parametre dosyasının bağlantısını kullanamazsınız. Hem hem de parametersLinkparameters belirtildiğinde dağıtım bir hatayla başarısız olur.

Bağlı şablonlar için göreli yol kullanma

relativePath özelliğiMicrosoft.Resources/deployments, bağlantılı şablonlar yazmayı kolaylaştırır. Bu özellik, üst öğeye göre bir konumda uzak bağlantılı şablon dağıtmak için kullanılabilir. Bu özellik, GitHub veya Azure depolama hesabı gibi uzak bir URI'de tüm şablon dosyalarının hazırlanıp kullanılabilir olmasını gerektirir. Ana şablon Azure PowerShell veya Azure CLI'dan bir URI kullanılarak çağrıldığında, alt dağıtım URI'si üst ve relativePath'in bir bileşimidir.

Not

TemplateSpec oluştururken özelliği tarafından relativePath başvuruda bulunan tüm şablonlar, Azure PowerShell veya Azure CLI tarafından templateSpec kaynağında paketlenmiştir. Dosyaların hazır olmasını gerektirmez. Daha fazla bilgi için bkz . Bağlı şablonlarla şablon belirtimi oluşturma.

Aşağıdaki gibi bir klasör yapısı varsay:

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

Aşağıdaki şablonda, mainTemplate.json'ın önceki görüntüde gösterildiği gibi nestedChild.json nasıl dağıtıldığı gösterilmektedir.

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

Aşağıdaki dağıtımda, önceki şablondaki bağlı şablonun URI'si şeklindedir 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"

Bir Azure depolama hesabında depolanan göreli yol ile bağlantılı şablonları dağıtmak için parametresini QueryString/query-string kullanarak TemplateUri parametresiyle kullanılacak SAS belirtecini belirtin. Bu parametre yalnızca Azure CLI sürüm 2.18 veya üzeri ile Azure PowerShell sürüm 5.4 veya üzeri tarafından desteklenir.

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

QueryString'de başta "?" olmadığından emin olun. Dağıtım, dağıtımlar için URI'yi derlerken bir tane ekler.

Şablon belirtimleri

Bağlantılı şablonlarınızı erişilebilir bir uç noktada tutmak yerine, ana şablonu ve bağlantılı şablonlarını dağıtabileceğiniz tek bir varlığa paketleyen bir şablon belirtimi oluşturabilirsiniz. Şablon belirtimi, Azure aboneliğinizdeki bir kaynaktır. Şablonu kuruluşunuzdaki kullanıcılarla güvenli bir şekilde paylaşmayı kolaylaştırır. Şablon belirtimine erişim vermek için Azure rol tabanlı erişim denetimini (Azure RBAC) kullanırsınız.

Daha fazla bilgi için bkz.

Bağımlılıklar

Diğer kaynak türlerinde olduğu gibi, iç içe/bağlı şablonlar arasında bağımlılıklar ayarlayabilirsiniz. İkinci bir iç içe/bağlantılı şablondaki kaynaklar önce iç içe/bağlantılı bir şablondaki kaynakların dağıtılması gerekiyorsa, ikinci şablonu ilk şablona bağımlı olarak ayarlayın.

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

veya parametersLink özelliği için templateLink özelliğini sağlamanız contentVersion gerekmez. sağlamazsanız contentVersion, şablonun geçerli sürümü dağıtılır. İçerik sürümü için bir değer sağlarsanız, bunun bağlantılı şablondaki sürümle eşleşmesi gerekir; aksi takdirde dağıtım bir hatayla başarısız olur.

Önceki örneklerde şablon bağlantıları için sabit kodlanmış URL değerleri gösterildi. Bu yaklaşım basit bir şablon için işe yarayabilir, ancak büyük bir modüler şablon kümesi için iyi çalışmaz. Bunun yerine, ana şablonun temel URL'sini depolayan bir statik değişken oluşturabilir ve ardından bu temel URL'den bağlantılı şablonlar için dinamik olarak URL'ler oluşturabilirsiniz. Bu yaklaşımın avantajı, yalnızca ana şablondaki statik değişkeni değiştirmeniz gerektiğinden şablonu kolayca taşıyabilmeniz veya çatal oluşturabilmenizdir. Ana şablon, ayrıştırılan şablon boyunca doğru URI'leri geçirir.

Aşağıdaki örnekte, bağlantılı şablonlar (sharedTemplateUrl ve vmTemplateUrl) için iki URL oluşturmak üzere temel URL'nin nasıl kullanılacağı gösterilmektedir.

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

Ayrıca geçerli şablonun temel URL'sini almak için deployment() kullanabilir ve bunu kullanarak aynı konumdaki diğer şablonların URL'sini alabilirsiniz. Şablon konumunuz değişirse veya şablon dosyasında sabit kod URL'leri kullanmak istemiyorsanız bu yaklaşım kullanışlıdır. templateLink özelliği yalnızca URL ile uzak bir şablona bağlanırken döndürülür. Yerel şablon kullanıyorsanız bu özellik kullanılamaz.

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

Sonuç olarak, bir özelliğin özelliğinde uri değişkenini templateLink kullanırsınız.

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

Kopyalamayı kullanma

İç içe şablon içeren bir kaynağın birden çok örneğini oluşturmak için öğesini kaynak düzeyinde Microsoft.Resources/deployments ekleyincopy. Veya kapsam ise inner, kopyayı iç içe şablona ekleyebilirsiniz.

Aşağıdaki örnek şablon, iç içe yerleştirilmiş bir şablonla nasıl kullanılacağını copy gösterir.

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

Bağlı şablondan değerleri alma

Bağlantılı bir şablondan çıkış değeri almak için, aşağıdaki gibi bir söz dizimi ile özellik değerini alın: "[reference('deploymentName').outputs.propertyName.value]".

Bağlantılı şablondan çıkış özelliği alırken özellik adı tire içermemelidir.

Aşağıdaki örneklerde bağlantılı şablona başvurma ve çıkış değeri alma gösterilmektedir. Bağlantılı şablon basit bir ileti döndürür. İlk olarak, bağlı şablon:

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

Ana şablon bağlantılı şablonu dağıtır ve döndürülen değeri alır. Dağıtım kaynağına ada göre başvurduğunu ve bağlı şablon tarafından döndürülen özelliğin adını kullandığına dikkat edin.

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

Aşağıdaki örnekte bir genel IP adresi dağıtan ve bu genel IP için Azure kaynağının kaynak kimliğini döndüren bir şablon gösterilmektedir:

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

Yük dengeleyici dağıtırken önceki şablondan genel IP adresini kullanmak için şablona bağlanın ve kaynağa bağımlılık Microsoft.Resources/deployments bildirin. Yük dengeleyicideki genel IP adresi, bağlı şablondan çıkış değerine ayarlanır.

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

Dağıtım geçmişi

Resource Manager, her şablonu dağıtım geçmişinde ayrı bir dağıtım olarak işler. Dağıtım geçmişinde üç bağlantılı veya iç içe yerleştirilmiş şablon içeren bir ana şablon şöyle görünür:

Screenshot of deployment history in Azure portal.

Dağıtımdan sonra çıkış değerlerini almak için geçmişteki bu ayrı girişleri kullanabilirsiniz. Aşağıdaki şablon bir genel IP adresi oluşturur ve IP adresinin çıkışını oluşturur:

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

Aşağıdaki şablon, önceki şablona bağlanır. Üç genel IP adresi oluşturur.

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

Dağıtımdan sonra çıkış değerlerini aşağıdaki PowerShell betiğiyle alabilirsiniz:

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

Veya Bash kabuğunda Azure CLI betiği:

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

Dış şablonun güvenliğini sağlama

Bağlantılı şablonun dışarıdan kullanılabilir olması gerekir ancak genel kullanıma açık olması gerekmez. Şablonunuzu yalnızca depolama hesabı sahibi tarafından erişilebilen özel bir depolama hesabına ekleyebilirsiniz. Ardından, dağıtım sırasında erişimi etkinleştirmek için bir paylaşılan erişim imzası (SAS) belirteci oluşturursunuz. Bu SAS belirtecini bağlı şablonun URI'sine eklersiniz. Belirteç güvenli bir dize olarak geçirilse de, SAS belirteci de dahil olmak üzere bağlı şablonun URI'si dağıtım işlemlerinde günlüğe kaydedilir. Pozlamayı sınırlamak için belirteç için bir süre sonu ayarlayın.

Parametre dosyası bir SAS belirteci aracılığıyla erişimle de sınırlanabilir.

Şu anda Azure Depolama güvenlik duvarının arkasındaki depolama hesabındaki bir şablona bağlanamazsınız.

Önemli

Bağlı şablonunuzun güvenliğini SAS belirteci ile sağlamak yerine bir şablon belirtimi oluşturmayı göz önünde bulundurun. Şablon belirtimi, ana şablonu ve bağlantılı şablonlarını Azure aboneliğinizde kaynak olarak güvenli bir şekilde depolar. Şablonu dağıtması gereken kullanıcılara erişim vermek için Azure RBAC kullanırsınız.

Aşağıdaki örnekte, şablona bağlanırken SAS belirtecinin nasıl geçirilir gösterilmektedir:

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

PowerShell'de kapsayıcı için bir belirteç alır ve şablonları aşağıdaki komutlarla dağıtırsınız. parametresinin containerSasToken şablonda tanımlandığına dikkat edin. Komuttaki New-AzResourceGroupDeployment bir parametre değildir.

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

Bash kabuğunda Azure CLI için kapsayıcı için bir belirteç alır ve şablonları aşağıdaki kodla dağıtırsınız:

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

Örnek şablonlar

Aşağıdaki örneklerde bağlantılı şablonların yaygın kullanımları gösterilmektedir.

Ana şablon Bağlantılı şablon Açıklama
Hello World bağlı şablon Bağlı şablondan dize döndürür.
Genel IP adresi olan Load Balancer bağlı şablon Bağlı şablondan genel IP adresi döndürür ve bu değeri yük dengeleyicide ayarlar.
Birden çok IP adresi bağlı şablon Bağlantılı şablonda birkaç genel IP adresi oluşturur.

Sonraki adımlar