Quickstart: Een virtuele-machineschaalset voor Windows maken met een ARM-sjabloon

Van toepassing op: ✔️ Uniforme schaalsets voor Windows-VM's ✔️

Notitie

Het volgende artikel is bedoeld voor Uniform Virtual Machine Scale Sets. We raden u aan flexibele virtuele-machineschaalsets te gebruiken voor nieuwe workloads. Meer informatie over deze nieuwe indelingsmodus vindt u in het overzicht van flexibele virtuele-machineschaalsets.

Met een virtuele-machineschaalset kunt u een set virtuele machines voor automatisch schalen implementeren en beheren. U kunt het aantal VM’s in de schaalset handmatig schalen of regels voor automatisch schalen definiëren op basis van resourcegebruik zoals CPU, vraag naar geheugen, of netwerkverkeer. Een Azure load balancer verdeelt het verkeer vervolgens naar de VM-exemplaren in de schaalset. In deze quickstart maakt u een virtuele-machineschaalset en implementeert u een voorbeeldtoepassing met een Azure Resource Manager-sjabloon (ARM-sjabloon).

Een Azure Resource Manager-sjabloon is een JSON-bestand (JavaScript Object Notation) dat de infrastructuur en configuratie voor uw project definieert. Voor de sjabloon is declaratieve syntaxis vereist. U beschrijft de beoogde implementatie zonder de reeks programmeeropdrachten te schrijven om de implementatie te maken.

Met ARM-sjablonen kunt u groepen gerelateerde resources implementeren. In één sjabloon kunt u de virtuele-machineschaalset maken, toepassingen installeren en regels voor automatisch schalen configureren. Met behulp van variabelen en parameters kan deze sjabloon opnieuw worden gebruikt voor het bijwerken van bestaande schaalsets, of om extra schaalsets te maken. U kunt sjablonen implementeren via de Azure-portal, Azure CLI, Azure PowerShell of via CI/CD-pijplijnen (Continuous Integration/Continuous Delivery).

Als uw omgeving voldoet aan de vereisten en u benkend bent met het gebruik van ARM-sjablonen, selecteert u de knop Implementeren naar Azure. De sjabloon wordt in Azure Portal geopend.

Button to deploy the Resource Manager template to Azure.

Vereisten

Als u geen Azure-abonnement hebt, maakt u een gratis account voordat u begint.

De sjabloon controleren

De sjabloon die in deze quickstart wordt gebruikt, komt uit Azure Quick Start-sjablonen.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.25.53.49325",
      "templateHash": "9083237914224042883"
    }
  },
  "parameters": {
    "vmssName": {
      "type": "string",
      "minLength": 3,
      "maxLength": 61,
      "metadata": {
        "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended."
      }
    },
    "vmSku": {
      "type": "string",
      "defaultValue": "Standard_D2s_v3",
      "metadata": {
        "description": "Size of VMs in the VM Scale Set."
      }
    },
    "windowsOSVersion": {
      "type": "string",
      "defaultValue": "2022-datacenter-azure-edition",
      "allowedValues": [
        "2019-DataCenter-GenSecond",
        "2016-DataCenter-GenSecond",
        "2022-datacenter-azure-edition"
      ],
      "metadata": {
        "description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version. Allowed values: 2008-R2-SP1, 2012-Datacenter, 2012-R2-Datacenter & 2016-Datacenter, 2019-Datacenter."
      }
    },
    "securityType": {
      "type": "string",
      "defaultValue": "TrustedLaunch",
      "allowedValues": [
        "Standard",
        "TrustedLaunch"
      ],
      "metadata": {
        "description": "Security Type of the Virtual Machine."
      }
    },
    "instanceCount": {
      "type": "int",
      "defaultValue": 3,
      "minValue": 1,
      "maxValue": 100,
      "metadata": {
        "description": "Number of VM instances (100 or less)."
      }
    },
    "singlePlacementGroup": {
      "type": "bool",
      "defaultValue": true,
      "metadata": {
        "description": "When true this limits the scale set to a single placement group, of max size 100 virtual machines. NOTE: If singlePlacementGroup is true, it may be modified to false. However, if singlePlacementGroup is false, it may not be modified to true."
      }
    },
    "adminUsername": {
      "type": "string",
      "defaultValue": "vmssadmin",
      "metadata": {
        "description": "Admin username on all VMs."
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Admin password on all VMs."
      }
    },
    "_artifactsLocation": {
      "type": "string",
      "defaultValue": "[deployment().properties.templateLink.uri]",
      "metadata": {
        "description": "The base URI where artifacts required by this template are located. For example, if stored on a public GitHub repo, you'd use the following URI: https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/201-vmss-windows-webapp-dsc-autoscale/."
      }
    },
    "_artifactsLocationSasToken": {
      "type": "securestring",
      "defaultValue": "",
      "metadata": {
        "description": "The sasToken required to access _artifactsLocation.  If your artifacts are stored on a public repo or public storage account you can leave this blank."
      }
    },
    "powershelldscZip": {
      "type": "string",
      "defaultValue": "DSC/InstallIIS.zip",
      "metadata": {
        "description": "Location of the PowerShell DSC zip file relative to the URI specified in the _artifactsLocation, i.e. DSC/IISInstall.ps1.zip"
      }
    },
    "webDeployPackage": {
      "type": "string",
      "defaultValue": "WebDeploy/DefaultASPWebApp.v1.0.zip",
      "metadata": {
        "description": "Location of the  of the WebDeploy package zip file relative to the URI specified in _artifactsLocation, i.e. WebDeploy/DefaultASPWebApp.v1.0.zip"
      }
    },
    "powershelldscUpdateTagVersion": {
      "type": "string",
      "defaultValue": "1.0",
      "metadata": {
        "description": "Version number of the DSC deployment. Changing this value on subsequent deployments will trigger the extension to run."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location for all resources."
      }
    },
    "platformFaultDomainCount": {
      "type": "int",
      "defaultValue": 1,
      "metadata": {
        "description": "Fault Domain count for each placement group."
      }
    }
  },
  "variables": {
    "vmScaleSetName": "[toLower(substring(format('vmssName{0}', uniqueString(resourceGroup().id)), 0, 9))]",
    "longvmScaleSet": "[toLower(parameters('vmssName'))]",
    "addressPrefix": "10.0.0.0/16",
    "subnetPrefix": "10.0.0.0/24",
    "vNetName": "[format('{0}vnet', variables('vmScaleSetName'))]",
    "publicIPAddressName": "[format('{0}pip', variables('vmScaleSetName'))]",
    "subnetName": "[format('{0}subnet', variables('vmScaleSetName'))]",
    "loadBalancerName": "[format('{0}lb', variables('vmScaleSetName'))]",
    "publicIPAddressID": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]",
    "lbProbeID": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadBalancerName'), 'tcpProbe')]",
    "natPoolName": "[format('{0}natpool', variables('vmScaleSetName'))]",
    "bePoolName": "[format('{0}bepool', variables('vmScaleSetName'))]",
    "lbPoolID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), variables('bePoolName'))]",
    "natStartPort": 50000,
    "natEndPort": 50119,
    "natBackendPort": 3389,
    "nicName": "[format('{0}nic', variables('vmScaleSetName'))]",
    "ipConfigName": "[format('{0}ipconfig', variables('vmScaleSetName'))]",
    "frontEndIPConfigID": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), 'loadBalancerFrontEnd')]",
    "osType": {
      "publisher": "MicrosoftWindowsServer",
      "offer": "WindowsServer",
      "sku": "[parameters('windowsOSVersion')]",
      "version": "latest"
    },
    "securityProfileJson": {
      "uefiSettings": {
        "secureBootEnabled": true,
        "vTpmEnabled": true
      },
      "securityType": "[parameters('securityType')]"
    },
    "imageReference": "[variables('osType')]",
    "webDeployPackageFullPath": "[uri(parameters('_artifactsLocation'), format('{0}{1}', parameters('webDeployPackage'), parameters('_artifactsLocationSasToken')))]",
    "powershelldscZipFullPath": "[uri(parameters('_artifactsLocation'), format('{0}{1}', parameters('powershelldscZip'), parameters('_artifactsLocationSasToken')))]"
  },
  "resources": [
    {
      "type": "Microsoft.Network/loadBalancers",
      "apiVersion": "2023-04-01",
      "name": "[variables('loadBalancerName')]",
      "location": "[parameters('location')]",
      "properties": {
        "frontendIPConfigurations": [
          {
            "name": "LoadBalancerFrontEnd",
            "properties": {
              "publicIPAddress": {
                "id": "[variables('publicIPAddressID')]"
              }
            }
          }
        ],
        "backendAddressPools": [
          {
            "name": "[variables('bePoolName')]"
          }
        ],
        "inboundNatPools": [
          {
            "name": "[variables('natPoolName')]",
            "properties": {
              "frontendIPConfiguration": {
                "id": "[variables('frontEndIPConfigID')]"
              },
              "protocol": "Tcp",
              "frontendPortRangeStart": "[variables('natStartPort')]",
              "frontendPortRangeEnd": "[variables('natEndPort')]",
              "backendPort": "[variables('natBackendPort')]"
            }
          }
        ],
        "loadBalancingRules": [
          {
            "name": "LBRule",
            "properties": {
              "frontendIPConfiguration": {
                "id": "[variables('frontEndIPConfigID')]"
              },
              "backendAddressPool": {
                "id": "[variables('lbPoolID')]"
              },
              "protocol": "Tcp",
              "frontendPort": 80,
              "backendPort": 80,
              "enableFloatingIP": false,
              "idleTimeoutInMinutes": 5,
              "probe": {
                "id": "[variables('lbProbeID')]"
              }
            }
          }
        ],
        "probes": [
          {
            "name": "tcpProbe",
            "properties": {
              "protocol": "Tcp",
              "port": 80,
              "intervalInSeconds": 5,
              "numberOfProbes": 2
            }
          }
        ]
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName'))]"
      ]
    },
    {
      "type": "Microsoft.Compute/virtualMachineScaleSets",
      "apiVersion": "2023-09-01",
      "name": "[variables('vmScaleSetName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[parameters('vmSku')]",
        "tier": "Standard",
        "capacity": "[parameters('instanceCount')]"
      },
      "properties": {
        "overprovision": true,
        "upgradePolicy": {
          "mode": "Automatic"
        },
        "singlePlacementGroup": "[parameters('singlePlacementGroup')]",
        "platformFaultDomainCount": "[parameters('platformFaultDomainCount')]",
        "virtualMachineProfile": {
          "storageProfile": {
            "osDisk": {
              "caching": "ReadWrite",
              "createOption": "FromImage"
            },
            "imageReference": "[variables('imageReference')]"
          },
          "osProfile": {
            "computerNamePrefix": "[variables('vmScaleSetName')]",
            "adminUsername": "[parameters('adminUsername')]",
            "adminPassword": "[parameters('adminPassword')]"
          },
          "securityProfile": "[if(equals(parameters('securityType'), 'TrustedLaunch'), variables('securityProfileJson'), null())]",
          "networkProfile": {
            "networkInterfaceConfigurations": [
              {
                "name": "[variables('nicName')]",
                "properties": {
                  "primary": true,
                  "ipConfigurations": [
                    {
                      "name": "[variables('ipConfigName')]",
                      "properties": {
                        "subnet": {
                          "id": "[reference(resourceId('Microsoft.Network/virtualNetworks', variables('vNetName')), '2023-04-01').subnets[0].id]"
                        },
                        "loadBalancerBackendAddressPools": [
                          {
                            "id": "[variables('lbPoolID')]"
                          }
                        ]
                      }
                    }
                  ]
                }
              }
            ]
          },
          "extensionProfile": {
            "extensions": [
              {
                "name": "Microsoft.Powershell.DSC",
                "properties": {
                  "publisher": "Microsoft.Powershell",
                  "type": "DSC",
                  "typeHandlerVersion": "2.9",
                  "autoUpgradeMinorVersion": true,
                  "forceUpdateTag": "[parameters('powershelldscUpdateTagVersion')]",
                  "settings": {
                    "configuration": {
                      "url": "[variables('powershelldscZipFullPath')]",
                      "script": "InstallIIS.ps1",
                      "function": "InstallIIS"
                    },
                    "configurationArguments": {
                      "nodeName": "localhost",
                      "WebDeployPackagePath": "[variables('webDeployPackageFullPath')]"
                    }
                  }
                }
              }
            ]
          }
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', variables('vNetName'))]"
      ]
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2023-04-01",
      "name": "[variables('publicIPAddressName')]",
      "location": "[parameters('location')]",
      "properties": {
        "publicIPAllocationMethod": "Static",
        "dnsSettings": {
          "domainNameLabel": "[variables('longvmScaleSet')]"
        }
      }
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2023-04-01",
      "name": "[variables('vNetName')]",
      "location": "[parameters('location')]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[variables('addressPrefix')]"
          ]
        },
        "subnets": [
          {
            "name": "[variables('subnetName')]",
            "properties": {
              "addressPrefix": "[variables('subnetPrefix')]"
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Insights/autoscalesettings",
      "apiVersion": "2022-10-01",
      "name": "autoscalehost",
      "location": "[parameters('location')]",
      "properties": {
        "name": "autoscalehost",
        "targetResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('vmScaleSetName'))]",
        "enabled": true,
        "profiles": [
          {
            "name": "Profile1",
            "capacity": {
              "minimum": "1",
              "maximum": "10",
              "default": "1"
            },
            "rules": [
              {
                "metricTrigger": {
                  "metricName": "Percentage CPU",
                  "metricResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('vmScaleSetName'))]",
                  "timeGrain": "PT1M",
                  "statistic": "Average",
                  "timeWindow": "PT5M",
                  "timeAggregation": "Average",
                  "operator": "GreaterThan",
                  "threshold": 50
                },
                "scaleAction": {
                  "direction": "Increase",
                  "type": "ChangeCount",
                  "value": "1",
                  "cooldown": "PT5M"
                }
              },
              {
                "metricTrigger": {
                  "metricName": "Percentage CPU",
                  "metricResourceUri": "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('vmScaleSetName'))]",
                  "timeGrain": "PT1M",
                  "statistic": "Average",
                  "timeWindow": "PT5M",
                  "timeAggregation": "Average",
                  "operator": "LessThan",
                  "threshold": 30
                },
                "scaleAction": {
                  "direction": "Decrease",
                  "type": "ChangeCount",
                  "value": "1",
                  "cooldown": "PT5M"
                }
              }
            ]
          }
        ]
      },
      "dependsOn": [
        "[resourceId('Microsoft.Compute/virtualMachineScaleSets', variables('vmScaleSetName'))]"
      ]
    }
  ],
  "outputs": {
    "applicationUrl": {
      "type": "string",
      "value": "[uri(format('http://{0}', reference(resourceId('Microsoft.Network/publicIPAddresses', variables('publicIPAddressName')), '2023-04-01').dnsSettings.fqdn), '/MyApp')]"
    }
  }
}

Deze resources worden in deze sjablonen gedefinieerd:

Een schaalset definiëren

Als u een schaal wilt maken met behulp van een sjabloon, definieert u de juiste resources. De kernonderdelen van het resourcetype Virtuele-machineschaalset zijn:

Eigenschappen Beschrijving van eigenschap Voorbeeldwaarde van sjabloon
type Azure-resourcetype dat moet worden gemaakt Microsoft.Compute/virtualMachineScaleSets
naam De naam van de schaalset myScaleSet
locatie De locatie voor het maken van de schaalset VS - oost
sku.name De VM-grootte voor elke instantie van de schaalset Standard_A1
sku.capacity Het aantal VM-instanties dat in het begin moet worden gemaakt 2
upgradePolicy.mode Upgrademodus voor VM-instantie wanneer er wijzigingen optreden Automatisch
imageReference Het platform of de aangepaste afbeelding die moet worden gebruikt voor de VM-instanties Microsoft Windows Server 2016 Datacenter
osProfile.computerNamePrefix Het naamvoorvoegsel voor elke VM-instantie myvmss
osProfile.adminUsername De gebruikersnaam voor elke VM-instantie azureuser
osProfile.adminPassword Het wachtwoord voor elke VM-instantie P@ssw0rd!

Als u een schaalsetsjabloon wilt aanpassen, kunt u de VM-grootte of initiële capaciteit wijzigen. Een andere mogelijkheid is om een ander platform of een aangepaste afbeelding te gebruiken.

Voorbeeldtoepassing toevoegen

Als u de schaalset wilt testen, installeert u een eenvoudige webtoepassing. Wanneer u een schaalset implementeert, kunnen VM-extensies worden gebruikt voor configuratie- en automatiseringstaken na de implementatie, zoals het installeren van een app. Scripts kunnen worden gedownload uit Azure Storage of GitHub, of worden geleverd in Azure Portal tijdens de uitvoering van extensies. Als u een extensie wilt toepassen op uw schaalset, voegt u de sectie extensionProfile toe aan het voorgaande resourcevoorbeeld. Met het extensieprofiel worden doorgaans de volgende eigenschappen gedefinieerd:

  • Type extensie
  • Uitgever van de extensie
  • Versie van de extensie
  • Locatie van de configuratie of installatiescripts
  • Opdrachten om uit te voeren op de VM-instanties

De sjabloon maakt gebruik van de PowerShell DSC-extensie om een ASP.NET MVC-app te installeren die wordt uitgevoerd in IIS.

Er wordt een installatiescript gedownload uit GitHub, zoals gedefinieerd in URL. Met de extensie wordt vervolgens InstallIIS uitgevoerd vanuit het script IISInstall.ps1, zoals gedefinieerd in Functie en Script. De ASP.NET-app zelf wordt geleverd als een Web Deploy-pakket, dat ook kan worden gedownload uit GitHub, zoals gedefinieerd in WebDeployPackagePath:

De sjabloon implementeren

U kunt de sjabloon implementeren door de knop Implementeren op Azure te selecteren. Met deze knop wordt Azure Portal geopend, de volledige sjabloon geladen, en wordt u gevraagd om een aantal parameters op te geven, zoals een naam voor de schaalset, het aantal instanties en de beheerdersreferenties.

Button to deploy the Resource Manager template to Azure.

U kunt ook een Resource Manager-sjabloon implementeren met Azure PowerShell:

# Create a resource group
New-AzResourceGroup -Name myResourceGroup -Location EastUS

# Deploy template into resource group
New-AzResourceGroupDeployment `
    -ResourceGroupName myResourceGroup `
    -TemplateURI https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/demos/vmss-windows-webapp-dsc-autoscale/azuredeploy.json

# Update the scale set and apply the extension
Update-AzVmss `
    -ResourceGroupName myResourceGroup `
    -VmScaleSetName myVMSS `
    -VirtualMachineScaleSet $vmssConfig

Geef de waarden op voor de naam van de schaalset en de beheerdersreferenties voor de VM-instanties, wanneer u hierom wordt gevraagd. Het kan 10-15 minuten duren voordat de schaalset is gemaakt en de extensie is toegepast om de app te configureren.

De implementatie valideren

U kunt de schaalset in actie zien door in een webbrowser naar de voorbeeldwebtoepassing te gaan. Gebruik Get-AzPublicIpAddress als volgt om het openbare IP-adres van uw load balancer op te vragen:

Get-AzPublicIpAddress -ResourceGroupName myResourceGroup | Select IpAddress

Voer het openbare IP-adres van de load balancer in een webbrowser in. Gebruik hiervoor de notatie http://publicIpAddress/MyApp. Via de load balancer wordt verkeer naar een van uw VM-instanties gedistribueerd, zoals wordt weergegeven in het volgende voorbeeld:

Running IIS site

Resources opschonen

U kunt de opdracht Remove-AzResourceGroup gebruiken om de resourcegroep, schaalset en alle gerelateerde resources te verwijderen wanneer u ze niet meer nodig hebt. De parameter -Force bevestigt dat u de resources wilt verwijderen, zonder een extra prompt om dit te doen. De parameter -AsJob retourneert het besturingselement naar de prompt zonder te wachten totdat de bewerking is voltooid.

Remove-AzResourceGroup -Name "myResourceGroup" -Force -AsJob

Volgende stappen

In deze snelstartgids hebt u een Windows-schaalset gemaakt met behulp van een ARM-sjabloon en de PowerShell DSC-extensie gebruikt om een standaard ASP.NET-app te installeren op de VM-instanties. Voor meer informatie gaat u verder met de zelfstudie voor het maken en beheren van Virtuele-machineschaalsets van Azure.