» vsphere_virtual_machine
The vsphere_virtual_machine
resource can be used to manage the complex
lifecycle of a virtual machine. It supports management of disk, network
interface, and CDROM devices, creation from scratch or cloning from template,
and migration through both host and storage vMotion.
For more details on working with virtual machines in vSphere, see this page.
» About Working with Virtual Machines in Terraform
A high degree of control and flexibility is afforded to a vSphere user when it comes to how to configure, deploy, and manage virtual machines - much more control than given in a traditional cloud provider. As such, Terraform has to make some decisions on how to manage the virtual machines it creates and manages. This section documents things you need to know about your virtual machine configuration that you should consider when setting up virtual machines, creating templates to clone from, or migrating from previous versions of this resource.
» Disks
The vsphere_virtual_machine
resource currently only supports standard
VMDK-backed virtual disks - it does not support other special kinds of disk
devices like RDM disks.
Disks are managed by an arbitrary label supplied to the label
attribute of a disk
block. This is separate from the
automatic naming that vSphere picks for you when creating a virtual machine.
Control over a virtual disk's name is not supported unless you are attaching an
external disk with the attach
attribute.
Virtual disks can be SCSI disks only. The SCSI controllers managed by Terraform
can vary, depending on the value supplied to
scsi_controller_count
. This also dictates the
controllers that are checked when looking for disks during a cloning process.
By default, this value is 1
, meaning that you can have up to 15 disks
configured on a virtual machine. These are all configured with the controller
type defined by the scsi_type
setting. If you are cloning from
a template, devices will be added or re-configured as necessary.
When cloning from a template, you must specify disks of either the same or greater size than the disks in the source template when creating a traditional clone, or exactly the same size when cloning from snapshot (also known as a linked clone). For more details, see the section on creating a virtual machine from a template.
A maximum of 60 virtual disks can be configured when the
scsi_controller_count
setting is configured to its
maximum of 4
controllers. See the disk options section for
more details.
» Customization and network waiters
Terraform waits during various parts of a virtual machine deployment to ensure that it is in a correct expected state before proceeding. These happen when a VM is created, or also when it's updated, depending on the waiter.
Two waiters of note are:
-
The customization waiter: This waiter watches events in vSphere to
monitor when customization on a virtual machine completes during VM creation.
Depending on your vSphere or VM configuration it may be necessary to change
the timeout or turn it off. This can be controlled by the
timeout
setting in the customization settings block. -
The network waiter: This waiter waits for interfaces to show up on a
guest virtual machine close to the end of both VM creation and update. This
waiter is necessary to ensure that correct IP information gets reported to
the guest virtual machine, mainly to facilitate the availability of a valid,
reachable default IP address for any provisioners.
The behavior of the waiter can be controlled with the
wait_for_guest_net_timeout
,wait_for_guest_net_routable
,wait_for_guest_ip_timeout
, andignored_guest_ips
settings.
» Migrating from a previous version of this resource
NOTE: This section only applies to versions of this resource available in versions v0.4.2 of this provider or earlier.
The path for migrating to the current version of this resource is very similar
to the import path, with the exception that the terraform
import
command does not need to be run. See that section for details on what
is required before you run terraform plan
on a state that requires migration.
A successful migration usually only results in a configuration-only diff - that
is, Terraform reconciles some configuration settings that cannot be set during
the migration process with state. In this event, no reconfiguration operations
are sent to the vSphere server during the next terraform apply
. See the
importing section for more details.
» Example Usage
» Creating a virtual machine from scratch
The following block contains all that is necessary to create a new virtual machine, with a single disk and network interface.
The resource makes use of the following data sources to do its job:
vsphere_datacenter
to locate the datacenter,
vsphere_datastore
to locate the default datastore to
put the virtual machine in, vsphere_resource_pool
to locate a resource pool located in a cluster or standalone host, and
vsphere_network
to locate a network.
data "vsphere_datacenter" "dc" {
name = "dc1"
}
data "vsphere_datastore" "datastore" {
name = "datastore1"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_compute_cluster" "cluster" {
name = "cluster1"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_network" "network" {
name = "public"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
resource "vsphere_virtual_machine" "vm" {
name = "terraform-test"
resource_pool_id = "${data.vsphere_compute_cluster.cluster.resource_pool_id}"
datastore_id = "${data.vsphere_datastore.datastore.id}"
num_cpus = 2
memory = 1024
guest_id = "other3xLinux64Guest"
network_interface {
network_id = "${data.vsphere_network.network.id}"
}
disk {
label = "disk0"
size = 20
}
}
» Cloning and customization example
Building on the above example, the below configuration creates a VM by cloning
it from a template, fetched via the
vsphere_virtual_machine
data source. This
allows us to locate the UUID of the template we want to clone, along with
settings for network interface type, SCSI bus type (especially important on
Windows machines), and disk attributes.
NOTE: Cloning requires vCenter and is not supported on direct ESXi connections.
data "vsphere_datacenter" "dc" {
name = "dc1"
}
data "vsphere_datastore" "datastore" {
name = "datastore1"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_compute_cluster" "cluster" {
name = "cluster1"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_network" "network" {
name = "public"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_virtual_machine" "template" {
name = "ubuntu-16.04"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
resource "vsphere_virtual_machine" "vm" {
name = "terraform-test"
resource_pool_id = "${data.vsphere_compute_cluster.cluster.resource_pool_id}"
datastore_id = "${data.vsphere_datastore.datastore.id}"
num_cpus = 2
memory = 1024
guest_id = "${data.vsphere_virtual_machine.template.guest_id}"
scsi_type = "${data.vsphere_virtual_machine.template.scsi_type}"
network_interface {
network_id = "${data.vsphere_network.network.id}"
adapter_type = "${data.vsphere_virtual_machine.template.network_interface_types[0]}"
}
disk {
label = "disk0"
size = "${data.vsphere_virtual_machine.template.disks.0.size}"
eagerly_scrub = "${data.vsphere_virtual_machine.template.disks.0.eagerly_scrub}"
thin_provisioned = "${data.vsphere_virtual_machine.template.disks.0.thin_provisioned}"
}
clone {
template_uuid = "${data.vsphere_virtual_machine.template.id}"
customize {
linux_options {
host_name = "terraform-test"
domain = "test.internal"
}
network_interface {
ipv4_address = "10.0.0.10"
ipv4_netmask = 24
}
ipv4_gateway = "10.0.0.1"
}
}
}
» Cloning from an OVF/OVA-created template with vApp properties
This alternate example details how to clone a VM from a template that came from
an OVF/OVA file. This leverages the resource's vApp
properties capabilities to
set appropriate keys that control various configuration settings on the virtual
machine or virtual appliance. In this scenario, using customize
is not
recommended as the functionality has tendency to overlap.
NOTE: Neither the vsphere_virtual_machine
resource nor the vSphere
provider supports importing of OVA or OVF files as this is a workflow that is
fundamentally not the domain of Terraform. The supported path for deployment in
Terraform is to first import the virtual machine into a template that has not
been powered on, and then clone from that template. This can be accomplished
with Packer, govc's import.ovf
and import.ova
subcommands, or ovftool.
data "vsphere_datacenter" "dc" {
name = "dc1"
}
data "vsphere_datastore" "datastore" {
name = "datastore1"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_compute_cluster" "cluster" {
name = "cluster1"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_network" "network" {
name = "public"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_virtual_machine" "tempate_from_ovf" {
name = "template_from_ovf"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
resource "vsphere_virtual_machine" "vm" {
name = "terraform-test"
resource_pool_id = "${data.vsphere_compute_cluster.cluster.resource_pool_id}"
datastore_id = "${data.vsphere_datastore.datastore.id}"
num_cpus = 2
memory = 1024
guest_id = "${data.vsphere_virtual_machine.template.guest_id}"
scsi_type = "${data.vsphere_virtual_machine.template.scsi_type}"
network_interface {
network_id = "${data.vsphere_network.network.id}"
adapter_type = "${data.vsphere_virtual_machine.template.network_interface_types[0]}"
}
disk {
name = "disk0"
size = "${data.vsphere_virtual_machine.template.disks.0.size}"
eagerly_scrub = "${data.vsphere_virtual_machine.template.disks.0.eagerly_scrub}"
thin_provisioned = "${data.vsphere_virtual_machine.template.disks.0.thin_provisioned}"
}
clone {
template_uuid = "${data.vsphere_virtual_machine.template_from_ovf.id}"
}
vapp {
properties {
"guestinfo.hostname" = "terraform-test.foobar.local"
"guestinfo.interface.0.name" = "ens192"
"guestinfo.interface.0.ip.0.address" = "10.0.0.100/24"
"guestinfo.interface.0.route.0.gateway" = "10.0.0.1"
"guestinfo.interface.0.route.0.destination" = "0.0.0.0/0"
"guestinfo.dns.server.0" = "10.0.0.10"
}
}
}
» Using Storage DRS
The vsphere_virtual_machine
resource also supports Storage DRS, allowing the
assignment of virtual machines to datastore clusters. When assigned to a
datastore cluster, changes to a virtual machine's underlying datastores are
ignored unless disks drift outside of the datastore cluster. The example below
makes use of the vsphere_datastore_cluster
data
source, and the
datastore_cluster_id
configuration setting. Note
that the vsphere_datastore_cluster
resource also exists to allow for
management of datastore clusters directly in Terraform.
NOTE: When managing datastore clusters, member datastores, and virtual
machines within the same Terraform configuration, race conditions can apply.
This is because datastore clusters must be created before datastores can be
assigned to them, and the respective vsphere_virtual_machine
resources will
no longer have an implicit dependency on the specific datastore resources. Use
depends_on
to create an explicit dependency on the
datastores in the cluster, or manage datastore clusters and datastores in a
separate configuration.
data "vsphere_datacenter" "dc" {
name = "dc1"
}
data "vsphere_datastore_cluster" "datastore_cluster" {
name = "datastore-cluster1"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_compute_cluster" "cluster" {
name = "cluster1"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
data "vsphere_network" "network" {
name = "public"
datacenter_id = "${data.vsphere_datacenter.dc.id}"
}
resource "vsphere_virtual_machine" "vm" {
name = "terraform-test"
resource_pool_id = "${data.vsphere_compute_cluster.cluster.resource_pool_id}"
datastore_cluster_id = "${data.vsphere_datastore_cluster.datastore_cluster.id}"
num_cpus = 2
memory = 1024
guest_id = "other3xLinux64Guest"
network_interface {
network_id = "${data.vsphere_network.network.id}"
}
disk {
label = "disk0"
size = 20
}
}
» Argument Reference
The following arguments are supported:
» General options
The following options are general virtual machine and Terraform workflow options:
-
name
- (Required) The name of the virtual machine. -
resource_pool_id
- (Required) The managed object reference ID of the resource pool to put this virtual machine in. See the section on virtual machine migration for details on changing this value.
NOTE: All clusters and standalone hosts have a resource pool, even if
one has not been explicitly created. For more information, see the section on
specifying the root resource pool in the
vsphere_resource_pool
data source documentation. This resource does not take
a cluster or standalone host resource directly.
-
datastore_id
- (Optional) The managed object reference ID of the virtual machine's datastore. The virtual machine configuration is placed here, along with any virtual disks that are created where a datastore is not explicitly specified. See the section on virtual machine migration for details on changing this value. -
datastore_cluster_id
- (Optional) The managed object reference ID of the datastore cluster ID to use. This setting applies to entire virtual machine and implies that you wish to use Storage DRS with this virtual machine. See the section on virtual machine migration for details on changing this value.
NOTE: One of datastore_id
or datastore_cluster_id
must be specified.
NOTE: Use of datastore_cluster_id
requires Storage DRS to be enabled
on that cluster.
NOTE: The datastore_cluster_id
setting applies to the entire virtual
machine - you cannot assign individual datastore clusters to individual disks.
In addition to this, you cannot use the attach
setting to attach
external disks on virtual machines that are assigned to datastore clusters.
-
folder
- (Optional) The path to the folder to put this virtual machine in, relative to the datacenter that the resource pool is in. -
host_system_id
- (Optional) An optional managed object reference ID of a host to put this virtual machine on. See the section on virtual machine migration for details on changing this value. If ahost_system_id
is not supplied, vSphere will select a host in the resource pool to place the virtual machine, according to any defaults or DRS policies in place. -
disk
- (Required) A specification for a virtual disk device on this virtual machine. See disk options below. -
network_interface
- (Required) A specification for a virtual NIC on this virtual machine. See network interface options below. -
cdrom
- (Optional) A specification for a CDROM device on this virtual machine. See CDROM options below. -
clone
- (Optional) When specified, the VM will be created as a clone of a specified template. Optional customization options can be submitted as well. See creating a virtual machine from a template for more details.
NOTE: Cloning requires vCenter and is not supported on direct ESXi connections.
-
vapp
- (Optional) Optional vApp configuration. The only sub-key available isproperties
, which is a key/value map of properties for virtual machines imported from OVF or OVA files. See Using vApp properties to supply OVF/OVA configuration for more details. -
guest_id
- (Optional) The guest ID for the operating system type. For a full list of possible values, see here. Default:other-64
. -
alternate_guest_name
- (Optional) The guest name for the operating system whenguest_id
isother
orother-64
. -
annotation
- (Optional) A user-provided description of the virtual machine. The default is no annotation. -
firmware
- (Optional) The firmware interface to use on the virtual machine. Can be one ofbios
orEFI
. Default:bios
. -
extra_config
- (Optional) Extra configuration data for this virtual machine. Can be used to supply advanced parameters not normally in configuration, such as data for cloud-config (under the guestinfo namespace).
NOTE: Do not use extra_config
when working with a template imported
from OVF or OVA as more than likely your settings will be ignored. Use the
vapp
block's properties
section as outlined in Using vApp properties to
supply OVF/OVA
configuration.
-
scsi_type
- (Optional) The type of SCSI bus this virtual machine will have. Can be one of lsilogic (LSI Logic Parallel), lsilogic-sas (LSI Logic SAS) or pvscsi (VMware Paravirtual). Defualt:pvscsi
. -
scsi_bus_sharing
- (Optional) Mode for sharing the SCSI bus. The modes are physicalSharing, virtualSharing, and noSharing. Default:noSharing
. -
tags
- (Optional) The IDs of any tags to attach to this resource. See here for a reference on how to apply tags.
NOTE: Tagging support is unsupported on direct ESXi connections and requires vCenter 6.0 or higher.
-
custom_attributes
- (Optional) Map of custom attribute ids to attribute value strings to set for virtual machine. See here for a reference on how to set values for custom attributes.
NOTE: Custom attributes are unsupported on direct ESXi connections and require vCenter.
» CPU and memory options
The following options control CPU and memory settings on the virtual machine:
-
num_cpus
- (Optional) The number of virtual processors to assign to this virtual machine. Default:1
. -
num_cores_per_socket
- (Optional) The number of cores to distribute among the CPUs in this virtual machine. If specified, the value supplied tonum_cpus
must be evenly divisible by this value. Default:1
. -
cpu_hot_add_enabled
- (Optional) Allow CPUs to be added to this virtual machine while it is running. -
cpu_hot_remove_enabled
- (Optional) Allow CPUs to be removed to this virtual machine while it is running. -
memory
- (Optional) The size of the virtual machine's memory, in MB. Default:1024
(1 GB). -
memory_hot_add_enabled
- (Optional) Allow memory to be added to this virtual machine while it is running.
NOTE: Certain CPU and memory hot-plug options are not available on every
operating system. Check the VMware Guest OS Compatibility
Guide first to see what settings your guest
operating system is eligible for. In addition, at least one terraform apply
must be executed before being able to take advantage of CPU and memory hot-plug
settings, so if you want the support, enable it as soon as possible.
» Boot options
The following options control boot settings on the virtual machine:
-
boot_delay
- (Optional) The number of milliseconds to wait before starting the boot sequence. The default is no delay. -
efi_secure_boot_enabled
- (Optional) When thefirmware
type is set to isefi
, this enables EFI secure boot. Default:false
.
NOTE: EFI secure boot is only available on vSphere 6.5 and higher.
-
boot_retry_delay
- (Optional) The number of milliseconds to wait before retrying the boot sequence. This only valid ifboot_retry_enabled
is true. Default:10000
(10 seconds). -
boot_retry_enabled
- (Optional) If set to true, a virtual machine that fails to boot will try again after the delay defined inboot_retry_delay
. Default:false
.
» VMware Tools options
The following options control VMware tools options on the virtual machine:
-
sync_time_with_host
- (Optional) Enable guest clock synchronization with the host. Requires VMware tools to be installed. Default:false
. -
run_tools_scripts_after_power_on
- (Optional) Enable the execution of post-power-on scripts when VMware tools is installed. Default:true
. -
run_tools_scripts_after_resume
- (Optional) Enable the execution of post-resume scripts when VMware tools is installed. Default:true
. -
run_tools_scripts_before_guest_reboot
- (Optional) Enable the execution of pre-reboot scripts when VMware tools is installed. Default:false
. -
run_tools_scripts_before_guest_shutdown
- (Optional) Enable the execution of pre-shutdown scripts when VMware tools is installed. Default:true
. -
run_tools_scripts_before_guest_standby
- (Optional) Enable the execution of pre-standby scripts when VMware tools is installed. Default:true
.
» Resource allocation options
The following options allow control over CPU and memory allocation on the virtual machine. Note that the resource pool that this VM is in may affect these options.
-
cpu_limit
- (Optional) The maximum amount of CPU (in MHz) that this virtual machine can consume, regardless of available resources. The default is no limit. -
cpu_reservation
- (Optional) The amount of CPU (in MHz) that this virtual machine is guaranteed. The default is no reservation. -
cpu_share_level
- (Optional) The allocation level for CPU resources. Can be one ofhigh
,low
,normal
, orcustom
. Default:custom
. -
cpu_share_count
- (Optional) The number of CPU shares allocated to the virtual machine when thecpu_share_level
iscustom
. -
memory_limit
- (Optional) The maximum amount of memory (in MB) that this virtual machine can consume, regardless of available resources. The default is no limit. -
memory_reservation
- (Optional) The amount of memory (in MB) that this virtual machine is guaranteed. The default is no reservation. -
memory_share_level
- (Optional) The allocation level for memory resources. Can be one ofhigh
,low
,normal
, orcustom
. Default:custom
. -
memory_share_count
- (Optional) The number of memory shares allocated to the virtual machine when thememory_share_level
iscustom
.
» Advanced options
The following options control advanced operation of the virtual machine, or control various parts of Terraform workflow, and should not need to be modified during basic operation of the resource. Only change these options if they are explicitly required, or if you are having trouble with Terraform's default behavior.
-
enable_disk_uuid
- (Optional) Expose the UUIDs of attached virtual disks to the virtual machine, allowing access to them in the guest. Default:false
. -
hv_mode
- (Optional) The (non-nested) hardware virtualization setting for this virtual machine. Can be one ofhvAuto
,hvOn
, orhvOff
. Default:hvAuto
. -
ept_rvi_mode
- (Optional) The EPT/RVI (hardware memory virtualization) setting for this virtual machine. Can be one ofautomatic
,on
, oroff
. Default:automatic
. -
nested_hv_enabled
- (Optional) Enable nested hardware virtualization on this virtual machine, facilitating nested virtualization in the guest. Default:false
. -
enable_logging
- (Optional) Enable logging of virtual machine events to a log file stored in the virtual machine directory. Default:false
. -
cpu_performance_counters_enabled
- (Optional) Enable CPU performance counters on this virtual machine. Default:false
. -
swap_placement_policy
- (Optional) The swap file placement policy for this virtual machine. Can be one ofinherit
,hostLocal
, orvmDirectory
. Default:inherit
. -
latency_sensitivity
- (Optional) Controls the scheduling delay of the virtual machine. Use a higher sensitivity for applications that require lower latency, such as VOIP, media player applications, or applications that require frequent access to mouse or keyboard devices. Can be one oflow
,normal
,medium
, orhigh
.
NOTE: Do not use a latency_sensitivity
setting of low
or medium
on
hosts running ESXi 6.0 or older. Doing so may result in virtual machine startup
issues or spurious diffs in Terraform. In addition, on higher sensitivities,
you may have to adjust memory_reservation
to the full
amount of memory provisioned for the virtual machine.
-
wait_for_guest_net_timeout
- (Optional) The amount of time, in minutes, to wait for an available IP address on this virtual machine's NICs. Older versions of VMware Tools do not populate this property. In those cases, this waiter can be disabled and thewait_for_guest_ip_timeout
waiter can be used instead. A value less than 1 disables the waiter. Default: 5 minutes. -
wait_for_guest_net_routable
- (Optional) Controls whether or not the guest network waiter waits for a routable address. Whenfalse
, the waiter does not wait for a default gateway, nor are IP addresses checked against any discovered default gateways as part of its success criteria. This property is ignored if thewait_for_guest_ip_timeout
waiter is used. Default:true
. -
wait_for_guest_ip_timeout
- (Optional) The amount of time, in minutes, to wait for an available guest IP address on this virtual machine. This should only be used if your version of VMware Tools does not allow thewait_for_guest_net_timeout
waiter to be used. A value less than 1 disables the waiter. Default: 0. -
ignored_guest_ips
- (Optional) List of IP addresses to ignore while waiting for an available IP address using either of the waiters. Any IP addresses in this list will be ignored if they show up so that the waiter will continue to wait for a real IP address. Default: []. -
shutdown_wait_timeout
- (Optional) The amount of time, in minutes, to wait for a graceful guest shutdown when making necessary updates to the virtual machine. Ifforce_power_off
is set to true, the VM will be force powered-off after this timeout, otherwise an error is returned. Default: 3 minutes. -
migrate_wait_timeout
- (Optional) The amount of time, in minutes, to wait for a virtual machine migration to complete before failing. Default: 10 minutes. Also see the section on virtual machine migration. -
force_power_off
- (Optional) If a guest shutdown failed or timed out while updating or destroying (seeshutdown_wait_timeout
), force the power-off of the virtual machine. Default:true
. -
scsi_controller_count
- (Optional) The number of SCSI controllers that Terraform manages on this virtual machine. This directly affects the amount of disks you can add to the virtual machine and the maximum disk unit number. Note that lowering this value does not remove controllers. Default:1
.
NOTE: scsi_controller_count
should only be modified when you will need
more than 15 disks on a single virtual machine, or in rare cases that require a
dedicated controller for certain disks. HashiCorp does not support exploiting
this value to add out-of-band devices.
» Disk options
Virtual disks are managed by adding an instance of the disk
block.
At the very least, there must be name
and size
attributes. unit_number
is
required for any disk other than the first, and there must be at least one
resource with the implicit number of 0.
An abridged multi-disk example is below:
resource "vsphere_virtual_machine" "vm" {
...
disk {
label = "disk0"
size = "10"
}
disk {
label = "disk1"
size = "100"
unit_number = 1
}
...
}
The options are:
-
label
- (Required) A label for the disk. Forces a new disk if changed.
NOTE: It's recommended that you set the disk label to a format matching
diskN
, where N
is the number of the disk, starting from disk number 0. This
will ensure that your configuration is compatible when importing a virtual
machine. For more information, see the section on importing.
NOTE: Do not choose a label that starts with orphaned_disk_
(example:
orphaned_disk_0
), as this prefix is reserved for disks that Terraform does
not recognize, such as disks that are attached externally. Terraform will issue
an error if you try to label a disk with this prefix.
-
name
- (Optional) An alias for bothlabel
andpath
, the latter when usingattach
. Required if not usinglabel
.
NOTE: This parameter has been deprecated and will be removed in future
versions of the vSphere provider. You cannot use name
on a disk that has
previously had a label
, and using this argument is not recommend for new
configurations.
NOTE: In previous versions of the vSphere provider this argument
controlled file names for non-attached disks - this behavior has now been
removed, and the only time this controls path is when attaching a disk
externally with attach
when the path
field is not specified.
-
size
- (Required) The size of the disk, in GiB. -
unit_number
- (Optional) The disk number on the SCSI bus. The maximum value for this setting is the value ofscsi_controller_count
times 15, minus 1 (so14
,29
,44
, and59
, for 1-4 controllers respectively). The default is0
, for which one disk must be set to. Duplicate unit numbers are not allowed. -
datastore_id
- (Optional) A managed object reference ID to the datastore for this virtual disk. The default is to use the datastore of the virtual machine. See the section on virtual machine migration for details on changing this value.
NOTE: Datastores cannot be assigned to individual disks when
datastore_cluster_id
is in use.
-
attach
- (Optional) Attach an external disk instead of creating a new one. Implies and conflicts withkeep_on_remove
. If set, you cannot setsize
,eagerly_scrub
, orthin_provisioned
. Must setpath
if used.
NOTE: External disks cannot be attached when
datastore_cluster_id
is in use.
-
path
- (Optional) When usingattach
, this parameter controls the path of a virtual disk to attach externally. Otherwise, it is a computed attribute that contains the virtual disk's current filename. -
keep_on_remove
- (Optional) Keep this disk when removing the device or destroying the virtual machine. Default:false
. -
disk_mode
- (Optional) The mode of this this virtual disk for purposes of writes and snapshotting. Can be one ofappend
,independent_nonpersistent
,independent_persistent
,nonpersistent
,persistent
, orundoable
. Default:persistent
. For an explanation of options, click here. -
eagerly_scrub
- (Optional) If set totrue
, the disk space is zeroed out on VM creation. This will delay the creation of the disk or virtual machine. Cannot be set totrue
whenthin_provisioned
istrue
. See the section on picking a disk type. Default:false
. -
thin_provisioned
- (Optional) Iftrue
, this disk is thin provisioned, with space for the file being allocated on an as-needed basis. Cannot be set totrue
wheneagerly_scrub
istrue
. See the section on picking a disk type. Default:true
. -
disk_sharing
- (Optional) The sharing mode of this virtual disk. Can be one ofsharingMultiWriter
orsharingNone
. Default:sharingNone
.
NOTE: Disk sharing is only available on vSphere 6.0 and higher.
-
write_through
- (Optional) Iftrue
, writes for this disk are sent directly to the filesystem immediately instead of being buffered. Default:false
. -
io_limit
- (Optional) The upper limit of IOPS that this disk can use. The default is no limit. -
io_reservation
- (Optional) The I/O reservation (guarantee) that this disk has, in IOPS. The default is no reservation. -
io_share_level
- (Optional) The share allocation level for this disk. Can be one oflow
,normal
,high
, orcustom
. Default:normal
. -
io_share_count
- (Optional) The share count for this disk when the share level iscustom
.
» Computed disk attributes
-
uuid
- The UUID of the virtual disk's VMDK file. This is used to track the virtual disk on the virtual machine.
» Picking a disk type
The eagerly_scrub
and thin_provisioned
options control the space allocation
type of a virtual disk. These show up in the vSphere console as a unified
enumeration of options, the equivalents of which are explained below. The
defaults in Terraform are the equivalent of thin provisioning.
-
Thick provisioned lazy zeroed: Both
eagerly_scrub
andthin_provisioned
should be set tofalse
. -
Thick provisioned eager zeroed:
eagerly_scrub
should be set to true, andthin_provisioned
should be set tofalse
. -
Thin provisioned:
eagerly_scrub
should be set tofalse
, andthin_provisioned
should be set totrue
.
For the technical details of each virtual disk provisioning policy, click here.
NOTE: Not all disk types are available on some types of datastores. Attempting to set options inappropriate for a datastore that a disk is deployed to will result in a successful initial apply, but vSphere will silently correct the options, and subsequent plans will fail with an appropriate error message until the settings are corrected.
NOTE: The disk type cannot be changed once set.
» Network interface options
Network interfaces are managed by adding an instance of the network_interface
block.
Interfaces are assigned to devices in the specific order they are declared. This has different implications for different operating systems.
Given the following example:
resource "vsphere_virtual_machine" "vm" {
...
network_interface {
network_id = "${data.vsphere_network.public.id}"
}
network_interface {
network_id = "${data.vsphere_network.private.id}"
}
}
The first interface with the public
network assigned to it would show up in
order before the interface assigned to private
. On some Linux systems, this
might mean that the first interface would show up as eth0
and the second
would show up as eth1
.
The options are:
-
network_id
- (Required) The managed object reference ID of the network to connect this interface to. -
adapter_type
- (Optional) The network interface type. Can be one ofe1000
,e1000e
, orvmxnet3
. Default:vmxnet3
. -
use_static_mac
- (Optional) If true, themac_address
field is treated as a static MAC address and set accordingly. Setting this totrue
requiresmac_address
to be set. Default:false
. -
mac_address
- (Optional) The MAC address of this network interface. Can only be manually set ifuse_static_mac
is true, otherwise this is a computed value that gives the current MAC address of this interface. -
bandwidth_limit
- (Optional) The upper bandwidth limit of this network interface, in Mbits/sec. The default is no limit. -
bandwidth_reservation
- (Optional) The bandwidth reservation of this network interface, in Mbits/sec. The default is no reservation. -
bandwidth_share_level
- (Optional) The bandwidth share allocation level for this interface. Can be one oflow
,normal
,high
, orcustom
. Default:normal
. -
bandwidth_share_count
- (Optional) The share count for this network interface when the share level iscustom
.
» CDROM options
A single virtual CDROM device can be created and attached to the virtual machine. The resource supports attaching a CDROM from a datastore ISO or using a remote client device.
An example is below:
resource "vsphere_virtual_machine" "vm" {
...
cdrom {
datastore_id = "${data.vsphere_datastore.iso_datastore.id}"
path = "ISOs/os-livecd.iso"
}
}
The options are:
-
client_device
- (Optional) Indicates whether the device should be backed by remote client device. Conflicts withdatastore_id
andpath
. -
datastore_id
- (Optional) The datastore ID that the ISO is located in. Requried for using a datastore ISO. Conflicts withclient_device
. -
path
- (Optional) The path to the ISO file. Requried for using a datastore ISO. Conflicts withclient_device
.
NOTE: Either client_device
(for a remote backed CDROM) or datastore_id
and path (for a datastore ISO backed CDROM) are required.
NOTE: Some CDROM drive types are currently unsupported by this resource,
such as pass-through devices. If these drives are present in a cloned template,
or added outside of Terraform, they will have their configurations corrected to
that of the defined device, or removed if no cdrom
block is present.
» Virtual device computed options
Configured virtual devices (disk
, network_interface
, and cdrom
) all
export the following attributes. These options help locate the device on future
Terraform runs. The options are:
-
key
- The ID of the device within the virtual machine. -
device_address
- An address internal to Terraform that helps locate the device whenkey
is unavailable. This follows a convention ofCONTROLLER_TYPE:BUS_NUMBER:UNIT_NUMBER
. Example:scsi:0:1
means device unit 1 on SCSI bus 0.
» Creating a Virtual Machine from a Template
The clone
block can be used to create a new virtual machine from an existing
virtual machine or template. The resource supports both making a complete copy
of a virtual machine, or cloning from a snapshot (otherwise known as a linked
clone).
See the cloning and customization example for a usage synopsis.
NOTE: Changing any option in clone
after creation forces a new
resource.
NOTE: Cloning requires vCenter and is not supported on direct ESXi connections.
The options available in the clone
block are:
-
template_uuid
- (Required) The UUID of the source virtual machine or template. -
linked_clone
- (Optional) Clone this virtual machine from a snapshot. Templates must have a single snapshot only in order to be eligible. Default:false
. -
timeout
- (Optional) The timeout, in minutes, to wait for the virtual machine clone to complete. Default: 30 minutes. -
customize
- (Optional) The customization spec for this clone. This allows the user to configure the virtual machine post-clone. For more details, see virtual machine customization.
» Virtual machine customization
As part of the clone
operation, a virtual machine can be
customized to configure host, network, or licensing
settings.
To perform virtual machine customization as a part of the clone process,
specify the customize
block with the respective customization options, nested
within the clone
block. See the cloning and customization
example for a usage synopsis.
The settings for customize
are as follows:
» Customization timeout settings
-
timeout
- (Optional) The time, in minutes that Terraform waits for customization to complete before failing. The default is 10 minutes, and setting the value to 0 or a negative value disables the waiter altogether.
» Network interface settings
These settings, which should be specified in nested network_interface
blocks
within customize
, configure network
interfaces on a per-interface basis and are matched up to
network_interface
devices in the order they are
declared.
Given the following example:
resource "vsphere_virtual_machine" "vm" {
...
network_interface {
network_id = "${data.vsphere_network.public.id}"
}
network_interface {
network_id = "${data.vsphere_network.private.id}"
}
clone {
...
customize {
...
network_interface {
ipv4_address = "10.0.0.10"
ipv4_netmask = 24
}
network_interface {
ipv4_address = "172.16.0.10"
ipv4_netmask = 24
}
ipv4_gateway = "10.0.0.1"
}
}
}
The first set of network_interface
data would be assigned to the public
interface, and the second to the private
interface.
To use DHCP, declare an empty network_interface
block for each interface
being configured. So the above example would look like:
resource "vsphere_virtual_machine" "vm" {
...
network_interface {
network_id = "${data.vsphere_network.public.id}"
}
network_interface {
network_id = "${data.vsphere_network.private.id}"
}
clone {
...
customize {
...
network_interface {}
network_interface {}
}
}
}
The options are:
-
dns_server_list
- (Optional) Network interface-specific DNS server settings for Windows operating systems. Ignored on Linux and possibly other operating systems - for those systems, please see the global DNS settings section. -
dns_domain
- (Optional) Network interface-specific DNS search domain for Windows operating systems. Ignored on Linux and possibly other operating systems - for those systems, please see the global DNS settings section. -
ipv4_address
- (Optional) The IPv4 address assigned to this network adapter. If left blank or not included, DHCP is used. -
ipv4_netmask
The IPv4 subnet mask, in bits (example:24
for 255.255.255.0). -
ipv6_address
- (Optional) The IPv6 address assigned to this network adapter. If left blank or not included, auto-configuration is used. -
ipv6_netmask
- (Optional) The IPv6 subnet mask, in bits (example:32
).
NOTE: The minimum setting for IPv4 in a customization specification is
DHCP. If you are setting up an IPv6-exclusive network without DHCP, you might
need to set wait_for_guest_net_timeout
to a
high enough value to cover the DHCP timeout of your virtual machine, or turn it
off altogether by supplying a zero or negative value. Keep in mind that turning
off wait_for_guest_net_timeout
will more than likely mean that IP addresses
will not be reported to any provisioners you may have configured on the
resource.
» Global routing settings
VM customization under the vsphere_virtual_machine
resource does not take a
per-interface gateway setting, but rather default routes are configured on a
global basis. For an example, see the network interface settings
section.
The settings here must match the IP/mask of at least one network_interface
supplied to customization.
The options are:
-
ipv4_gateway
- (Optional) The IPv4 default gateway when usingnetwork_interface
customization on the virtual machine. -
ipv6_gateway
- (Optional) The IPv6 default gateway when usingnetwork_interface
customization on the virtual machine.
» Global DNS settings
The following settings configure DNS globally, generally for Linux systems. For Windows systems, this is done per-interface, see network interface settings.
-
dns_server_list
- The list of DNS servers to configure on a virtual machine. -
dns_suffix_list
- A list of DNS search domains to add to the DNS configuration on the virtual machine.
» Linux customization options
The settings in the linux_options
block pertain to Linux guest OS
customization. If you are customizing a Linux operating system, this section
must be included.
Example:
resource "vsphere_virtual_machine" "vm" {
...
clone {
...
customize {
...
linux_options {
host_name = "terraform-test"
domain = "test.internal"
}
}
}
}
The options are:
-
host_name
- (Required) The host name for this machine. This, along withdomain
, make up the FQDN of this virtual machine. -
domain
- (Required) The domain name for this machine. This, along withhost_name
, make up the FQDN of this virtual machine. -
hw_clock_utc
- (Optional) Tells the operating system that the hardware clock is set to UTC. Default:true
. -
time_zone
- (Optional) Sets the time zone. For a list of possible combinations, click here. The default is UTC.
» Windows customization options
The settings in the windows_options
block pertain to Windows guest OS
customization. If you are customizing a Windows operating system, this section
must be included.
Example:
resource "vsphere_virtual_machine" "vm" {
...
clone {
...
customize {
...
windows_options {
computer_name = "terraform-test"
workgroup = "test"
admin_password = "VMw4re"
}
}
}
}
The options are:
-
computer_name
- (Required) The computer name of this virtual machine. -
admin_password
- (Optional) The administrator password for this virtual machine.
NOTE: admin_password
is a sensitive field in Terraform and will not be
output on-screen, but is stored in state and sent to the VM in plain text -
keep this in mind when provisioning your infrastructure.
-
workgroup
- (Optional) The workgroup name for this virtual machine. One of this orjoin_domain
must be included. -
join_domain
- (Optional) The domain to join for this virtual machine. One of this orworkgroup
must be included. -
domain_admin_user
- (Optional) The user of the domain administrator used to join this virtual machine to the domain. Required if you are settingjoin_domain
. -
domain_admin_password
- (Optional) The password of the domain administrator used to join this virtual machine to the domain. Required if you are settingjoin_domain
.
NOTE: domain_admin_password
is a sensitive field in Terraform and will
not be output on-screen, but is stored in state and sent to the VM in plain
text - keep this in mind when provisioning your infrastructure.
-
full_name
- (Optional) The full name of the user of this virtual machine. This populates the "user" field in the general Windows system information. Default:Administrator
. -
organization_name
- (Optional) The organization name this virtual machine is being installed for. This populates the "organization" field in the general Windows system information. Default:Managed by Terraform
. -
product_key
- (Optional) The product key for this virtual machine. The default is no key. -
run_once_command_list
- (Optional) A list of commands to run at first user logon, after guest customization. -
auto_logon
- (Optional) Specifies whether or not the VM automatically logs on as Administrator. Default:false
. -
auto_logon_count
- (Optional) Specifies how many times the VM should auto-logon the Administrator account whenauto_logon
is true. This should be set accordingly to ensure that all of your commands that run inrun_once_command_list
can log in to run. Default:1
. -
time_zone
- (Optional) The new time zone for the virtual machine. This is a numeric, sysprep-dictated, timezone code. For a list of codes, click here. The default is85
(GMT/UTC).
» Supplying your own SysPrep file
Alternative to the windows_options
supplied above, you can instead supply
your own sysprep.inf
file contents via the windows_sysprep_text
option.
This allows full control of the customization process out-of-band of vSphere.
Example below:
resource "vsphere_virtual_machine" "vm" {
...
clone {
...
customize {
...
windows_sysprep_text = "${file("${path.module}/sysprep.inf")}"
}
}
}
Note this option is mutually exclusive to windows_options
- one must not be
included if the other is specified.
» Using vApp properties to supply OVF/OVA configuration
Alternative to the settings in customize
, one can use the settings in the
properties
section of the vapp
block to supply configuration parameters to
a virtual machine cloned from a template that came from an imported OVF or OVA
file. Both GuestInfo and ISO transport methods are supported. For templates
that use ISO transport, a CDROM backed by client device is required. See CDROM
options for details.
NOTE: The only supported usage path for vApp properties is for existing user-configurable keys. These generally come from an existing template that was created from an imported OVF or OVA file. You cannot set values for vApp properties on virtual machines created from scratch, virtual machines lacking a vApp configuration, or on property keys that do not exist.
The configuration looks similar to the one below:
resource "vsphere_virtual_machine" "vm" {
...
clone {
template_uuid = "${data.vsphere_virtual_machine.template_from_ovf.id}"
}
vapp {
properties {
"guestinfo.hostname" = "${var.vm_name}.foobar.local"
"guestinfo.interface.0.name" = "ens192"
"guestinfo.interface.0.ip.0.address" = "10.0.0.100/24"
"guestinfo.interface.0.route.0.gateway" = "10.0.0.1"
"guestinfo.interface.0.route.0.destination" = "0.0.0.0/0"
"guestinfo.dns.server.0" = "10.0.0.10"
}
}
}
» Additional requirements and notes for cloning
Note that when cloning from a template, there are additional requirements in both the resource configuration and source template:
- The virtual machine must not be powered on at the time of cloning.
- All disks on the virtual machine must be SCSI disks.
- You must specify at least the same number of
disk
devices as there are disks that exist in the template. These devices are ordered and lined up by theunit_number
attribute. Additional disks can be added past this. - The
size
of a virtual disk must be at least the same size as its counterpart disk in the template. - When using
linked_clone
, thesize
,thin_provisioned
, andeagerly_scrub
settings for each disk must be an exact match to the individual disk's counterpart in the source template. - The
scsi_controller_count
setting should be configured as necessary to cover all of the disks on the template. For best results, only configure this setting for the amount of controllers you will need to cover your disk quantity and bandwidth needs, and configure your template accordingly. For most workloads, this setting should be kept at its default of1
, and all disks in the template should reside on the single, primary controller. - Some operating systems (such as Windows) do not respond well to a change in
disk controller type, so when using such OSes, take care to ensure that
scsi_type
is set to an exact match of the template's controller set. For maximum compatibility, make sure the SCSI controllers on the source template are all the same type.
To ease the gathering of some of these options, you can use the
vsphere_virtual_machine
data source, which
will give you disk attributes, network interface types, SCSI bus types, and
also the guest ID of the source template. See the cloning and customization
example for usage details.
» Virtual Machine Migration
The vsphere_virtual_machine
resource supports live migration (otherwise known
as vMotion) both on the host and storage level. One can migrate the entire VM
to another host, cluster, resource pool, or datastore, and migrate or pin a
single disk to a specific datastore.
» Host, cluster, and resource pool migration
To migrate the virtual machine to another host or resource pool, change the
host_system_id
or resource_pool_id
to the manged object IDs of the new host
or resource pool accordingly. To change the virtual machine's cluster or
standalone host, select a resource pool within the specific target.
The same rules apply for migration as they do for VM creation - any host specified needs to be a part of the resource pool supplied. Also keep in mind the implications of moving the virtual machine to a resource pool in another cluster or standalone host, namely ensuring that all hosts in the cluster (or the single standalone host) have access to the datastore that the virtual machine is in.
» Storage migration
Storage migration can be done on two levels:
- Global datastore migration can be handled by changing the global
datastore_id
attribute. This triggers a storage migration for all disks that do not have an explicitdatastore_id
specified. - When using Storage DRS through the
datastore_cluster_id
attribute, the entire virtual machine can be migrated from one datastore cluster to another by changing the value of this setting. In addition, whendatastore_cluster_id
is in use, any disks that drift to datastores outside of the datastore cluster via such actions as manual modification will be migrated back to the datastore cluster on the next apply. - An individual
disk
device can be migrated by manually specifying thedatastore_id
in its configuration block. This also pins it to the specific datastore that is specified - if at a later time the VM and any unpinned disks migrate to another host, the disk will stay on the specified datastore.
An example of datastore pinning is below. As long as the datastore in the
pinned_datastore
data source does not change, any change to the standard
vm_datastore
data source will not affect the data disk - the disk will stay
where it is.
resource "vsphere_virtual_machine" "vm" {
...
datastore_id = "${data.vsphere_datastore.vm_datastore.id}"
disk {
label = "disk0"
size = 10
}
disk {
datastore_id = "${data.vsphere_datastore.pinned_datastore.id}"
label = "disk1"
size = 100
unit_number = 1
}
...
}
» Storage migration restrictions
Note that you cannot migrate external disks added with the attach
parameter.
As these disks have usually been created and assigned to a datastore outside of
the scope of the vsphere_virtual_machine
resource in question, such as by
using the vsphere_virtual_disk
resource,
management of such disks would render their configuration unstable.
» Attribute Reference
The following attributes are exported on the base level of this resource:
-
id
- The UUID of the virtual machine. -
reboot_required
- Value internal to Terraform used to determine if a configuration set change requires a reboot. This value is only useful during an update process and gets reset on refresh. -
vmware_tools_status
- The state of VMware tools in the guest. This will determine the proper course of action for some device operations. -
vmx_path
- The path of the virtual machine's configuration file in the VM's datastore. -
imported
- This is flagged if the virtual machine has been imported, or the state has been migrated from a previous version of the resource. It influences the behavior of the first post-import apply operation. See the section on importing below. -
change_version
- A unique identifier for a given version of the last configuration applied, such the timestamp of the last update to the configuration. -
uuid
- The UUID of the virtual machine. Also exposed as theid
of the resource. -
default_ip_address
- The IP address selected by Terraform to be used with any provisioners configured on this resource. Whenever possible, this is the first IPv4 address that is reachable through the default gateway configured on the machine, then the first reachable IPv6 address, and then the first general discovered address if neither exist. If VMware tools is not running on the virtual machine, or if the VM is powered off, this value will be blank. -
guest_ip_addresses
- The current list of IP addresses on this machine, including the value ofdefault_ip_address
. If VMware tools is not running on the virtual machine, or if the VM is powered off, this list will be empty. -
moid
: The managed object reference ID of the created virtual machine. -
vapp_transport
- Computed value which is only valid for cloned virtual machines. A list of vApp transport methods supported by the source virtual machine or template.
» Importing
An existing virtual machine can be imported into this resource via supplying the full path to the virtual machine. An example is below:
terraform import vsphere_virtual_machine.vm /dc1/vm/srv1
The above would import the virtual machine named srv1
that is located in the
dc1
datacenter.
» Additional requirements and notes for importing
Many of the same requirements for cloning apply to importing, although since importing writes directly to state, a lot of these rules cannot be enforced at import time, so every effort should be made to ensure the correctness of the configuration before the import.
In addition to these rules, the following extra rules apply to importing:
- Disks need to have their
label
argument assigned in a convention matchingdiskN
, starting with disk number 0, based on each disk's order on the SCSI bus. As an example, a disk on SCSI controller 0 with a unit number of 0 would be labeleddisk0
, a disk on the same controller with a unit number of 1 would bedisk1
, but the next disk, which is on SCSI controller 1 with a unit number of 0, still becomesdisk2
. - Disks always get imported with
keep_on_remove
enabled until the firstterraform apply
runs, which will remove the setting for known disks. This is an extra safeguard against naming or accounting mistakes in the disk configuration. - The
scsi_controller_count
for the resource is set to the number of contiguous SCSI controllers found, starting with the SCSI controller at bus number 0. If no SCSI controllers are found, the VM is not eligible for import. To ensure maximum compatibility, make sure your virtual machine has the exact number of SCSI controllers it needs, and setscsi_controller_count
accordingly.
After importing, you should run terraform plan
. Unless you have changed
anything else in configuration that would be causing other attributes to
change, the only difference should be configuration-only changes, usually
comprising of:
- The
imported
flag will transition fromtrue
tofalse
. -
keep_on_remove
of known disks will transition fromtrue
tofalse
. - Configuration supplied in the
clone
block, if present, will be persisted to state. This initial persistence operation does not perform any cloning or customization actions, nor does it force a new resource. After the first apply operation, further changes toclone
will force a new resource as per normal operation.
NOTE: Further to the above, do not make any configuration changes to
clone
after importing or upgrading from a legacy version of the provider
before doing an initial terraform apply
as these changes will not correctly
force a new resource, and your changes will have persisted to state, preventing
further plans from correctly triggering a diff.
These changes only update Terraform state when applied, hence it is safe to run when the virtual machine is running. If more settings are being modified, you may need to plan maintenance accordingly for any necessary re-configuration of the virtual machine.