教學課程:部署連結的範本
在前面的教學課程中,您已了解如何部署儲存在本機電腦中的範本。 若要部署複雜的解決方案,您可以將一個範本拆解成許多範本,然後透過主要範本來部署這些拆解出來的範本。 在本教學課程中,您將了解如何部署包含連結範本參考的主要範本。 部署主要範本時,其會觸發連結範本的部署。 您也會了解如何使用 SAS 權杖來儲存及保護範本。 完成此教學課程大約需要 12 分鐘。
必要條件
建議您完成上一個教學課程,但這並非必要條件。
檢閱範本
在前面的教學課程中,您部署了範本來建立儲存體帳戶、App Service 方案和 Web 應用程式。 所使用的範本是:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"projectName": {
"type": "string",
"minLength": 3,
"maxLength": 11,
"metadata": {
"description": "Specify a project name that is used to generate resource names."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Specify a location for the resources."
}
},
"storageSKU": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS",
"Standard_ZRS",
"Premium_LRS",
"Premium_ZRS",
"Standard_GZRS",
"Standard_RAGZRS"
],
"metadata": {
"description": "Specify the storage account type."
}
},
"linuxFxVersion": {
"type": "string",
"defaultValue": "php|7.0",
"metadata": {
"description": "Specify the Runtime stack of current web app"
}
}
},
"variables": {
"storageAccountName": "[format('{0}{1}', parameters('projectName'), uniqueString(resourceGroup().id))]",
"webAppName": "[format('{0}WebApp', parameters('projectName'))]",
"appServicePlanName": "[format('{0}Plan', parameters('projectName'))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-01-01",
"name": "[variables('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('storageSKU')]"
},
"kind": "StorageV2",
"properties": {
"supportsHttpsTrafficOnly": true
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2022-09-01",
"name": "[variables('appServicePlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "B1",
"tier": "Basic",
"size": "B1",
"family": "B",
"capacity": 1
},
"kind": "linux",
"properties": {
"perSiteScaling": false,
"reserved": true,
"targetWorkerCount": 0,
"targetWorkerSizeId": 0
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-09-01",
"name": "[variables('webAppName')]",
"location": "[parameters('location')]",
"kind": "app",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
"siteConfig": {
"linuxFxVersion": "[parameters('linuxFxVersion')]"
}
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
]
}
],
"outputs": {
"storageEndpoint": {
"type": "object",
"value": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2023-01-01').primaryEndpoints]"
}
}
}
建立連結的範本
您可以將儲存體帳戶資源分散到連結的範本中:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"type": "string",
"metadata": {
"description": "Specify the storage account name."
}
},
"location": {
"type": "string",
"metadata": {
"description": "Specify a location for the resources."
}
},
"storageSKU": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS",
"Standard_ZRS",
"Premium_LRS",
"Premium_ZRS",
"Standard_GZRS",
"Standard_RAGZRS"
],
"metadata": {
"description": "Specify the storage account type."
}
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-01-01",
"name": "[parameters('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('storageSKU')]"
},
"kind": "StorageV2",
"properties": {
"supportsHttpsTrafficOnly": true
}
}
],
"outputs": {
"storageEndpoint": {
"type": "object",
"value": "[reference(parameters('storageAccountName')).primaryEndpoints]"
}
}
}
下列範本是主要範本。 醒目提示的 Microsoft.Resources/deployments
物件會顯示如何呼叫連結的範本。 連結的範本無法儲存為本機檔案,也無法儲存為只能在區域網路上使用的檔案。 您可以提供包含 HTTP 或 HTTPS 的連結範本 URI 值,或使用 relativePath 屬性,在相對於父範本的位置部署遠端連結範本。 其中一個選項是將主要範本和連結範本同時放在儲存體帳戶中。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"projectName": {
"type": "string",
"minLength": 3,
"maxLength": 11,
"metadata": {
"description": "Specify a project name that is used to generate resource names."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Specify a location for the resources."
}
},
"linuxFxVersion": {
"type": "string",
"defaultValue": "php|7.0",
"metadata": {
"description": "The Runtime stack of current web app"
}
}
},
"variables": {
"storageAccountName": "[concat(parameters('projectName'), uniqueString(resourceGroup().id))]",
"webAppName": "[concat(parameters('projectName'), 'WebApp')]",
"appServicePlanName": "[concat(parameters('projectName'), 'Plan')]"
},
"resources": [
{
"name": "linkedTemplate",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
"properties": {
"mode": "Incremental",
"templateLink": {
"relativePath": "linkedStorageAccount.json"
},
"parameters": {
"storageAccountName": {
"value": "[variables('storageAccountName')]"
},
"location": {
"value": "[parameters('location')]"
}
}
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2022-09-01",
"name": "[variables('appServicePlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "B1",
"tier": "Basic",
"size": "B1",
"family": "B",
"capacity": 1
},
"kind": "linux",
"properties": {
"perSiteScaling": false,
"reserved": true,
"targetWorkerCount": 0,
"targetWorkerSizeId": 0
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-09-01",
"name": "[variables('webAppName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]"
],
"kind": "app",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]",
"siteConfig": {
"linuxFxVersion": "[parameters('linuxFxVersion')]"
}
}
}
],
"outputs": {
"storageEndpoint": {
"type": "object",
"value": "[reference('linkedTemplate').outputs.storageEndpoint.value]"
}
}
}
儲存連結的範本
主要範本和連結範本都儲存在 GitHub 中:
下列 PowerShell 指令碼會建立儲存體帳戶、建立容器,並將連結範本從 GitHub 存放庫複製到容器。 這兩個範本為:
- 主要範本:https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/azuredeploy.json
- 連結的範本:https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/linkedStorageAccount.json
選取 [試試看] 以開啟 Cloud Shell,選取 [複製] 以複製 PowerShell 指令碼,然後以滑鼠右鍵按一下殼層窗格以貼上指令碼:
重要
儲存體帳戶名稱必須是唯一的,長度介於 3 到 24 個字元,而且只能使用數字和小寫字母。 範例範本的 storageAccountName
變數合併了 projectName
參數的 11 個字元上限,以及 13 個字元的 uniqueString 值。
$projectName = Read-Host -Prompt "Enter a project name:" # This name is used to generate names for Azure resources, such as storage account name.
$location = Read-Host -Prompt "Enter a location (i.e. centralus)"
$resourceGroupName = $projectName + "rg"
$storageAccountName = $projectName + "store"
$containerName = "templates" # The name of the Blob container to be created.
$mainTemplateURL = "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/azuredeploy.json"
$linkedTemplateURL = "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/linkedStorageAccount.json"
$mainFileName = "azuredeploy.json" # A file name used for downloading and uploading the main template.Add-PSSnapin
$linkedFileName = "linkedStorageAccount.json" # A file name used for downloading and uploading the linked template.
# Download the templates
Invoke-WebRequest -Uri $mainTemplateURL -OutFile "$home/$mainFileName"
Invoke-WebRequest -Uri $linkedTemplateURL -OutFile "$home/$linkedFileName"
# Create a resource group
New-AzResourceGroup -Name $resourceGroupName -Location $location
# Create a storage account
$storageAccount = New-AzStorageAccount `
-ResourceGroupName $resourceGroupName `
-Name $storageAccountName `
-Location $location `
-SkuName "Standard_LRS"
$context = $storageAccount.Context
# Create a container
New-AzStorageContainer -Name $containerName -Context $context -Permission Container
# Upload the templates
Set-AzStorageBlobContent `
-Container $containerName `
-File "$home/$mainFileName" `
-Blob $mainFileName `
-Context $context
Set-AzStorageBlobContent `
-Container $containerName `
-File "$home/$linkedFileName" `
-Blob $linkedFileName `
-Context $context
Write-Host "Press [ENTER] to continue ..."
部署範本
若要在儲存體帳戶中部署範本,請產生 SAS 權杖並提供給 -QueryString 參數。 設定到期時間,以允許足夠的時間來完成部署。 僅有帳戶擁有者可以存取包含範本的 Blob。 不過建立 Blob 的 SAS 權杖時,具備該 SAS 權杖的任何人都可以存取這個 Blob。 如果另一位使用者攔截了 URI 和 SAS 權杖,那麼該使用者也能存取範本。 SAS Token 是限制存取範本的好方法,但您不應該將機密資料 (如密碼) 直接包含在範本中。
如果您尚未建立資源群組,請參閱建立資源群組。
注意
在下列 Azure CLI 程式碼中,date
參數 -d
會是 macOS 中無效的引數。 因此若 macOS 的使用者,要在 macOS 上的終端機新增 2 小時到目前的時間,應該使用 -v+2H
。
$projectName = Read-Host -Prompt "Enter the same project name:" # This name is used to generate names for Azure resources, such as storage account name.
$resourceGroupName="${projectName}rg"
$storageAccountName="${projectName}store"
$containerName = "templates"
$key = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageAccountName).Value[0]
$context = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $key
$mainTemplateUri = $context.BlobEndPoint + "$containerName/azuredeploy.json"
$sasToken = New-AzStorageContainerSASToken `
-Context $context `
-Container $containerName `
-Permission r `
-ExpiryTime (Get-Date).AddHours(2.0)
$newSas = $sasToken.substring(1)
New-AzResourceGroupDeployment `
-Name DeployLinkedTemplate `
-ResourceGroupName $resourceGroupName `
-TemplateUri $mainTemplateUri `
-QueryString $newSas `
-projectName $projectName `
-verbose
Write-Host "Press [ENTER] to continue ..."
清除資源
您可以藉由刪除資源群組來清除您所部署的資源。
- 在 Azure 入口網站中,選取左側功能表中的 [資源群組]。
- 在 [依名稱篩選] 欄位中輸入資源群組名稱。
- 選取資源群組名稱。
- 從頂端功能表中選取 [刪除資源群組]。
下一步
您已了解如何部署連結的範本。 在下一個教學課程中,您將了解如何建立 DevOps 管線來部署範本。