|
| 1 | +--- |
| 2 | +title: Tutorial - Deploy a linked template |
| 3 | +description: Learn how to deploy a linked template |
| 4 | +ms.date: 03/13/2020 |
| 5 | +ms.topic: tutorial |
| 6 | +ms.author: jgao |
| 7 | +--- |
| 8 | + |
| 9 | +# Tutorial: Deploy a linked template |
| 10 | + |
| 11 | +In the [previous tutorials](./deployment-tutorial-local-template.md), you learned how to deploy a template that is stored in your local computer. To deploy complex solutions, you can break a template into many templates, and deploy these templates through a main template. In this tutorial, you learn how to deploy a main template that contains the reference to a linked template. When the main template gets deployed, it triggers the deployment of the linked template. You also learn how to store and secure the linked template by using SAS token. It takes about **12 minutes** to complete. |
| 12 | + |
| 13 | +## Prerequisites |
| 14 | + |
| 15 | +We recommend that you complete the previous tutorial, but it's not required. |
| 16 | + |
| 17 | +## Review template |
| 18 | + |
| 19 | +In the previous tutorials, you deploy a template that creates a storage account, App Service plan, and web app. The template used was: |
| 20 | + |
| 21 | +:::code language="json" source="~/resourcemanager-templates/get-started-deployment/local-template/azuredeploy.json"::: |
| 22 | + |
| 23 | +## Create a linked template |
| 24 | + |
| 25 | +You can separate the storage account resource into a linked template: |
| 26 | + |
| 27 | +:::code language="json" source="~/resourcemanager-templates/get-started-deployment/linked-template/linkedStorageAccount.json"::: |
| 28 | + |
| 29 | +The following template is the main template. The highlighted **Microsoft.Resources/deployments** object shows how to call a linked template. The linked template cannot be stored as a local file or a file that is only available on your local network. You can only provide a URI value that includes either *http* or *https*. Resource Manager must be able to access the template. One option is to place your linked template in a storage account, and use the URI for that item. The URI is passed to template using a parameter. See the highlighted parameter definition. |
| 30 | + |
| 31 | +:::code language="json" source="~/resourcemanager-templates/get-started-deployment/linked-template/azuredeploy.json" highlight="27-32,40-58"::: |
| 32 | + |
| 33 | +Save a copy of the main template to your local computer with the .json extension, for example, azuredeploy.json. You don't need to save a copy of the linked template. The linked template will be copied from a GitHub repository to a storage account. |
| 34 | + |
| 35 | +## Store the linked template |
| 36 | + |
| 37 | +The following PowerShell script creates a storage account, creates a container, and copies the linked template from a GitHub repository to the container. A copy of the linked template is stored in [GitHub](https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/linkedStorageAccount.json). |
| 38 | + |
| 39 | +Select **Try-it** to open the Cloud Shell, select **Copy** to copy the PowerShell script, and right-click the shell pane to paste the script: |
| 40 | + |
| 41 | +> [!IMPORTANT] |
| 42 | +> Storage account names must be between 3 and 24 characters in length and use numbers and lower-case letters only. The name must be unique. In the template, the storage account name is the project name with "store" appended, and the project name must be between 3 and 11 characters. So the project name must meet the storage account name requirements and has less than 11 characters. |
| 43 | +
|
| 44 | +```azurepowershell-interactive |
| 45 | +$projectName = Read-Host -Prompt "Enter a project name:" # This name is used to generate names for Azure resources, such as storage account name. |
| 46 | +$location = Read-Host -Prompt "Enter a location (i.e. centralus)" |
| 47 | +
|
| 48 | +$resourceGroupName = $projectName + "rg" |
| 49 | +$storageAccountName = $projectName + "store" |
| 50 | +$containerName = "templates" # The name of the Blob container to be created. |
| 51 | +
|
| 52 | +$linkedTemplateURL = "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/linkedStorageAccount.json" # A completed linked template used in this tutorial. |
| 53 | +$fileName = "linkedStorageAccount.json" # A file name used for downloading and uploading the linked template. |
| 54 | +
|
| 55 | +# Download the template |
| 56 | +Invoke-WebRequest -Uri $linkedTemplateURL -OutFile "$home/$fileName" |
| 57 | +
|
| 58 | +# Create a resource group |
| 59 | +New-AzResourceGroup -Name $resourceGroupName -Location $location |
| 60 | +
|
| 61 | +# Create a storage account |
| 62 | +$storageAccount = New-AzStorageAccount ` |
| 63 | + -ResourceGroupName $resourceGroupName ` |
| 64 | + -Name $storageAccountName ` |
| 65 | + -Location $location ` |
| 66 | + -SkuName "Standard_LRS" |
| 67 | +
|
| 68 | +$context = $storageAccount.Context |
| 69 | +
|
| 70 | +# Create a container |
| 71 | +New-AzStorageContainer -Name $containerName -Context $context -Permission Container |
| 72 | +
|
| 73 | +# Upload the template |
| 74 | +Set-AzStorageBlobContent ` |
| 75 | + -Container $containerName ` |
| 76 | + -File "$home/$fileName" ` |
| 77 | + -Blob $fileName ` |
| 78 | + -Context $context |
| 79 | +
|
| 80 | +Write-Host "Press [ENTER] to continue ..." |
| 81 | +``` |
| 82 | + |
| 83 | +## Deploy template |
| 84 | + |
| 85 | +To deploy a private template in a storage account, generate a SAS token and include it in the URI for the template. Set the expiry time to allow enough time to complete the deployment. The blob containing the template is accessible to only the account owner. However, when you create a SAS token for the blob, the blob is accessible to anyone with that URI. If another user intercepts the URI, that user is able to access the template. A SAS token is a good way of limiting access to your templates, but you should not include sensitive data like passwords directly in the template. |
| 86 | + |
| 87 | +If you haven't created the resource group, see [Create resource group](./deployment-tutorial-local-template.md#create-resource-group). |
| 88 | + |
| 89 | +# [PowerShell](#tab/azure-powershell) |
| 90 | + |
| 91 | +```azurepowershell |
| 92 | +
|
| 93 | +$projectName = Read-Host -Prompt "Enter a project name:" # This name is used to generate names for Azure resources, such as storage account name. |
| 94 | +$templateFile = Read-Host -Prompt "Enter the main template file and path" |
| 95 | +
|
| 96 | +$resourceGroupName="${projectName}rg" |
| 97 | +$storageAccountName="${projectName}store" |
| 98 | +$containerName = "templates" |
| 99 | +$fileName = "linkedStorageAccount.json" # A file name used for downloading and uploading the linked template. |
| 100 | +
|
| 101 | +$key = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageAccountName).Value[0] |
| 102 | +$context = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $key |
| 103 | +
|
| 104 | +# Generate a SAS token |
| 105 | +$linkedTemplateUri = New-AzStorageBlobSASToken ` |
| 106 | + -Context $context ` |
| 107 | + -Container $containerName ` |
| 108 | + -Blob $fileName ` |
| 109 | + -Permission r ` |
| 110 | + -ExpiryTime (Get-Date).AddHours(2.0) ` |
| 111 | + -FullUri |
| 112 | +
|
| 113 | +# Deploy the template |
| 114 | +New-AzResourceGroupDeployment ` |
| 115 | + -Name DeployLinkedTemplate ` |
| 116 | + -ResourceGroupName $resourceGroupName ` |
| 117 | + -TemplateFile $templateFile ` |
| 118 | + -projectName $projectName ` |
| 119 | + -linkedTemplateUri $linkedTemplateUri ` |
| 120 | + -verbose |
| 121 | +``` |
| 122 | + |
| 123 | +# [Azure CLI](#tab/azure-cli) |
| 124 | + |
| 125 | +```azurecli |
| 126 | +
|
| 127 | +echo "Enter a project name that is used to generate resource names:" |
| 128 | +read projectName |
| 129 | +echo "Enter the main template file:" |
| 130 | +read templateFile |
| 131 | +
|
| 132 | +resourceGroupName="${projectName}rg" |
| 133 | +storageAccountName="${projectName}store" |
| 134 | +containerName="templates" |
| 135 | +fileName="linkedStorageAccount.json" |
| 136 | +
|
| 137 | +key=$(az storage account keys list -g $resourceGroupName -n $storageAccountName --query [0].value -o tsv) |
| 138 | +
|
| 139 | +linkedTemplateUri=$(az storage blob generate-sas \ |
| 140 | + --account-name $storageAccountName \ |
| 141 | + --account-key $key \ |
| 142 | + --container-name $containerName \ |
| 143 | + --name $fileName \ |
| 144 | + --permissions r \ |
| 145 | + --expiry `date -u -d "120 minutes" '+%Y-%m-%dT%H:%MZ'` \ |
| 146 | + --full-uri) |
| 147 | +
|
| 148 | +linkedTemplateUri=$(echo $linkedTemplateUri | sed 's/"//g') |
| 149 | +az deployment group create \ |
| 150 | + --name DeployLinkedTemplate \ |
| 151 | + --resource-group $resourceGroupName \ |
| 152 | + --template-file $templateFile \ |
| 153 | + --parameters projectName=$projectName linkedTemplateUri=$linkedTemplateUri \ |
| 154 | + --verbose |
| 155 | +``` |
| 156 | + |
| 157 | +--- |
| 158 | + |
| 159 | +## Clean up resources |
| 160 | + |
| 161 | +Clean up the resources you deployed by deleting the resource group. |
| 162 | + |
| 163 | +1. From the Azure portal, select **Resource group** from the left menu. |
| 164 | +2. Enter the resource group name in the **Filter by name** field. |
| 165 | +3. Select the resource group name. |
| 166 | +4. Select **Delete resource group** from the top menu. |
| 167 | + |
| 168 | +## Next steps |
| 169 | + |
| 170 | +You learned how to deploy a linked template. In the next tutorial, you learn how to create a DevOp pipeline to deploy a template. |
| 171 | + |
| 172 | +> [!div class="nextstepaction"] |
| 173 | +> [Create a pipeline](./deployment-tutorial-pipeline.md) |
0 commit comments