Skip to main content

dtcloud_vm (Resource)

Manages a virtual machine.

This resource builds the machine, renames it, resizes it, changes its power state and destroys it. Interfaces and volumes added after boot belong to dtcloud_vm_network_interface and dtcloud_vm_volume_attachment.

Example Usage​

resource "dtcloud_vm" "web" {
name = "web-01"
flavor_id = data.dtcloud_flavors.small.flavors[0].id
state = "running"

key_name = dtcloud_ssh_key.deploy.name
# Written as it should reach the guest; the provider base64-encodes it, which is
# the only form the API accepts. Encoding it here too would double-encode it.
user_data = file("${path.module}/cloud-init.yaml")

# Interfaces declared here are created with the machine and live and die with
# it. Add one afterwards with dtcloud_vm_network_interface instead.
network {
uuid = dtcloud_network.app.id
security_groups = [dtcloud_security_group.web.id]

fixed_ip {
ip_version = 4
}
}

# The boot disk is boot_index 0.
block_device {
boot_index = 0
volume_size = 40
source_type = "image"
device_type = "disk"
destination_type = "volume"
uuid = var.image_id
volume_type = "standard"
delete_on_termination = true
}
}
warning

At least one of key_name, user_data or script is required. They are the only ways credentials or a provisioning payload reach the guest. user_data and script cannot both be set: the platform builds cloud-init from script only when user_data is absent, so the plan refuses the combination instead of silently dropping the script.

note

On a Linux image, set username, hostname and disable_root in script. They are optional only because Windows template images ignore them, and the apply warns when a Linux script leaves any of them out.

note

Leave fixed_ip out for the usual case: the provider asks for one address and the platform allocates it. The addresses actually assigned are reported back into the network blocks.

Schema​

Required​

  • flavor_id (String) ID of the flavor (sizing). Changing this resizes the instance in place. Unless enable_hot_plug is true the platform requires the instance to be stopped first, so the provider stops it, resizes and returns it to the configured power state — a plan that does this is the one where status also shows as (known after apply).
  • name (String) Name of the virtual machine. Can be changed in place.

Optional​

  • block_device (Block List) Block devices to attach at boot. The boot disk is the entry with boot_index 0. At least one is required. Changing this forces a new resource to be created. (see below for nested schema)
  • enable_hot_plug (Boolean) Allow live vCPU/memory resize on the instance. With this on, changing flavor_id does not power-cycle the instance. Can be toggled after creation.
  • graceful_shutdown (Boolean) When stopping, ask the guest to shut down (softStop) instead of cutting power (hardStop).
  • is_gpu_image (Boolean) Set when booting a GPU image. Changing this forces a new resource to be created.
  • key_name (String) Name of an existing SSH key to inject, e.g. a dtcloud_ssh_key resource's name. Changing this forces a new resource to be created.
  • network (Block List) Network interfaces to attach at boot. At least one is required. Changing this forces a new resource to be created. (see below for nested schema)
  • script (Block List, Max: 1) Initial credentials applied to the guest at first boot. On a Linux image, set username, hostname and disable_root as well — they are optional only because Windows template images ignore them. Changing this forces a new resource to be created. (see below for nested schema)
  • state (String) Desired power state: running, stopped or shelved. Shelving releases compute resources while keeping the VM and its disks.
  • timeouts (Block, Optional) (see below for nested schema)
  • user_data (String) Cloud-init user data, written as it should reach the guest. The API only accepts it base64-encoded and the provider encodes it, so passing base64encode() output here would encode it twice and the guest would receive the encoded text. Changing this forces a new resource to be created.

Read-Only​

  • created_at (String) When the VM was created, in RFC 3339 format.
  • flavor_name (String) Human-readable name of the VM's flavor.
  • id (String) The ID of this resource.
  • image (String) Name of the image the VM was built from.
  • image_os_type (String) OS family of the image, e.g. linux or windows.
  • last_modified (String) When the VM was last modified, in RFC 3339 format.
  • metadata (Map of String) Metadata the platform attaches to the instance, e.g. ha_enabled.
  • network_interface (List of Object) Network interfaces currently attached to the VM. (see below for nested schema)
  • primary_ip (String) Convenience shortcut: the primary IP of the first public interface, falling back to the first interface with an address.
  • ram (String) Memory as reported by the API, e.g. "512 MB".
  • ssh_key (String) Name of the SSH key injected into the VM.
  • status (String) Current power/provisioning state, e.g. ACTIVE, SHUTOFF, ERROR.
  • task_state (String) In-flight platform task, empty when the VM is settled.
  • vcpus (Number) Number of virtual CPUs.
  • volume (List of Object) Volumes currently attached to the VM, including the boot disk. (see below for nested schema)

Nested Schema for block_device​

Required:

  • boot_index (Number) Boot order. The boot disk is 0. Changing this forces a new resource to be created.
  • delete_on_termination (Boolean) Whether the device is deleted with the VM. Changing this forces a new resource to be created.
  • destination_type (String) One of: volume, local. Changing this forces a new resource to be created.
  • device_type (String) One of: cdrom, disk. Changing this forces a new resource to be created.
  • source_type (String) Where the device comes from. One of: blank, image, volume, backup. Changing this forces a new resource to be created.
  • volume_size (Number) Size in GB (1-8192). Can be increased in place; decreasing is not supported.
  • volume_type (String) Storage policy / volume type the disk is created on. Can be changed in place.

Optional:

  • uuid (String) ID of the source image, volume or backup. Omitted for blank devices. Changing this forces a new resource to be created.

Nested Schema for network​

Required:

  • uuid (String) ID of the network to attach to. Changing this forces a new resource to be created.

Optional:

  • fixed_ip (Block List) Fixed IPs on this interface. Omit to have one address allocated. Can be changed in place. (see below for nested schema)
  • port_security_enabled (Boolean) Whether port security (and therefore security groups) applies to this interface. Defaults to the network's own setting. Changing this forces a new resource to be created.
  • security_groups (List of String) Security group IDs bound to this interface. Can be changed in place. Defaults to the project's default group.

Nested Schema for network.fixed_ip​

Optional:

  • ip_address (String) Specific address to request. Allocated by the platform when omitted, and reported back here either way.
  • ip_version (Number) IP version, 4 or 6. Advisory on write — the platform allocates from the attached network; pin ip_address to choose an address. Reported back from the assigned address.

Nested Schema for script​

Required:

  • os (String) Guest OS family. One of: linux, windows. Changing this forces a new resource to be created.
  • password (String, Sensitive) Initial password for the guest account. Changing this forces a new resource to be created.

Optional:

  • disable_root (Boolean) Disable direct root login. Required in practice on Linux images; ignored by Windows template images. Changing this forces a new resource to be created.
  • hostname (String) Hostname to set inside the guest. Required in practice on Linux images; ignored by Windows template images. Changing this forces a new resource to be created.
  • username (String) Account to create. Required in practice on Linux images; ignored by Windows template images. Changing this forces a new resource to be created.

Nested Schema for timeouts​

Optional:

  • create (String)
  • delete (String)
  • update (String)

Nested Schema for network_interface​

Read-Only:

  • is_public (Boolean)
  • mac_address (String)
  • network_id (String)
  • network_name (String)
  • port_id (String)
  • primary_ip (String)
  • secondary_ips (List of String)
  • security_groups (List of Object) (see below for nested schema)
  • spoofing_protection (Boolean)

Nested Schema for network_interface.security_groups​

Read-Only:

  • id (String)
  • name (String)

Nested Schema for volume​

Read-Only:

  • delete_on_termination (Boolean)
  • id (String)
  • name (String)
  • size (Number)
  • storage_policy (String)

Behaviour worth knowing​

  • What changes in place. name, flavor_id, state, enable_hot_plug, and inside the blocks network.security_groups, network.fixed_ip, block_device.volume_size (increase only) and block_device.volume_type. Adding or removing a whole network or block_device block, network.uuid, network.port_security_enabled, the other block_device fields and the boot-time arguments key_name, user_data, script and is_gpu_image build a new machine.
  • Resizing. With enable_hot_plug = true the flavor changes while the machine keeps running. Without it the platform refuses to resize a running instance, so the provider stops it, resizes it and returns it to the configured state. In a plan, the resize that power-cycles the machine is the one where status also shows as known after apply, and the apply warns that the machine was restarted.
  • Growing a disk does not grow the filesystem. After volume_size increases, extend the partition and the filesystem inside the guest (growpart and resize2fs, or your filesystem's equivalent); the apply warns about it. volume_size cannot be decreased.
  • The guest does not see a changed fixed_ip at once. The address moves on the port, but the operating system keeps the old one until its DHCP lease renews, and for good if the interface is configured statically. Renew the lease or reboot; the apply warns about it.
  • port_security_enabled has no default. Left unset it is not sent, and the network decides. It cannot be false while security_groups is set on the same block.
  • Extra disks are matched by size and storage policy. Beyond the boot disk the platform reports no order, so a block_device change is refused when two attached volumes look the same. Manage such disks with dtcloud_vm_volume_attachment.
  • What drift Terraform can see. name, flavor_id, state, key_name, enable_hot_plug, the network blocks and the size, storage policy and delete-on-termination setting of each block_device are read back. user_data, script and is_gpu_image are not reported by any endpoint, so a change made to them outside Terraform stays invisible.
  • network_interface and volume are a snapshot from the last refresh. Interfaces and volumes attached by other resources in the same apply appear after the next refresh.
  • One resource is one machine. The API can create several machines in one call; this resource does not expose that. Use Terraform's count or for_each.

state is the power state Terraform keeps the machine in; a machine always boots running first.

FromToWhat the provider does
runningstoppedsoftStop, or hardStop when graceful_shutdown = false
stoppedrunningstart
anyshelvedshelve, which releases the compute resources and keeps the machine and its disks
shelvedrunningunshelve
shelvedstoppedunshelve, then stop

Timeouts​

create defaults to 20 minutes, update to 10 minutes and delete to 15 minutes. Creating waits for the machine to reach ACTIVE, and a resize stops and restarts it, so an update can take several minutes. Override them with a timeouts block:

resource "dtcloud_vm" "web" {
# ...

timeouts {
create = "30m"
}
}

Import​

# user_data, script and is_gpu_image are not reported by any endpoint: read the
# import notes before the first apply.
terraform import dtcloud_vm.web 4c9a1f37-8d25-4e60-b13f-6a7c2e5b9d88

Read back on import: name, flavor_id, state, key_name, enable_hot_plug, every interface as a network block, and the boot disk as a block_device block. The boot disk's source_type, device_type and destination_type are inferred, because the platform does not report them. Not read back: user_data, script, is_gpu_image, graceful_shutdown, and disks attached after boot.

user_data, script and is_gpu_image force a new machine, so if the configuration sets them the first plan after an import proposes a rebuild. Ignore them to keep the imported machine:

resource "dtcloud_vm" "web" {
# ...

lifecycle {
ignore_changes = [user_data, script, is_gpu_image]
}
}
danger

Import a machine before attaching extra interfaces to it. An import has no blocks to match against, so every interface the machine has becomes a network block. If some of them belong to dtcloud_vm_network_interface resources, the configuration declares fewer blocks than were imported, and the first plan proposes to replace the machine.