Skip to content

You are viewing documentation for Instruqt 2.0 Labs - our upcoming product releasing in September 2026. For current Tracks documentation, please visitdocs.instruqt.com.

Virtual Machine


Defined insandboxes.hcl

The vm resource defines a virtual machine that runs as part of your lab sandbox environment. VMs provide full operating system compute for labs that need system services, OS-level configuration, extra disks, or workloads that do not fit a container-only design.

As a lab author, you can use VMs to create richer sandbox environments:

  • Full Operating Systems: Run workloads that need a complete Linux environment instead of a single container process
  • System Configuration Labs: Teach package installation, service management, networking, or disk setup
  • Nested Runtime Labs: Provide VM images that include Docker, Kubernetes, or other platform tooling
  • Stateful Services: Attach additional disks for databases, data directories, or other storage-heavy exercises

Use a VM when the lab experience depends on OS behavior. Use a container when a lighter process-isolated runtime is enough.

resource "vm" "ubuntu" {
image {
name = "ubuntu:24.04"
}
}
resource "network" "main" {
subnet = "10.50.0.0/24"
}
resource "vm" "ubuntu" {
config {
arch = "x86_64"
}
image {
name = "ubuntu:24.04"
username = "registry-user"
password = variable.registry_token
}
resources {
cpu = 2
memory = 2048
}
environment = {
GREETING = "hello"
}
dns = ["1.1.1.1"]
startup_script = <<-EOF
#!/bin/sh
apt-get update
apt-get install -y nginx
EOF
network {
id = resource.network.main.meta.id
ip_address = "10.50.0.10"
aliases = ["web"]
}
disk {
destination = "/data"
size = 20
}
volume {
source = "./shared"
destination = "/mnt/shared"
read_only = true
}
port {
local = "8080"
host = "8080"
protocol = "tcp"
open_in_browser = "/"
}
port_range {
range = "3000-3010"
enable_host = true
protocol = "tcp"
}
health_check {
timeout = "30s"
tcp {
address = "localhost:8080"
}
}
}
vm
├─ config
│ └─ arch
├─ image (required)
│ └─ name, username, password
├─ resources
│ └─ cpu, memory
├─ environment
├─ dns[]
├─ startup_script
├─ networking
│ └─ network[] (repeatable)
│ └─ id, ip_address, aliases
├─ storage
│ ├─ disk[] (repeatable)
│ │ └─ destination, size
│ └─ volume[] (repeatable)
│ └─ source, destination, type, read_only
├─ port exposure
│ ├─ port[] (repeatable)
│ │ └─ local, host, protocol, open_in_browser
│ └─ port_range[] (repeatable)
│ └─ range, enable_host, protocol
└─ monitoring
└─ health_check
├─ timeout
├─ http[] (address, method, body, headers, success_codes)
├─ tcp[] (address)
└─ exec[] (command, script, exit_code)

Fields

FieldTypeRequiredDescription
configblockVM configuration
imageblockVM image configuration
resourcesblockResource allocation for the VM
diskblockDisk images attached to the VMrepeatable
volumeblockVolume mounts for the VMrepeatable
networkblockConnect your container to a specific network to enable communication between containers or services.repeatable
portblockExpose specific ports so learners can access web apps, APIs, or services running in the container.repeatable
port_rangeblockRange of ports to exposerepeatable
environmentmap(string)Environment variables for the VM
startup_scriptstringScript to run on VM boot
dnslist(string)Configure DNS servers or custom hostnames for your VM to resolve network addresses.
ConstraintsMust be a valid IP address
health_checkblockDefine checks to confirm that your VM is running and responsive.

Config

vmConfig

VM configuration

FieldTypeRequiredDescription
archstringCPU architecture (e.g. x86_64, aarch64)

Image

vmImage

VM image configuration

FieldTypeRequiredDescription
namestringDocker image name with optional tag
ConstraintsMust match `^[a-z0-9]([a-z0-9-]*[a-z0-9])*(\.[a-z0-9]([a-z0-9-]*[a-z0-9])*)*(/[a-z0-9]+([a-z0-9._-]*[a-z0-9])*)*(:[a-z0-9]+([a-z0-9._-]*[a-z0-9])*)?$`
usernamestringDocker registry user to use for private repositories
passwordstringDocker registry password to use for private repositories

Resources

vmResources

Resource allocation for the VM

FieldTypeRequiredDescription
cpunumberNumber of CPU cores
memorynumberMemory in MB

Disk

vmDisk

Disk images attached to the VM

FieldTypeRequiredDescription
typestringDisk type (e.g. qcow2, raw)
sourcestringSource image URL or path
sizestringDisk size (e.g. 20G)
destinationstringMount path inside the VM
readonlyboolMount as read-only

Volume

vmVolume

Volume mounts for the VM

FieldTypeRequiredDescription
sourcestringSource path on the host
destinationstringMount path inside the VM
read_onlyboolMount as read-only

Network

vmNetwork

Network interfaces for the VM

FieldTypeRequiredDescription
idstringID of the network to attach the container
ip_addressstringStatic IP address to assign container for the network, the ip address must be within range defined by the network subnet. If this parameter is omitted an IP address will be automatically assigned.
aliaseslist(string)Aliases allow alternate names to specified for the container

Port

vmPort

Port mappings for the VM

FieldTypeRequiredDescription
localnumberThe local port in the container
ConstraintsMinimum 1; Maximum 65535
remotenumberRemote port of the service
ConstraintsMinimum 1; Maximum 65535
hostnumberThe host port to map the local port to
ConstraintsMinimum 1; Maximum 65535
protocolstringThe protocol to use when exposing the port
Allowedtcp udp
Defaulttcp
open_in_browserstringWhen a host port is defined open this port with the given path in a browser

Port Range

vmPort Range

Range of ports to expose

FieldTypeRequiredDescription
rangestringLocal port in the container
ConstraintsRange format is "<number>-<number>"
enable_hostboolHost port
protocolstringProtocol tcp, udp
Allowedtcp udp
Defaulttcp

Health Check

vmHealth Check

Health checks for the VM

FieldTypeRequiredDescription
timeoutstringThe maximum duration to wait before marking the health check as failed. Expressed as a Go duration, e.g. 1s = 1 second, 100ms = 100 milliseconds.
Default30s
ConstraintsMust be a valid duration (e.g. 30s, 5m)
execblockRuns a command or script inside the VM. The check passes when the command exits with code 0.repeatable
httpblockSends an HTTP request to the address and passes when the response matches the expected success codes.repeatable
tcpblockAttempts to open a TCP connection to the address. If the connection opens, the check passes.repeatable

Exec Health Check

vmHealth CheckExec Health Check

Execute command health check

FieldTypeRequiredDescription
commandlist(string)Command to execute
scriptstringScript to execute
exit_codenumberExpected exit code

HTTP Health Check

vmHealth CheckHTTP Health Check

HTTP health check

FieldTypeRequiredDescription
addressstringThe URL to check, health check expects a HTTP status code to be returned by the URL in order to pass the health check.
methodstringHTTP method to use when executing the check.
bodystringHTTP body to send with the request.
headersmap(list(string))HTTP headers to send with the check
success_codeslist(number)HTTP status codes returned from the endpoint when called. If the returned status code matches any in the array then the health check will pass.

TCP Health Check

vmHealth CheckTCP Health Check

TCP health check

FieldTypeRequiredDescription
addressstringTCP address to check

Computed Attributes

These attributes are set by the system and are read-only.

AttributeTypeDescription
image.idstringUnique identifier for the image, this is independent of tag and changes each time the image is built. An image that has been tagged multiple times also shares the same ID.
network[].namestringName will equal the name of the network as created by jumppad
network[].assigned_addressstringAssignedAddress will equal if IPAddress is set, else it will be the value automatically assigned from the network
resource "vm" "ubuntu" {
image {
name = "ubuntu:24.04"
}
}
resource "network" "main" {
subnet = "10.50.0.0/24"
}
resource "vm" "devbox" {
image {
name = "ubuntu:24.04"
}
resources {
cpu = 2
memory = 2048
}
network {
id = resource.network.main.meta.id
ip_address = "10.50.0.10"
}
startup_script = <<-EOF
#!/bin/sh
apt-get update
apt-get install -y curl jq
EOF
}
resource "terminal" "devbox" {
target = resource.vm.devbox
shell = "/bin/bash"
}
resource "network" "main" {
subnet = "10.50.0.0/24"
}
resource "vm" "web" {
image {
name = "ubuntu:24.04"
}
disk {
destination = "/var/lib/app"
size = 20
}
port {
local = "8080"
host = "8080"
}
network {
id = resource.network.main.meta.id
}
health_check {
http {
address = "http://localhost:8080/health"
}
}
}
resource "service" "web" {
target = resource.vm.web
port = 8080
}
  1. Choose the right compute type: Use VMs for full OS behavior and containers for lightweight application runtimes
  2. Attach a network for interactive labs: Terminal access, service tabs, startup scripts, and exec health checks depend on VM reachability
  3. Size resources deliberately: VMs need enough CPU and memory for the guest operating system and your lab workload
  4. Use explicit image tags: Pin images to stable versions for repeatable lab runs
  5. Make startup scripts idempotent: Startup scripts should handle reruns and partially completed setup safely
  6. Use disks for durable paths: Mount additional disks at application data paths and avoid reserved system paths
  7. Expose only needed ports: Map the smallest set of ports required for the learner experience