Tutorial: Implantar um modelo vinculado
Nos tutoriais anteriores, você aprendeu a implantar um modelo que é armazenado em seu computador local. Para implantar soluções complexas, você pode dividir um modelo em vários modelos e implantar esses modelos por meio de um modelo principal. Neste tutorial, você aprenderá a implantar um modelo principal que contém a referência a um modelo vinculado. Quando o modelo principal é implantado, ele dispara a implantação do modelo vinculado. Saiba também como armazenar e proteger os modelos usando um token SAS. Esse procedimento demora cerca de 12 minutos para ser concluído.
Pré-requisitos
Recomendamos que você conclua o tutorial anterior, mas isso não é obrigatório.
Examinar modelo
Nos tutoriais anteriores, você implanta um modelo que cria uma conta de armazenamento, um plano do Serviço de Aplicativo e um aplicativo Web. O modelo usado foi:
{
"$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]"
}
}
}
Criar um modelo vinculado
Você pode separar o recurso de conta de armazenamento em um modelo vinculado:
{
"$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]"
}
}
}
O modelo a seguir é o modelo principal. O objeto Microsoft.Resources/deployments
realçado mostra como chamar um modelo vinculado. O modelo vinculado não pode ser armazenado como um arquivo local ou um arquivo que esteja disponível somente na sua rede local. Você pode fornecer um valor de URI do modelo vinculado que inclui HTTP ou HTTPS ou usar a propriedade relativePath para implantar um modelo vinculado remoto em uma localização relativa ao modelo pai. Uma opção é colocar o modelo principal e o modelo vinculado em uma conta de armazenamento.
{
"$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]"
}
}
}
Armazenar o modelo vinculado
O modelo principal e o modelo vinculado são armazenados no GitHub:
O script do PowerShell a seguir cria uma conta de armazenamento e um contêiner, além de copiar os dois modelos de um repositório GitHub para o contêiner. Esses dois modelos são:
- O modelo principal: https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/azuredeploy.json
- O modelo vinculado: https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/linkedStorageAccount.json
Selecione Experimentar para abrir o Cloud Shell, selecione Copiar para copiar o script do PowerShell e clique com o botão direito do mouse no painel do shell para colar o script:
Importante
Os nomes das contas de armazenamento devem ser exclusivos, ter entre 3 e 24 caracteres e usar apenas números e letras minúsculas. A variável storageAccountName
do modelo de exemplo combina o máximo de 11 caracteres do parâmetro projectName
com um valor de uniqueString de 13 caracteres.
$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 ..."
Implantar modelo
Para implantar modelos em uma conta de armazenamento, gere um token SAS e forneça-o ao parâmetro -QueryString. Defina a hora de vencimento de forma a permitir que haja tempo suficiente para concluir a implantação. Os blobs que contêm o modelo ficam acessíveis somente para o proprietário da conta. No entanto, quando você cria um token SAS para um blob, o blob fica acessível para qualquer pessoa com o token SAS. Se outro usuário intercepta o URI e o token SAS, esse usuário pode acessar o modelo. Um token SAS é uma boa maneira de limitar o acesso aos seus modelos, mas você não deve incluir dados confidenciais, como senhas, diretamente no modelo.
Caso você não tenha criado o grupo de recursos, confira Criar grupo de recursos.
Observação
No código da CLI do Azure abaixo, o parâmetro de date
-d
é um argumento inválido no macOS. Portanto, para adicionar 2 horas à hora atual no terminal no macOS, os usuários do macOS devem usar -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 ..."
Limpar os recursos
Limpe os recursos que você implantou excluindo o grupo de recursos.
- No portal do Azure, escolha Grupos de recursos do menu à esquerda.
- No campo Filtrar por nome, insira o nome do grupo de recursos.
- Selecione o nome do grupo de recursos.
- Escolha Excluir grupo de recursos no menu superior.
Próximas etapas
Você aprendeu a implantar um modelo vinculado. No próximo tutorial, você aprenderá a criar um pipeline de DevOps para implantar um modelo.