Samouczek: wdrażanie połączonego szablonu
W poprzednich samouczkach przedstawiono sposób wdrażania szablonu przechowywanego na komputerze lokalnym. Aby wdrożyć złożone rozwiązania, można podzielić szablon na wiele szablonów i wdrożyć te szablony za pomocą głównego szablonu. Z tego samouczka dowiesz się, jak wdrożyć główny szablon zawierający odwołanie do połączonego szablonu. Po wdrożeniu głównego szablonu są wywoływane wdrożenia szablonów połączonych. Dowiesz się również, jak przechowywać i zabezpieczać szablony przy użyciu tokenu SAS. Ukończenie tego procesu trwa około 12 minut .
Wymagania wstępne
Zalecamy ukończenie poprzedniego samouczka, ale nie jest to wymagane.
Przeglądanie szablonu
W poprzednich samouczkach wdrożysz szablon, który tworzy konto magazynu, plan usługi App Service i aplikację internetową. Użyto szablonu:
{
"$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]"
}
}
}
Tworzenie połączonego szablonu
Zasób konta magazynu można oddzielić od połączonego szablonu:
{
"$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]"
}
}
}
Poniższy szablon jest głównym szablonem. Wyróżniony Microsoft.Resources/deployments
obiekt pokazuje, jak wywołać połączony szablon. Połączony szablon nie może być przechowywany jako plik lokalny ani plik, który jest dostępny tylko w sieci lokalnej. Możesz podać wartość identyfikatora URI połączonego szablonu, który zawiera protokół HTTP lub HTTPS, albo użyć właściwości relativePath , aby wdrożyć zdalny połączony szablon w lokalizacji względem szablonu nadrzędnego. Jedną z opcji jest umieszczenie zarówno głównego szablonu, jak i połączonego szablonu na koncie magazynu.
{
"$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]"
}
}
}
Przechowywanie połączonego szablonu
Oba szablony główne i połączone szablony są przechowywane w usłudze GitHub:
Poniższy skrypt programu PowerShell tworzy konto magazynu, tworzy kontener i kopiuje dwa szablony z repozytorium GitHub do kontenera. Te dwa szablony to:
- Główny szablon: https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/azuredeploy.json
- Połączony szablon: https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/get-started-deployment/linked-template/linkedStorageAccount.json
Wybierz pozycję Wypróbuj , aby otworzyć usługę Cloud Shell, wybierz pozycję Kopiuj , aby skopiować skrypt programu PowerShell, a następnie kliknij prawym przyciskiem myszy okienko powłoki, aby wkleić skrypt:
Ważne
Nazwy kont magazynu muszą być unikatowe, od 3 do 24 znaków, a tylko cyfry i małe litery. Zmienna storageAccountName
przykładowego szablonu łączy projectName
maksymalnie 11 znaków parametru z unikatową wartością 13 znaków.
$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 ..."
Wdrażanie szablonu
Aby wdrożyć szablony na koncie magazynu, wygeneruj token SAS i podaj go do parametru -QueryString . Ustaw czas wygaśnięcia, aby umożliwić wystarczającą ilość czasu na ukończenie wdrożenia. Obiekty blob zawierające szablony są dostępne tylko dla właściciela konta. Jednak podczas tworzenia tokenu SAS dla obiektu blob obiekt blob jest dostępny dla każdego, kto ma ten token SAS. Jeśli inny użytkownik przechwytuje identyfikator URI i token SAS, ten użytkownik może uzyskać dostęp do szablonu. Token SAS to dobry sposób ograniczania dostępu do szablonów, ale nie należy dołączać poufnych danych, takich jak hasła bezpośrednio w szablonie.
Jeśli grupa zasobów nie została utworzona, zobacz Tworzenie grupy zasobów.
Uwaga
W poniższym kodzie date
interfejsu wiersza polecenia platformy Azure parametr -d
jest nieprawidłowym argumentem w systemie macOS. Dlatego użytkownicy systemu macOS, aby dodać 2 godziny do bieżącego czasu w terminalu w systemie macOS, należy użyć polecenia -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 ..."
Czyszczenie zasobów
Wyczyść wdrożone zasoby, usuwając grupę zasobów.
- W witrynie Azure Portal wybierz pozycję Grupa zasobów z menu po lewej stronie.
- Wprowadź nazwę grupy zasobów w polu Filtruj według nazwy.
- Wybierz nazwę grupy zasobów.
- Wybierz pozycję Usuń grupę zasobów z górnego menu.
Następne kroki
Wiesz już, jak wdrożyć połączony szablon. W następnym samouczku dowiesz się, jak utworzyć potok DevOps w celu wdrożenia szablonu.