Azure Resource Manager 模板中的虚拟机Virtual machines in an Azure Resource Manager template

本文介绍 Azure Resource Manager 模板中与虚拟机相关的方面。This article describes aspects of an Azure Resource Manager template that apply to virtual machines. 本文不会介绍用于创建虚拟机的完整模板;在完整的模板中,需要提供存储帐户、网络接口、公共 IP 地址和虚拟网络的资源定义。This article doesn't describe a complete template for creating a virtual machine; for that you need resource definitions for storage accounts, network interfaces, public IP addresses, and virtual networks. 有关如何统一定义这些资源的详细信息,请参阅 Resource Manager 模板演练For more information about how these resources can be defined together, see the Resource Manager template walkthrough.

在库中 有许多包含 VM 资源的模板。There are many templates in the gallery that include the VM resource. 本文并未介绍可在模板中包含的所有元素。Not all elements that can be included in a template are described here.

Note

本文进行了更新,以便使用新的 Azure PowerShell Az 模块。This article has been updated to use the new Azure PowerShell Az module. 你仍然可以使用 AzureRM 模块,至少在 2020 年 12 月之前,它将继续接收 bug 修补程序。You can still use the AzureRM module, which will continue to receive bug fixes until at least December 2020. 若要详细了解新的 Az 模块和 AzureRM 兼容性,请参阅新 Azure Powershell Az 模块简介To learn more about the new Az module and AzureRM compatibility, see Introducing the new Azure PowerShell Az module. 有关 Az 模块安装说明,请参阅安装 Azure PowerShellFor Az module installation instructions, see Install Azure PowerShell.

本示例演示了模板中用于创建指定数量的 VM 的典型资源节:This example shows a typical resource section of a template for creating a specified number of VMs:

"resources": [
  { 
    "apiVersion": "2016-04-30-preview", 
    "type": "Microsoft.Compute/virtualMachines", 
    "name": "[concat('myVM', copyindex())]", 
    "location": "[resourceGroup().location]",
    "copy": {
      "name": "virtualMachineLoop", 
      "count": "[parameters('numberOfInstances')]"
    },
    "dependsOn": [
      "[concat('Microsoft.Network/networkInterfaces/myNIC', copyindex())]" 
    ], 
    "properties": { 
      "hardwareProfile": { 
        "vmSize": "Standard_DS1" 
      }, 
      "osProfile": { 
        "computername": "[concat('myVM', copyindex())]", 
        "adminUsername": "[parameters('adminUsername')]", 
        "adminPassword": "[parameters('adminPassword')]" 
      }, 
      "storageProfile": { 
        "imageReference": { 
          "publisher": "MicrosoftWindowsServer", 
          "offer": "WindowsServer", 
          "sku": "2012-R2-Datacenter", 
          "version": "latest" 
        }, 
        "osDisk": { 
          "name": "[concat('myOSDisk', copyindex())]",
          "caching": "ReadWrite", 
          "createOption": "FromImage" 
        },
        "dataDisks": [
          {
            "name": "[concat('myDataDisk', copyindex())]",
            "diskSizeGB": "100",
            "lun": 0,
            "createOption": "Empty"
          }
        ] 
      }, 
      "networkProfile": { 
        "networkInterfaces": [ 
          { 
            "id": "[resourceId('Microsoft.Network/networkInterfaces',
              concat('myNIC', copyindex()))]" 
          } 
        ] 
      },
      "diagnosticsProfile": {
        "bootDiagnostics": {
          "enabled": "true",
          "storageUri": "[concat('https://', variables('storageName'), '.blob.core.chinacloudapi.cn')]"
        }
      } 
    },
    "resources": [ 
      { 
        "name": "Microsoft.Insights.VMDiagnosticsSettings", 
        "type": "extensions", 
        "location": "[resourceGroup().location]", 
        "apiVersion": "2016-03-30", 
        "dependsOn": [ 
          "[concat('Microsoft.Compute/virtualMachines/myVM', copyindex())]" 
        ], 
        "properties": { 
          "publisher": "Microsoft.Azure.Diagnostics", 
          "type": "IaaSDiagnostics", 
          "typeHandlerVersion": "1.5", 
          "autoUpgradeMinorVersion": true, 
          "settings": { 
            "xmlCfg": "[base64(concat(variables('wadcfgxstart'), 
            variables('wadmetricsresourceid'), 
            concat('myVM', copyindex()),
            variables('wadcfgxend')))]", 
            "storageAccount": "[variables('storageName')]" 
          }, 
          "protectedSettings": { 
            "storageAccountName": "[variables('storageName')]", 
            "storageAccountKey": "[listkeys(variables('accountid'), 
              '2015-06-15').key1]", 
            "storageAccountEndPoint": "https://core.chinacloudapi.cn" 
          } 
        } 
      },
      {
        "name": "MyCustomScriptExtension",
        "type": "extensions",
        "apiVersion": "2016-03-30",
        "location": "[resourceGroup().location]",
        "dependsOn": [
          "[concat('Microsoft.Compute/virtualMachines/myVM', copyindex())]"
        ],
        "properties": {
          "publisher": "Microsoft.Compute",
          "type": "CustomScriptExtension",
          "typeHandlerVersion": "1.7",
          "autoUpgradeMinorVersion": true,
          "settings": {
            "fileUris": [
              "[concat('https://', variables('storageName'),
                '.blob.core.chinacloudapi.cn/customscripts/start.ps1')]" 
            ],
            "commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File start.ps1"
          }
        }
      } 
    ]
  } 
]

Note

本示例依赖于前面创建的存储帐户。This example relies on a storage account that was previously created. 可通过在模板中部署存储帐户来创建存储帐户。You could create the storage account by deploying it from the template. 本示例还依赖于在模板中定义的网络接口及其相关资源。The example also relies on a network interface and its dependent resources that would be defined in the template. 本示例未显示这些资源。These resources are not shown in the example.

API 版本API Version

使用模板部署资源时,必须指定要使用的 API 版本。When you deploy resources using a template, you have to specify a version of the API to use. 本示例使用以下 apiVersion 元素显示虚拟机资源:The example shows the virtual machine resource using this apiVersion element:

"apiVersion": "2016-04-30-preview",

在模板中指定的 API 版本会影响到可在模板中定义的属性。The version of the API you specify in your template affects which properties you can define in the template. 通常,在创建模板时,应选择最新的 API 版本。In general, you should select the most recent API version when creating templates. 对于现有模板,可以决定是要继续使用以前的 API 版本,还是要选择最新版本来更新模板以利用新功能。For existing templates, you can decide whether you want to continue using an earlier API version, or update your template for the latest version to take advantage of new features.

可通过以下方式获取最新的 API 版本:Use these opportunities for getting the latest API versions:

Note

在 Azure China 中使用 Azure CLI 2.0 之前,请首先运行 az cloud set -n AzureChinaCloud 更改云环境。Before you can use Azure CLI 2.0 in Azure China, please run az cloud set -n AzureChinaCloud first to change the cloud environment. 如果要切换回全局 Azure,请再次运行 az cloud set -n AzureCloudIf you want to switch back to Global Azure, run az cloud set -n AzureCloud again.

参数和变量Parameters and variables

使用参数可在运行模板时轻松指定模板值。Parameters make it easy for you to specify values for the template when you run it. 本示例使用了以下 parameters 节:This parameters section is used in the example:

"parameters": {
  "adminUsername": { "type": "string" },
  "adminPassword": { "type": "securestring" },
  "numberOfInstances": { "type": "int" }
},

部署示例模板时,需输入每个 VM 上的管理员帐户的名称与密码值,以及要创建的 VM 数目。When you deploy the example template, you enter values for the name and password of the administrator account on each VM and the number of VMs to create. 可以选择在使用模板管理的单独文件中指定参数值,或者根据提示提供值。You have the option of specifying parameter values in a separate file that's managed with the template, or providing values when prompted.

使用变量可以轻松设置在整个模板中重复使用的值,或者可随时变化的值。Variables make it easy for you to set up values in the template that are used repeatedly throughout it or that can change over time. 本示例使用了以下 variables 节:This variables section is used in the example:

"variables": { 
  "storageName": "mystore1",
  "accountid": "[concat('/subscriptions/', subscription().subscriptionId, 
    '/resourceGroups/', resourceGroup().name,
  '/providers/','Microsoft.Storage/storageAccounts/', variables('storageName'))]", 
  "wadlogs": "<WadCfg> 
    <DiagnosticMonitorConfiguration overallQuotaInMB=\"4096\" xmlns=\"http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration\"> 
      <DiagnosticInfrastructureLogs scheduledTransferLogLevelFilter=\"Error\"/> 
      <WindowsEventLog scheduledTransferPeriod=\"PT1M\" > 
        <DataSource name=\"Application!*[System[(Level = 1 or Level = 2)]]\" /> 
        <DataSource name=\"Security!*[System[(Level = 1 or Level = 2)]]\" /> 
        <DataSource name=\"System!*[System[(Level = 1 or Level = 2)]]\" />
      </WindowsEventLog>", 
  "wadperfcounters": "<PerformanceCounters scheduledTransferPeriod=\"PT1M\">
      <PerformanceCounterConfiguration counterSpecifier=\"\\Process(_Total)\\Thread Count\" sampleRate=\"PT15S\" unit=\"Count\">
        <annotation displayName=\"Threads\" locale=\"en-us\"/>
      </PerformanceCounterConfiguration>
    </PerformanceCounters>", 
  "wadcfgxstart": "[concat(variables('wadlogs'), variables('wadperfcounters'), 
    '<Metrics resourceId=\"')]", 
  "wadmetricsresourceid": "[concat('/subscriptions/', subscription().subscriptionId, 
    '/resourceGroups/', resourceGroup().name , 
    '/providers/', 'Microsoft.Compute/virtualMachines/')]", 
  "wadcfgxend": "\"><MetricAggregation scheduledTransferPeriod=\"PT1H\"/>
    <MetricAggregation scheduledTransferPeriod=\"PT1M\"/>
    </Metrics></DiagnosticMonitorConfiguration>
    </WadCfg>"
}, 

部署示例模板时,先前创建的存储帐户的名称和标识符将使用变量值。When you deploy the example template, variable values are used for the name and identifier of the previously created storage account. 变量还用于提供诊断扩展的设置。Variables are also used to provide the settings for the diagnostic extension. 请参阅创建 Azure Resource Manager 模板的最佳实践来帮助自己确定如何构造模板中的参数和变量。Use the best practices for creating Azure Resource Manager templates to help you decide how you want to structure the parameters and variables in your template.

资源循环Resource loops

如果需要为应用程序创建多个虚拟机,可在模板中使用 copy 元素。When you need more than one virtual machine for your application, you can use a copy element in a template. 此可选元素根据以参数形式指定的数目反复创建 VM:This optional element loops through creating the number of VMs that you specified as a parameter:

"copy": {
  "name": "virtualMachineLoop", 
  "count": "[parameters('numberOfInstances')]"
},

另请注意,在本示例中,为资源指定某些值时使用了循环索引。Also, notice in the example that the loop index is used when specifying some of the values for the resource. 例如,如果输入实例计数 3,则操作系统磁盘的名称是 myOSDisk1、myOSDisk2 和 myOSDisk3:For example, if you entered an instance count of three, the names of the operating system disks are myOSDisk1, myOSDisk2, and myOSDisk3:

"osDisk": { 
  "name": "[concat('myOSDisk', copyindex())]",
  "caching": "ReadWrite", 
  "createOption": "FromImage" 
}

Note

此示例将托管磁盘用于虚拟机。This example uses managed disks for the virtual machines.

请记住,如果为模板中的一个资源创建了循环,则创建或访问其他资源时,可能需要使用该循环。Keep in mind that creating a loop for one resource in the template may require you to use the loop when creating or accessing other resources. 例如,多个 VM 不能使用同一个网络接口,因此,如果模板反复创建三个 VM,则它也必须反复创建三个网络接口。For example, multiple VMs can't use the same network interface, so if your template loops through creating three VMs it must also loop through creating three network interfaces. 将网络接口分配到 VM 时,会使用循环索引来标识该接口:When assigning a network interface to a VM, the loop index is used to identify it:

"networkInterfaces": [ { 
  "id": "[resourceId('Microsoft.Network/networkInterfaces',
    concat('myNIC', copyindex()))]" 
} ]

依赖项Dependencies

大多数资源必须依赖于其他资源才能正常工作。Most resources depend on other resources to work correctly. 虚拟机必须与虚拟网络相关联,因此需要一个网络接口。Virtual machines must be associated with a virtual network and to do that it needs a network interface. dependsOn 元素用于确保在创建 VM 之前,网络接口随时可供使用:The dependsOn element is used to make sure that the network interface is ready to be used before the VMs are created:

"dependsOn": [
  "[concat('Microsoft.Network/networkInterfaces/', 'myNIC', copyindex())]" 
],

资源管理器将并行部署所有不依赖于其他所要部署的资源的资源。Resource Manager deploys in parallel any resources that aren't dependent on another resource being deployed. 请谨慎设置依赖关系,因为可能会无意中指定不必要的依赖关系,导致部署速度变慢。Be careful when setting dependencies because you can inadvertently slow your deployment by specifying unnecessary dependencies. 多个资源的依赖关系可能会串联在一起。Dependencies can chain through multiple resources. 例如,网络接口依赖于公共 IP 地址和虚拟网络资源。For example, the network interface depends on the public IP address and virtual network resources.

如何知道是否需要指定依赖关系?How do you know if a dependency is required? 查看模板中设置的值即可。Look at the values you set in the template. 如果虚拟机资源定义中的某个元素指向同一模板中部署的另一个资源,则需要指定依赖关系。If an element in the virtual machine resource definition points to another resource that is deployed in the same template, you need a dependency. 例如,示例虚拟机定义了一个网络配置文件:For example, your example virtual machine defines a network profile:

"networkProfile": { 
  "networkInterfaces": [ { 
    "id": "[resourceId('Microsoft.Network/networkInterfaces',
      concat('myNIC', copyindex())]" 
  } ] 
},

若要设置此属性,网络接口必须存在。To set this property, the network interface must exist. 因此,需要指定依赖关系。Therefore, you need a dependency. 如果在一个资源(父级)内部定义了另一个资源(子级),则也需要设置依赖关系。You also need to set a dependency when one resource (a child) is defined within another resource (a parent). 例如,诊断设置和自定义脚本扩展都定义为虚拟机的子资源。For example, the diagnostic settings and custom script extensions are both defined as child resources of the virtual machine. 只有存在该虚拟机时,才能创建这些子资源。They can't be created until the virtual machine exists. 因此,这两个资源都标记为依赖于该虚拟机。Therefore, both resources are marked as dependent on the virtual machine.

配置文件Profiles

定义虚拟机资源时,需要使用几个 profile 元素。Several profile elements are used when defining a virtual machine resource. 其中一些元素是必需的,还有一些是可选的。Some are required and some are optional. 例如,hardwareProfile、osProfile、storageProfile 和 networkProfile 元素是必需的,而 diagnosticsProfile 是可选的。For example, the hardwareProfile, osProfile, storageProfile, and networkProfile elements are required, but the diagnosticsProfile is optional. 这些配置文件定义如下所述的设置:These profiles define settings such as:

磁盘和映像Disks and images

在 Azure 中,vhd 文件可以表示磁盘或映像In Azure, vhd files can represent disks or images. 如果 vhd 文件中的操作系统专用于特定 VM,则该文件称为磁盘。When the operating system in a vhd file is specialized to be a specific VM, it's referred to as a disk. 如果 vhd 文件中的操作系统经过通用化,用于创建多个 VM,则该文件称为映像。When the operating system in a vhd file is generalized to be used to create many VMs, it's referred to as an image.

从平台映像创建新虚拟机和新磁盘Create new virtual machines and new disks from a platform image

创建 VM 时,必须确定要使用哪个操作系统。When you create a VM, you must decide what operating system to use. imageReference 元素用于定义新 VM 的操作系统。The imageReference element is used to define the operating system of a new VM. 本示例显示了 Windows Server 操作系统的定义:The example shows a definition for a Windows Server operating system:

"imageReference": { 
  "publisher": "MicrosoftWindowsServer", 
  "offer": "WindowsServer", 
  "sku": "2012-R2-Datacenter", 
  "version": "latest" 
},

若要创建 Linux 操作系统,可使用以下定义:If you want to create a Linux operating system, you might use this definition:

"imageReference": {
  "publisher": "Canonical",
  "offer": "UbuntuServer",
  "sku": "14.04.2-LTS",
  "version": "latest"
},

操作系统磁盘的配置设置是使用 osDisk 元素分配的。Configuration settings for the operating system disk are assigned with the osDisk element. 此示例定义了一个新的托管磁盘,其缓存模式设置为 ReadWrite,并且该磁盘是从平台映像创建的:The example defines a new managed disk with the caching mode set to ReadWrite and that the disk is being created from a platform image:

"osDisk": { 
  "name": "[concat('myOSDisk', copyindex())]",
  "caching": "ReadWrite", 
  "createOption": "FromImage" 
},

从现有托管磁盘创建新虚拟机Create new virtual machines from existing managed disks

如果要从现有磁盘创建虚拟机,请删除 imageReference 和 osProfile 元素,并定义以下磁盘设置:If you want to create virtual machines from existing disks, remove the imageReference and the osProfile elements and define these disk settings:

"osDisk": { 
  "osType": "Windows",
  "managedDisk": { 
    "id": "[resourceId('Microsoft.Compute/disks', [concat('myOSDisk', copyindex())])]" 
  }, 
  "caching": "ReadWrite",
  "createOption": "Attach" 
},

从托管映像创建新虚拟机Create new virtual machines from a managed image

如果要从托管映像创建虚拟机,请更改 imageReference 元素,并定义以下磁盘设置:If you want to create a virtual machine from a managed image, change the imageReference element and define these disk settings:

"storageProfile": { 
  "imageReference": {
    "id": "[resourceId('Microsoft.Compute/images', 'myImage')]"
  },
  "osDisk": { 
    "name": "[concat('myOSDisk', copyindex())]",
    "osType": "Windows",
    "caching": "ReadWrite", 
    "createOption": "FromImage" 
  }
},

附加数据磁盘Attach data disks

可以选择将数据磁盘添加到 VM。You can optionally add data disks to the VMs. 磁盘数目取决于要使用的操作系统磁盘的大小。The number of disks depends on the size of operating system disk that you use. 如果 VM 的大小设置为 Standard_DS1_v2,则可添加到 VM 的数据磁盘数目上限为 2。With the size of the VMs set to Standard_DS1_v2, the maximum number of data disks that could be added to the them is two. 在本示例中,将向每个 VM 添加一个托管数据磁盘:In the example, one managed data disk is being added to each VM:

"dataDisks": [
  {
    "name": "[concat('myDataDisk', copyindex())]",
    "diskSizeGB": "100",
    "lun": 0, 
    "caching": "ReadWrite",
    "createOption": "Empty"
  }
],

扩展Extensions

尽管扩展是独立的资源,但它们与 VM 密切相关。Although extensions are a separate resource, they're closely tied to VMs. 可将扩展添加为 VM 的子资源,或添加为独立的资源。Extensions can be added as a child resource of the VM or as a separate resource. 本示例显示添加到 VM 的诊断扩展The example shows the Diagnostics Extension being added to the VMs:

{ 
  "name": "Microsoft.Insights.VMDiagnosticsSettings", 
  "type": "extensions", 
  "location": "[resourceGroup().location]", 
  "apiVersion": "2016-03-30", 
  "dependsOn": [ 
    "[concat('Microsoft.Compute/virtualMachines/myVM', copyindex())]" 
  ], 
  "properties": { 
    "publisher": "Microsoft.Azure.Diagnostics", 
    "type": "IaaSDiagnostics", 
    "typeHandlerVersion": "1.5", 
    "autoUpgradeMinorVersion": true, 
    "settings": { 
      "xmlCfg": "[base64(concat(variables('wadcfgxstart'), 
      variables('wadmetricsresourceid'), 
      concat('myVM', copyindex()),
      variables('wadcfgxend')))]", 
      "storageAccount": "[variables('storageName')]" 
    }, 
    "protectedSettings": { 
      "storageAccountName": "[variables('storageName')]", 
      "storageAccountKey": "[listkeys(variables('accountid'), 
        '2015-06-15').key1]", 
      "storageAccountEndPoint": "https://core.chinacloudapi.cn" 
    } 
  } 
},

此扩展资源使用 storageName 变量和 diagnostic 变量来提供值。This extension resource uses the storageName variable and the diagnostic variables to provide values. 要更改此扩展收集的数据,可将更多的性能计数器添加到 wadperfcounters 变量。If you want to change the data that is collected by this extension, you can add more performance counters to the wadperfcounters variable. 还可以选择将诊断数据放入其他存储帐户,而不是 VM 磁盘所在的存储帐户。You could also choose to put the diagnostics data into a different storage account than where the VM disks are stored.

可在 VM 上安装许多扩展,但最有用的扩展也许是自定义脚本扩展There are many extensions that you can install on a VM, but the most useful is probably the Custom Script Extension. 在本示例中,首次启动每个 VM 时,会在 VM 上运行名为 start.ps1 的 PowerShell 脚本:In the example, a PowerShell script named start.ps1 runs on each VM when it first starts:

{
  "name": "MyCustomScriptExtension",
  "type": "extensions",
  "apiVersion": "2016-03-30",
  "location": "[resourceGroup().location]",
  "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/myVM', copyindex())]"
  ],
  "properties": {
    "publisher": "Microsoft.Compute",
    "type": "CustomScriptExtension",
    "typeHandlerVersion": "1.7",
    "autoUpgradeMinorVersion": true,
    "settings": {
      "fileUris": [
        "[concat('https://', variables('storageName'),
          '.blob.core.chinacloudapi.cn/customscripts/start.ps1')]" 
      ],
      "commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File start.ps1"
    }
  }
}

start.ps1 脚本可以完成许多配置任务。The start.ps1 script can accomplish many configuration tasks. 例如,在本示例中已添加到 VM 的数据磁盘并未初始化;这些数据磁盘可以使用自定义脚本进行初始化。For example, the data disks that are added to the VMs in the example aren't initialized; you can use a custom script to initialize them. 如果要执行多个启动任务,可在 Azure 存储中使用 start.ps1 文件调用其他 PowerShell 脚本。If you have multiple startup tasks to do, you can use the start.ps1 file to call other PowerShell scripts in Azure storage. 本示例使用 PowerShell,但你可以使用目前所用的操作系统支持的任何脚本方法。The example uses PowerShell, but you can use any scripting method that is available on the operating system that you're using.

可在门户中通过“扩展”设置查看已安装的扩展的状态:You can see the status of the installed extensions from the Extensions settings in the portal:

获取扩展状态

此外,也可以使用 Get-AzVMExtension PowerShell 命令、vm extension get Azure CLI 命令或“获取扩展信息”REST API 来获取扩展信息。You can also get extension information by using the Get-AzVMExtension PowerShell command, the vm extension get Azure CLI command, or the Get extension information REST API.

部署Deployments

部署模板时,Azure 会跟踪以组的形式部署的资源,并自动为这个部署的组分配一个名称。When you deploy a template, Azure tracks the resources that you deployed as a group and automatically assigns a name to this deployed group. 部署名称与模板名称相同。The name of the deployment is the same as the name of the template.

如果很想知道部署中的资源状态,则可在 Azure 门户中查看资源组:If you're curious about the status of resources in the deployment, view the resource group in the Azure portal:

获取部署信息

完全可以使用同一个模板来创建资源或更新现有资源。It's not a problem to use the same template to create resources or to update existing resources. 使用命令部署模板时,可以指定想要使用的模式When you use commands to deploy templates, you have the opportunity to say which mode you want to use. 模式可设置为“完整”(Complete) 或“增量”(Incremental)。The mode can be set to either Complete or Incremental. 默认设置为执行增量更新。The default is to do incremental updates. 请谨慎使用“完整”模式,因为这可能会意外删除资源。Be careful when using the Complete mode because you may accidentally delete resources. 在模式设置为“完整”时,资源管理器会删除资源组中不包含在模板内的所有资源。When you set the mode to Complete, Resource Manager deletes any resources in the resource group that aren't in the template.

后续步骤Next Steps