快速入門:使用ARM範本建立 Windows 虛擬機擴展集

適用於:✔️ Windows VM ✔️ 統一擴展集

注意

下列文章適用於統一 虛擬機器擴展集。 建議您將彈性虛擬機器擴展集用於新的工作負載。 在我們的彈性虛擬機器擴展集概觀中,深入了解這個新的協調流程模式。

虛擬機擴展集可讓您部署和管理一組自動調整虛擬機。 您可以手動調整擴展集中的 VM 數目,或根據 CPU、記憶體需求或網路流量等資源使用量來定義自動調整的規則。 然後,Azure 負載平衡器會將流量分散到擴展集中的 VM 實例。 在本快速入門中,您會建立虛擬機擴展集,並使用 Azure Resource Manager 範本部署範例應用程式(ARM 範本)。

Azure Resource Manager 範本是 JavaScript 物件表示法 (JSON) 檔案,可定義專案的基礎結構和組態。 範本使用宣告式語法。 您不需要撰寫程式設計命令順序來建立部署,即可描述預定的部署。

ARM 範本可讓您部署相關資源的群組。 在單一範本中,您可以建立虛擬機擴展集、安裝應用程式,以及設定自動調整規則。 使用變數和參數時,可以重複使用此範本來更新現有的擴展集,或建立其他擴展集。 您可以透過 Azure 入口網站、Azure CLI、Azure PowerShell,或從持續整合/持續傳遞 (CI/CD) 管線部署範本。

如果您的環境符合必要條件,而且您很熟悉 ARM 範本,請選取 [部署至 Azure] 按鈕。 範本會在 Azure 入口網站中開啟。

Button to deploy the Resource Manager template to Azure.

必要條件

如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶

檢閱範本

本快速入門中使用的範本來自 Azure 快速入門範本

{
  "$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')]"
    }
  }
}

這些資源定義在這些樣本中:

定義擴展集

若要使用範本建立縮放比例,您可以定義適當的資源。 虛擬機擴展集資源類型的核心部分包括:

屬性 屬性的描述 範例範本值
type 要建立的 Azure 資源類型 Microsoft.Compute/virtualMachineScaleSets
NAME 擴展集名稱 myScaleSet
location 建立擴展集的位置 美國東部
sku.name 每個擴展集實例的 VM 大小 標準_A1
sku.capacity 要最初建立的 VM 實例數目 2
upgradePolicy.mode 發生變更時 VM 實例升級模式 自動
imageReference 要用於 VM 實例的平臺或自定義映像 Microsoft Windows Server 2016 Datacenter
osProfile.computerNamePrefix 每個 VM 實例的名稱前置詞 myvmss
osProfile.adminUsername 每個 VM 實例的用戶名稱 azureuser
osProfile.adminPassword 每個 VM 實例的密碼 P@ssw0rd!

若要自定義擴展集範本,您可以變更 VM 大小或初始容量。 另一個選項是使用不同的平臺或自定義映像。

新增範例應用程式

若要測試擴展集,請安裝基本的 Web 應用程式。 當您部署擴展集時,VM 擴充功能可以提供部署後設定和自動化工作,例如安裝應用程式。 您可以從 Azure 儲存體或 GitHub 下載指令碼,或是在擴充功能執行階段將指令碼提供給 Azure 入口網站。 若要將擴充功能套用至擴展集,請將 extensionProfile 區段新增至上述資源範例。 延伸模組設定檔通常會定義下列屬性:

  • 擴充功能類型
  • 延伸模組發行者
  • 延伸模組版本
  • 設定或安裝腳本的位置
  • 在 VM 實例上執行的命令

此範本會使用 PowerShell DSC 擴充功能來安裝在 IIS 中執行的 ASP.NET MVC 應用程式。

從 GitHub 下載安裝文稿,如 URL 中所定義。 擴充功能接著會從 IISInstall.ps1 腳本執行 InstallIIS,如函式腳本中所定義。 ASP.NET 應用程式本身會以 Web Deploy 套件的形式提供,此套件也會從 GitHub 下載,如 WebDeployPackagePath 中所定義:

部署範本

您可以選取 [ 部署至 Azure ] 按鈕來部署範本。 此按鈕會開啟 Azure 入口網站、載入完整的範本,並提示輸入幾個參數,例如擴展集名稱、實例計數和系統管理員認證。

Button to deploy the Resource Manager template to Azure.

您也可以使用 Azure PowerShell 來部署 Resource Manager 範本:

# 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

回答提示,以提供 VM 實例的擴展集名稱和系統管理員認證。 建立擴展集可能需要 10-15 分鐘的時間,並套用擴充功能來設定應用程式。

驗證部署

若要查看您的擴充集運作情形,請在網頁瀏覽器中存取範例 Web 應用程式。 使用 Get-AzPublicIpAddress 取得負載平衡器的公用 IP 位址,如下所示:

Get-AzPublicIpAddress -ResourceGroupName myResourceGroup | Select IpAddress

以格式 http://publicIpAddress/MyApp輸入負載平衡器的公用IP位址至網頁瀏覽器。 負載平衡器會將流量散發至您的其中一個 VM 執行個體,如下列範例所示:

Running IIS site

清除資源

不再需要時,您可以使用 Remove-AzResourceGroup 來移除資源群組擴展集。 -Force 參數會確認您想要刪除資源,而不另外對您提示將要進行此作業。 -AsJob 參數不會等待作業完成,就會將控制項傳回給提示字元。

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

下一步

在本快速入門中,您已使用ARM範本建立 Windows 擴展集,並使用PowerShell DSC 擴充功能在 VM 實例上安裝基本 ASP.NET 應用程式。 若要深入瞭解,請繼續進行教學課程,以瞭解如何建立和管理 Azure 虛擬機器擴展集。