Proposed Pull Request Change

title description ms.topic ms.date ms.service zone_pivot_groups ms.subservice ms.author ms.reviewer author ms.custom
Create a virtual machine on VMware vCenter using Infrastructure as Code methods In this quickstart, you learn how to create a virtual machine on VMware vCenter using Azure Arc tutorial 02/10/2026 azure-arc vmware-bicep-terraform azure-arc-vmware-vsphere v-gajeronika v-gajeronika Jeronika-MS ['build-2025']
📄 Document Links
GitHub View on GitHub Microsoft Learn View on Microsoft Learn
Content Truncation Detected
The generated rewrite appears to be incomplete.
Original lines: -
Output lines: -
Ratio: -
Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
+0 -0
+0 -0
--- title: Create a virtual machine on VMware vCenter using Infrastructure as Code methods description: In this quickstart, you learn how to create a virtual machine on VMware vCenter using Azure Arc ms.topic: tutorial ms.date: 02/10/2026 ms.service: azure-arc zone_pivot_groups: vmware-bicep-terraform ms.subservice: azure-arc-vmware-vsphere ms.author: v-gajeronika ms.reviewer: v-gajeronika author: Jeronika-MS # Customer intent: As a self-service user, I want to provision a VM using vCenter resources through Azure so that I can deploy my code ms.custom: - build-2025 --- # Create a virtual machine on VMware vCenter using Infrastructure as Code methods ::: zone pivot="bicep" This article describes how to provision a VM using vCenter resources using a Bicep template. ## Create an Arc VMware machine using Bicep template Use the following bicep template to create an Arc VMware machine. [Here](/azure/templates/microsoft.connectedvmwarevsphere/2023-12-01/virtualmachineinstances?pivots=deployment-language-arm-template) is the list of available Azure Resource Manager (ARM), Bicep, and Terraform templates for Arc-enabled VMware resources. To trigger any other Arc operation, convert the corresponding [ARM template to Bicep template](/azure/azure-resource-manager/bicep/decompile#decompile-from-json-to-bicep). ```bicep // Parameters param vmName string = 'contoso-vm' param vmAdminPassword string = 'examplepassword!#' param vCenterId string = '/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/contoso-rg/providers/Microsoft.ConnectedVMwarevSphere/vcenters/contoso-vcenter' param templateId string = '/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/contoso-rg/providers/Microsoft.ConnectedVMwarevSphere/VirtualMachineTemplates/contoso-template-win22' param resourcePoolId string = '/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/contoso-rg/providers/Microsoft.ConnectedVMwarevSphere/ResourcePools/contoso-respool' param datastoreId string = '/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/contoso-rg/providers/Microsoft.ConnectedVMwarevSphere/Datastores/contoso-datastore' param networkId string = '/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/contoso-rg/providers/Microsoft.ConnectedVMwarevSphere/VirtualNetworks/contoso-network' param extendedLocation object = { type: 'customLocation' name: '/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/contoso-rg/providers/Microsoft.ExtendedLocation/customLocations/contoso-customlocation' } param ipSettings object = { allocationMethod: 'static' gateway: ['172.24.XXX.1'] ipAddress: '172.24.XXX.105' subnetMask: '255.255.255.0' dnsServers: ['172.24.XXX.9'] } resource contosoMachine 'Microsoft.HybridCompute/machines@2023-10-03-preview' = { name: vmName location:'westeurope' kind:'VMware' properties:{} tags: { foo: 'bar' } } resource vm 'Microsoft.ConnectedVMwarevSphere/virtualMachineInstances@2023-12-01' = { name: 'default' scope: contosoMachine extendedLocation: extendedLocation properties: { hardwareProfile: { memorySizeMB: 4096 numCPUs: 2 } osProfile: { computerName: vmName adminPassword: vmAdminPassword } placementProfile: { resourcePoolId: resourcePoolId datastoreId: datastoreId } infrastructureProfile: { templateId: templateId vCenterId: vCenterId } networkProfile: { networkInterfaces: [ { nicType: 'vmxnet3' ipSettings: ipSettings networkId: networkId name: 'VLAN103NIC' powerOnBoot: 'enabled' } ] } } } // Outputs output vmId string = vm.id ``` ::: zone-end ::: zone pivot="terraform" This article describes how to provision a VM using vCenter resources using a Terraform template. ## Create an Arc VMware machine with Terraform ### Prerequisites - **Azure Subscription**: Ensure you have an active Azure subscription. - **Terraform**: Install Terraform on your machine. - **Azure CLI**: Install Azure CLI to authenticate and manage resources. Follow these steps to create an Arc VMware machine using Terraform. The following two scenarios are covered in this article: 1. For VMs discovered in vCenter inventory, perform enable in Azure operation and install Arc agents. 1. Create a new Arc VMware VM using templates, Resource pool, Datastore and install Arc agents. ### Scenario 1 For VMs discovered in vCenter inventory, enable them in Azure and install Arc agents. #### Step 1: Define variables in a variables.tf file Create a file named `variables.tf` and define all the necessary variables. ```terraform variable "subscription_id" { description = "The subscription ID for the Azure account." type = string } variable "resource_group_name" { description = "The name of the resource group." type = string } variable "location" { description = "The location/region where the resources will be created." type = string } variable "machine_name" { description = "The name of the machine." type = string } variable "inventory_item_id" { description = "The ID of the Inventory Item for the VM." type = string } variable "custom_location_id" { description = "The ID of the custom location." type = string } variable "vm_username" { description = "The admin username for the VM." type = string } variable "vm_password" { description = "The admin password for the VM." type = string } variable "resource_group_name" { description = "The name of the resource group." type = string } variable "location" { description = "The location/region where the resources will be created." type = string } variable "machine_name" { description = "The name of the machine." type = string } variable "vm_username" { description = "The admin username for the VM." type = string } variable "vm_password" { description = "The admin password for the VM." type = string } variable "inventory_id" { description = "The Inventory ID for the VM." type = string } variable "vcenter_id" { description = "The ID of the vCenter." type = string } variable "custom_location_id" { description = "The ID of the custom location." type = string } ``` #### Step 2: Create a tfvars file Create a file named *CreateVMwareVM.tfvars* and provide sample values for the variables. ```terraform subscription_id = "your-subscription-id" resource_group_name = "your-resource-group" location = "eastus" machine_name = "test_machine0001" inventory_item_id = "/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.ConnectedVMwarevSphere/VCenters/your-vcenter-id/InventoryItems/your-inventory-item-id" custom_location_id = "/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.ExtendedLocation/customLocations/your-custom-location-id" vm_username = "Administrator" vm_password = " The admin password for the VM " ``` #### Step 3: Modify the configuration to use variables Create a file named *main.tf* and insert the following code. ```terraform terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = ">= 3.0" } azapi = { source = "azure/azapi" version = ">= 1.0.0" } } } # Configure the AzureRM provider with the subscription ID provider "azurerm" { features {} subscription_id = var.subscription_id } # Configure the AzAPI provider with the subscription ID provider "azapi" { subscription_id = var.subscription_id } # Retrieve the resource group details data "azurerm_resource_group" "example" { name = var.resource_group_name } # Create a VMware machine resource in Azure resource "azapi_resource" "test_machine0001" { schema_validation_enabled = false parent_id = data.azurerm_resource_group.example.id type = "Microsoft.HybridCompute/machines@2023-06-20-preview" name = var.machine_name location = data.azurerm_resource_group.example.location body = jsonencode({ kind = "VMware" identity = { type = "SystemAssigned" } }) } # Create a Virtual Machine instance using the VMware machine and Inventory Item ID resource "azapi_resource" "test_inventory_vm0001" { schema_validation_enabled = false type = "Microsoft.ConnectedVMwarevSphere/VirtualMachineInstances@2023-10-01" name = "default" parent_id = azapi_resource.test_machine0001.id body = jsonencode({ properties = { infrastructureProfile = { inventoryItemId = var.inventory_item_id } } extendedLocation = { type = "CustomLocation" name = var.custom_location_id } }) depends_on = [azapi_resource.test_machine0001] } # Install Arc agent on the VM resource "azapi_resource" "guestAgent" { type = "Microsoft.ConnectedVMwarevSphere/virtualMachineInstances/guestAgents@2023-10-01" parent_id = azapi_resource.test_inventory_vm0001.id name = "default" body = jsonencode({ properties = { credentials = { username = var.vm_username password = var.vm_password } provisioningAction = "install" } }) schema_validation_enabled = false ignore_missing_property = false depends_on = [azapi_resource.test_inventory_vm0001] } ``` #### Step 4: Run Terraform commands Use the `-var-file` flag to pass the *.tfvars* file during Terraform commands. 1. Initialize Terraform (if not already initialized): `terraform init` 1. Validate the configuration: `terraform validate -var-file="CreateVMwareVM.tfvars"` 1. Plan the changes: `terraform plan -var-file="CreateVMwareVM.tfvars"` 1. Apply the changes: `terraform apply -var-file="CreateVMwareVM.tfvars"` Confirm the prompt by entering **yes** to apply the changes. ### Best practices - **Use version control**: Keep your Terraform configuration files under version control, such as Git, to track changes over time. - **Review plans carefully**: Always review the output of `terraform plan` before applying changes to ensure that you understand what changes will be made. - **State management**: Regularly back up your Terraform state files to avoid data loss. By following these steps, you can effectively create and manage HCRP and Arc VMware VMs on Azure using Terraform and install guest agents on the created VMs. ### Scenario 2 Create a new Arc VMware VM using templates, resource pool, datastore, and install Arc agents. #### Step 1: Define variables in a variables.tf file Create a file named `variables.tf` and define all the necessary variables. ```terraform variable "subscription_id" { description = "The subscription ID for the Azure account." type = string } variable "resource_group_name" { description = "The name of the resource group." type = string } variable "location" { description = "The location/region where the resources will be created." type = string } variable "machine_name" { description = "The name of the machine." type = string } variable "vm_username" { description = "The admin username for the VM." type = string } variable "vm_password" { description = "The admin password for the VM." type = string } variable "template_id" { description = "The ID of the VM template." type = string } variable "vcenter_id" { description = "The ID of the vCenter." type = string } variable "resource_pool_id" { description = "The ID of the resource pool." type = string } variable "datastore_id" { description = "The ID of the datastore." type = string } variable "custom_location_id" { description = "The ID of the custom location." type = string } ``` #### Step 2: Create tfvars file Create a file named *CreateVMwareVM.tfvars* and provide sample values for the variables. ```terraform subscription_id = "your-subscription-id" resource_group_name = "your-resource-group" location = "eastus" machine_name = "test_machine0002" vm_username = "Administrator" vm_password = "*********" template_id = "/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.ConnectedVMwarevSphere/virtualmachinetemplates/your-template-id" vcenter_id = "/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.ConnectedVMwarevSphere/VCenters/your-vcenter-id" resource_pool_id = "/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.ConnectedVMwarevSphere/resourcepools/your-resource-pool-id" datastore_id = "/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.ConnectedVMwarevSphere/datastores/your-datastore-id" custom_location_id = "/subscriptions/your-subscription-id/resourceGroups/your-resource-group/providers/Microsoft.ExtendedLocation/customLocations/your-custom-location-id" ``` #### Step 3: Modify the configuration to use variables Create a file named *main.tf* and insert the following code. ```terraform terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = ">= 3.0" } azapi = { source = "azure/azapi" version = ">= 1.0.0" } } } # Configure the AzureRM provider with the subscription ID provider "azurerm" { features {} subscription_id = var.subscription_id } # Configure the AzAPI provider with the subscription ID provider "azapi" { subscription_id = var.subscription_id } # Retrieve the resource group details data "azurerm_resource_group" "example" { name = var.resource_group_name } # Create a VMware machine resource in Azure resource "azapi_resource" "test_machine0002" { schema_validation_enabled = false parent_id = data.azurerm_resource_group.example.id type = "Microsoft.HybridCompute/machines@2023-06-20-preview" name = var.machine_name location = data.azurerm_resource_group.example.location body = jsonencode({ kind = "VMware" identity = { type = "SystemAssigned" } }) } # Create a Virtual Machine instance using the VMware machine created above resource "azapi_resource" "test_vm0002" { schema_validation_enabled = false type = "Microsoft.ConnectedVMwarevSphere/VirtualMachineInstances@2023-10-01" name = "default" parent_id = azapi_resource.test_machine0002.id body = jsonencode({ properties = { infrastructureProfile = { templateId = var.template_id vCenterId = var.vcenter_id } placementProfile = { resourcePoolId = var.resource_pool_id datastoreId = var.datastore_id } osProfile = { adminPassword = var.vm_password } } extendedLocation = { type = "CustomLocation" name = var.custom_location_id } }) depends_on = [azapi_resource.test_machine0002] } # Create a guest agent for the VM instance resource "azapi_resource" "guestAgent" { type = "Microsoft.ConnectedVMwarevSphere/virtualMachineInstances/guestAgents@2023-10-01" parent_id = azapi_resource.test_vm0002.id name = "default" body = jsonencode({ properties = { credentials = { username = var.vm_username password = var.vm_password } provisioningAction = "install" } }) schema_validation_enabled = false ignore_missing_property = false depends_on = [azapi_resource.test_vm0002] } ``` #### Step 4: Run Terraform commands Use the `-var-file` flag to pass the *.tfvars* file during Terraform commands. 1. Initialize Terraform (if not already initialized): `terraform init` 1. Validate the configuration: `terraform validate -var-file="CreateVMwareVM.tfvars"` 1. Plan the changes: `terraform plan -var-file="CreateVMwareVM.tfvars"` 1. Apply the changes: `terraform apply -var-file="CreateVMwareVM.tfvars"` Confirm the prompt by entering **yes** to apply the changes. ### Best practices - **Use version control**: Keep your Terraform configuration files under version control, such as Git, to track changes over time. - **Review plans carefully**: Always review the output of `terraform plan` before applying changes to ensure that you understand what changes will be made. - **State management**: Regularly back up your Terraform state files to avoid data loss. ::: zone-end ## Next steps [Perform operations on VMware VMs in Azure](perform-vm-ops-through-azure.md).
Success! Branch created successfully. Create Pull Request on GitHub
Error: