Créer des machines virtuelles dans un groupe identique à l’aide d’un modèle ARM
Cet article explique comment créer un groupe identique de machines virtuelles à l’aide d’un modèle ARM.
Un modèle Azure Resource Manager est un fichier JSON (JavaScript Object Notation) qui définit l’infrastructure et la configuration de votre projet. Le modèle utilise la syntaxe déclarative. Vous décrivez votre déploiement prévu sans écrire la séquence de commandes de programmation pour créer le déploiement.
Si votre environnement remplit les prérequis et que vous êtes déjà familiarisé avec l’utilisation des modèles ARM, sélectionnez le bouton Déployer sur Azure. Le modèle s’ouvre dans le portail Azure.
Prérequis
Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer.
Modèle ARM
Un modèle Azure Resource Manager est un fichier JSON (JavaScript Object Notation) qui définit l’infrastructure et la configuration de votre projet. Le modèle utilise la syntaxe déclarative. Vous décrivez votre déploiement prévu sans écrire la séquence de commandes de programmation pour créer le déploiement.
Les modèles ARM vous permettent de déployer des groupes de ressources associées. Dans un même modèle, vous pouvez créer le groupe de machines virtuelles identiques, installer des applications et configurer des règles de mise à l’échelle automatique. Avec l’utilisation de variables et de paramètres, ce modèle peut être réutilisé pour mettre à jour des groupes identiques existants ou en créer d’autres. Vous pouvez déployer des modèles via le Portail Azure, Azure CLI ou Azure PowerShell, ou à partir de pipelines d’intégration continue/de livraison continue.
Vérifier le modèle
{
"$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": "Location for all resources"
}
},
"vmSku": {
"type": "string",
"defaultValue": "Standard_D2s_v3",
"metadata": {
"description": "Size of VMs in the VM Scale Set."
}
},
"vmssName": {
"type": "string",
"metadata": {
"description": "String used as a base for naming resources (9 characters or less). A hash is prepended to this string for some resources, and resource-specific information is appended."
}
},
"instanceCount": {
"type": "int",
"defaultValue": 1,
"minValue": 1,
"maxValue": 100,
"metadata": {
"description": "Number of VM instances (100 or less)."
}
},
"adminUsername": {
"type": "string",
"metadata": {
"description": "Admin username on all VMs."
}
},
"authenticationType": {
"type": "string",
"defaultValue": "sshPublicKey",
"allowedValues": [
"sshPublicKey",
"password"
],
"metadata": {
"description": "Type of authentication to use on the Virtual Machine. SSH key is recommended."
}
},
"adminPasswordOrKey": {
"type": "securestring",
"metadata": {
"description": "SSH Key or password for the Virtual Machine. SSH key is recommended."
}
},
"securityType": {
"type": "string",
"defaultValue": "TrustedLaunch",
"allowedValues": [
"Standard",
"TrustedLaunch"
],
"metadata": {
"description": "Security Type of the Virtual Machine."
}
},
"_artifactsLocation": {
"type": "string",
"defaultValue": "[deployment().properties.templatelink.uri]",
"metadata": {
"description": "The base URI where artifacts required by this template are located"
}
},
"_artifactsLocationSasToken": {
"type": "securestring",
"defaultValue": "",
"metadata": {
"description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated"
}
}
},
"variables": {
"addressPrefix": "10.0.0.0/16",
"subnetPrefix": "10.0.0.0/24",
"networkApiVersion": "2020-11-01",
"virtualNetworkName": "[concat(parameters('vmssName'), 'vnet')]",
"publicIPAddressName": "[concat(parameters('vmssName'), 'pip')]",
"subnetName": "[concat(parameters('vmssName'), 'subnet')]",
"loadBalancerName": "[concat(parameters('vmssName'), 'lb')]",
"publicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]",
"networkSecurityGroupName": "[concat(parameters('vmssName'), 'nsg')]",
"bePoolName": "[concat(parameters('vmssName'), 'bepool')]",
"lbRuleName": "[concat(parameters('vmssName'), 'lbrule')]",
"lbProbeName": "[concat(parameters('vmssName'), 'lbprobe')]",
"bePoolConfigID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'),variables('bePoolName'))]",
"lbProbeID": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadBalancerName'),variables('lbProbeName'))]",
"nicName": "[concat(parameters('vmssName'), 'nic')]",
"ipConfigName": "[concat(parameters('vmssName'), 'ipconfig')]",
"frontEndIPConfigID": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'),'loadBalancerFrontEnd')]",
"osType": {
"publisher": "Canonical",
"offer": "0001-com-ubuntu-server-focal",
"sku": "20_04-lts-gen2",
"version": "latest"
},
"imageReference": "[variables('osType')]",
"securityProfileJson": {
"uefiSettings": {
"secureBootEnabled": true,
"vTpmEnabled": true
},
"securityType": "[parameters('securityType')]"
},
"linuxConfiguration": {
"disablePasswordAuthentication": true,
"ssh": {
"publicKeys": [
{
"path": "[concat('/home/', parameters('adminUsername'), '/.ssh/authorized_keys')]",
"keyData": "[parameters('adminPasswordOrKey')]"
}
]
}
}
},
"resources": [
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2023-04-01",
"name": "[variables('networkSecurityGroupName')]",
"location": "[parameters('location')]",
"properties": {
"securityRules": [
{
"name": "AllowPort9000",
"properties": {
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "9000",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 100,
"direction": "Inbound"
}
}
]
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2023-04-01",
"name": "[variables('virtualNetworkName')]",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[variables('addressPrefix')]"
]
},
"subnets": [
{
"name": "[variables('subnetName')]",
"properties": {
"addressPrefix": "[variables('subnetPrefix')]",
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
}
}
}
]
}
},
{
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2023-04-01",
"name": "[variables('publicIPAddressName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard"
},
"properties": {
"publicIPAllocationMethod": "Static",
"dnsSettings": {
"domainNameLabel": "[parameters('vmssName')]"
}
}
},
{
"type": "Microsoft.Network/loadBalancers",
"apiVersion": "2023-04-01",
"name": "[variables('loadBalancerName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard"
},
"dependsOn": [
"[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
],
"properties": {
"frontendIPConfigurations": [
{
"name": "LoadBalancerFrontEnd",
"properties": {
"publicIPAddress": {
"id": "[variables('publicIPAddressID')]"
}
}
}
],
"backendAddressPools": [
{
"name": "[variables('bePoolName')]"
}
],
"probes": [
{
"name": "[variables('lbProbeName')]",
"properties": {
"port": 9000,
"protocol": "Tcp",
"numberOfProbes": 2,
"intervalInSeconds": 5
}
}
],
"loadBalancingRules": [
{
"name": "[variables('lbRuleName')]",
"properties": {
"frontendIPConfiguration": {
"id": "[variables('frontEndIPConfigID')]"
},
"backendAddressPool": {
"id": "[variables('bePoolConfigID')]"
},
"probe": {
"id": "[variables('lbProbeID')]"
},
"loadDistribution": "Default",
"backendPort": 9000,
"frontendPort": 9000,
"protocol": "Tcp",
"idleTimeoutInMinutes": 4,
"enableFloatingIP": false,
"enableTcpReset": false,
"disableOutboundSnat": false
}
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachineScaleSets",
"apiVersion": "2023-09-01",
"name": "[parameters('vmssName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('vmSku')]",
"tier": "Standard",
"capacity": "[parameters('instanceCount')]"
},
"dependsOn": [
"[resourceId('Microsoft.Network/loadBalancers', variables('loadBalancerName'))]",
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]"
],
"properties": {
"orchestrationMode": "Flexible",
"platformFaultDomainCount": 1,
"singlePlacementGroup": false,
"virtualMachineProfile": {
"storageProfile": {
"osDisk": {
"createOption": "FromImage",
"caching": "ReadWrite"
},
"imageReference": "[variables('imageReference')]"
},
"osProfile": {
"computerNamePrefix": "[parameters('vmssName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPasswordOrKey')]",
"linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), null(), variables('linuxConfiguration'))]"
},
"securityProfile": "[if(equals(parameters('securityType'), 'TrustedLaunch'), variables('securityProfileJson'), null())]",
"networkProfile": {
"networkApiVersion": "[variables('networkApiVersion')]",
"networkInterfaceConfigurations": [
{
"name": "[variables('nicName')]",
"properties": {
"primary": true,
"ipConfigurations": [
{
"name": "[variables('ipConfigName')]",
"properties": {
"primary": true,
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]"
},
"loadBalancerBackendAddressPools": [
{
"id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('bePoolName'))]"
}
]
}
}
]
}
}
]
},
"extensionProfile": {
"extensions": [
{
"name": "lapextension",
"properties": {
"publisher": "Microsoft.Azure.Extensions",
"type": "CustomScript",
"typeHandlerVersion": "2.0",
"autoUpgradeMinorVersion": true,
"enableAutomaticUpgrade": true,
"settings": {
"fileUris": [
"[uri(parameters('_artifactsLocation'), concat('installserver.sh', parameters('_artifactsLocationSasToken')))]",
"[uri(parameters('_artifactsLocation'), concat('workserver.py', parameters('_artifactsLocationSasToken')))]"
],
"commandToExecute": "bash installserver.sh"
}
}
}
]
}
}
}
},
{
"type": "Microsoft.Insights/autoscaleSettings",
"apiVersion": "2022-10-01",
"name": "[concat(parameters('vmssName'), '-autoscalehost')]",
"location": "[parameters('location')]",
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachineScaleSets', parameters('vmSSName'))]"
],
"properties": {
"name": "[concat(parameters('vmssName'), '-autoscalehost')]",
"targetResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', parameters('vmSSName'))]",
"enabled": true,
"profiles": [
{
"name": "Profile1",
"capacity": {
"minimum": "1",
"maximum": "10",
"default": "1"
},
"rules": [
{
"metricTrigger": {
"metricName": "Percentage CPU",
"metricResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', parameters('vmSSName'))]",
"timeGrain": "PT1M",
"statistic": "Average",
"timeWindow": "PT5M",
"timeAggregation": "Average",
"operator": "GreaterThan",
"threshold": 60
},
"scaleAction": {
"direction": "Increase",
"type": "ChangeCount",
"value": "1",
"cooldown": "PT1M"
}
},
{
"metricTrigger": {
"metricName": "Percentage CPU",
"metricResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', parameters('vmSSName'))]",
"timeGrain": "PT1M",
"statistic": "Average",
"timeWindow": "PT5M",
"timeAggregation": "Average",
"operator": "LessThan",
"threshold": 30
},
"scaleAction": {
"direction": "Decrease",
"type": "ChangeCount",
"value": "1",
"cooldown": "PT1M"
}
}
]
}
]
}
}
]
}
Ces ressources Azure sont définies dans le modèle :
- Microsoft.Network/virtualNetworks
- Microsoft.Network/publicIPAddresses
- Microsoft.Network/loadBalancers
- Microsoft.Compute/virtualMachineScaleSets
- Microsoft.Insights/autoscaleSettings
- Microsoft.Network/networkSecurityGroups
Définir un groupe identique
Pour créer un groupe identique avec un modèle, vous définissez les ressources appropriées. Les parties essentielles du type de ressource de groupe de machines virtuelles identiques sont les suivantes :
Propriété | Description de la propriété | Exemple de valeur de modèle |
---|---|---|
type | Type de ressource Azure à créer | Microsoft.Compute/virtualMachineScaleSets |
name | Nom du groupe identique | myScaleSet |
location | Emplacement de création du groupe identique | USA Est |
sku.name | Taille de machine virtuelle pour chaque instance de groupe identique | Standard_A1 |
sku.capacity | Nombre d’instances de machines virtuelles à créer initialement | 2 |
imageReference | Plateforme ou image personnalisée à utiliser pour les instances de machine virtuelle | Canonical Ubuntu Server 16.04-LTS |
osProfile.computerNamePrefix | Préfixe du nom de chaque instance de machine virtuelle | myvmss |
osProfile.adminUsername | Nom d’utilisateur de chaque instance de machine virtuelle | azureuser |
osProfile.adminPassword | Mot de passe de chaque instance de machine virtuelle | P@ssw0rd! |
Pour personnaliser un modèle de groupe identique, vous pouvez changer la taille ou la capacité initiale des machines virtuelles. L’autre possibilité consiste à utiliser une autre plateforme ou une image personnalisée.
Ajouter un exemple d’application
Pour tester votre groupe identique, installez une application web de base. Lorsque vous déployez un groupe identique, les extensions de machine virtuelle peuvent fournir des tâches d’automatisation et de configuration après le déploiement, telles que l’installation d’une application. Des scripts peuvent être téléchargés à partir de Stockage Azure ou de GitHub, ou fournis dans le portail Azure lors de l’exécution de l’extension. Pour appliquer une extension à votre groupe identique, vous ajoutez la section extensionProfile à l’exemple de ressource précédent. En règle générale, le profil d’extension définit les propriétés suivantes :
- Type d’extension
- Éditeur d’extension
- Version d’extension
- Emplacement des scripts de configuration ou d’installation
- Commandes à exécuter sur les instances de machine virtuelle
Le modèle utilise l’extension de script personnalisé pour installer Bottle, un framework web Python, et un serveur HTTP simple.
Deux scripts sont définis dans fileUris - installserver.sh et workserver.py. Ces fichiers sont téléchargés à partir de GitHub, puis commandToExecute exécute bash installserver.sh
pour installer et configurer l’application.
Déployer le modèle
Vous pouvez également déployer un modèle Resource Manager en utilisant Azure CLI :
# Create a resource group
az group create --name myResourceGroup --location EastUS
# Deploy template into resource group
az deployment group create -g myResourceGroup -f azuredeploy.json --parameters _artifactsLocation=https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/application-workloads/python/vmss-bottle-autoscale/azuredeploy.json
Renseignez le nom du groupe identique, le nombre d’instances et les informations d’identification d’administrateur pour les instances de machine virtuelle. Quelques minutes sont nécessaires pour que le groupe identique et les ressources associées soient créés.
Valider le déploiement
Pour voir votre groupe identique en action, accédez à l’exemple d’application web dans un navigateur web. Obtenez l’adresse IP publique de l’équilibreur de charge avec az network public-ip list comme suit :
az network public-ip list \
--resource-group myResourceGroup \
--query [*].ipAddress -o tsv
Entrez l’adresse IP publique de l’équilibreur de charge dans un navigateur web au format http://publicIpAddress:9000/do_work. L’équilibreur de charge répartit le trafic vers l’une de vos instances de machine virtuelle, comme illustré dans l’exemple suivant :
Nettoyer les ressources
Lorsque vous n’en avez plus besoin, vous pouvez utiliser la commande az group delete pour supprimer le groupe de ressources, le groupe identique et toutes les ressources associées, comme suit. Le paramètre --no-wait
retourne le contrôle à l’invite de commandes sans attendre que l’opération se termine. Le paramètre --yes
confirme que vous souhaitez supprimer les ressources sans passer par une invite supplémentaire à cette fin.
az group delete --name myResourceGroup --yes --no-wait