Skip to content

Terraform & Packer

Infrastructure-as-Code (IaC) brings the same version control, peer review, and repeatability that software teams rely on to infrastructure provisioning. The VergeOS Terraform provider lets you declare VMs, networks, and users in HCL configuration files, while the Packer plugin automates golden image creation. Together, they form a declarative pipeline: Packer builds the images, Terraform deploys the infrastructure.

The VergeOS Terraform provider is published on the Terraform Registry and is fully compatible with OpenTofu (the open-source Terraform fork). It enables you to manage VergeOS resources through standard terraform plan / terraform apply workflows.

terraform {
required_providers {
vergeio = {
source = "verge-io/vergeio"
version = "~> 0.1.0"
}
}
}
provider "vergeio" {
host = "https://vergeos.example.com"
username = "admin"
password = var.vergeos_password
insecure = true # Set to true for self-signed SSL certificates
}
ParameterRequiredDescription
hostYesURL or IP address of the VergeOS system or tenant
usernameYesVergeOS username with appropriate permissions
passwordYesPassword for the specified user (mark as sensitive)
insecureNoSet true to accept self-signed SSL certificates

The provider currently supports four managed resource types for creating and updating VergeOS objects:

ResourcePurposeKey Attributes
vergeio_vmCreate and manage virtual machinescpu_cores, ram, os_family, machine_type, ha_group, cluster, guest_agent, uefi, secure_boot, snapshot_profile, powerstate, inline vergeio_drive and vergeio_nic blocks
vergeio_networkConfigure virtual networksnetwork_address (CIDR), dhcp_enabled, dhcp_start, dhcp_end, dns_server_list, gateway, powerstate
vergeio_userProvision usersUser account management within VergeOS
vergeio_memberManage group membershipAssociate users with groups for RBAC

Eight read-only data sources let you query existing VergeOS objects for use in your configurations:

Data SourceReturns
vergeio_versionCurrent VergeOS version information
vergeio_clustersAvailable compute/storage clusters
vergeio_nodesNodes in the environment
vergeio_networksExisting virtual networks
vergeio_vmsVirtual machines (filterable by name, snapshot status)
vergeio_groupsUser groups for RBAC
vergeio_mediasourcesUploaded ISOs and media files
vergeio_cloudinitfilesAvailable cloud-init configuration files

This example creates a Linux web server with a 10 GB virtio-scsi drive and a NIC attached to an internal network:

resource "vergeio_vm" "web_server" {
name = "my-web-server"
description = "Web Server"
enabled = true
os_family = "linux"
cpu_cores = 2
machine_type = "q35"
ram = 2048
powerstate = false
guest_agent = true
cloudinit_datasource = "nocloud"
ha_group = "web"
# Storage
vergeio_drive {
name = "Web Server OS Disk"
description = "Operating System Disk"
disksize = 10
interface = "virtio-scsi"
preferred_tier = 3
orderid = 0
}
# Networking
vergeio_nic {
name = "Web Server Network"
description = "NIC for Web Server"
interface = "virtio"
enabled = true
vnet = vergeio_network.web_network.id
}
}
resource "vergeio_network" "web_network" {
name = "web-internal-network"
network_address = "192.168.10.0/24"
dns_server_list = ["8.8.8.8", "8.8.4.4"]
dhcp_enabled = true
dhcp_start = "192.168.10.100"
dhcp_end = "192.168.10.200"
}

Use data sources to reference existing infrastructure without managing it:

data "vergeio_vms" "production" {
filter_name = "prod-db"
is_snapshot = false
}
output "production_vms" {
value = data.vergeio_vms.production.vms
}

Combine the VM resource with cloud-init for first-boot automation:

resource "vergeio_vm" "app_server" {
name = "app-server-01"
os_family = "linux"
cpu_cores = 4
machine_type = "q35"
ram = 8192
guest_agent = true
cloudinit_datasource = "nocloud"
cloudinit_files {
name = "user-data"
contents = <<-EOF
#cloud-config
packages:
- nginx
- python3
runcmd:
- systemctl enable nginx
- systemctl start nginx
EOF
}
vergeio_drive {
name = "OS Disk"
disksize = 20
interface = "virtio-scsi"
preferred_tier = 2
}
vergeio_nic {
interface = "virtio"
vnet = vergeio_network.web_network.id
}
}

The Packer plugin for VergeOS (github.com/verge-io/packer-plugin-vergeio) automates the creation of VM images directly on the VergeOS platform. Where Terraform manages running infrastructure, Packer focuses on building the golden images that serve as the foundation for deployments.

Golden images ensure every deployed VM starts from a known, tested, and hardened baseline. Instead of provisioning a bare OS and running configuration scripts on every deployment, Packer pre-bakes the image once:

  • Consistency — Every VM created from the image is identical
  • Speed — No first-boot provisioning delay; VMs are ready immediately
  • Compliance — Security baselines and patches are baked in at build time
  • Pipeline integration — Trigger image rebuilds from CI/CD on OS patch days
packer {
required_plugins {
vergeio = {
source = "github.com/verge-io/vergeio"
version = ">= 0.1.1"
}
}
}
source "vergeio" "ubuntu" {
endpoint = "https://vergeos.example.com"
username = "admin"
password = var.vergeos_password
vm_name = "packer-ubuntu-base"
cpu_cores = 2
ram = 4096
os_family = "linux"
disk {
disksize = 20
interface = "virtio-scsi"
tier = 2
}
}
build {
sources = ["source.vergeio.ubuntu"]
provisioner "shell" {
inline = [
"apt-get update",
"apt-get install -y nginx qemu-guest-agent",
"systemctl enable qemu-guest-agent"
]
}
}
FeatureDescription
Full VM lifecycleCreates VM, provisions, captures image, cleans up
Cloud-init supportInline and external file cloud-init configurations
Dynamic network discoveryResolves network IDs by name at build time
Graceful shutdown4-phase shutdown process ensures clean image capture
Disk import handlingAutomatically waits for disk imports to complete before power-on
Multi-OS supportLinux and Windows image creation

Packer images integrate naturally with the VergeOS Recipe system. A typical workflow:

  1. Packer builds and hardens the golden image on a schedule (e.g., monthly patch cycle)
  2. The image is registered as a VM Recipe in the VergeOS Marketplace
  3. Users deploy standardized VMs from the recipe — either through the UI or via Terraform
  4. Updates flow automatically: rebuild the Packer image, update the recipe, and all new deployments get the latest version

The Terraform Playground is a companion repository that provides ready-to-use Terraform configurations for deploying complete VergeOS topologies in lab environments. It supports four deployment scenarios:

2-Node HCI

Minimal hyper-converged cluster for testing and development. Both nodes serve as controller, compute, and storage.

4-Node HCI

Production-grade HCI with dedicated controller pair and two additional compute/storage nodes.

4-Node Hybrid

Mixed deployment with HCI foundation nodes and compute-only scale-out nodes.

6-Node UCI

Full Ultraconverged Infrastructure with dedicated controller, storage, and compute clusters.

These playground configurations are used extensively in the Module 10 labs for hands-on topology deployment practice. They demonstrate real-world Terraform provider usage while teaching VergeOS architecture concepts.

For teams that want declarative infrastructure without image pipelines:

For production environments with golden image management:

Terraform handles provisioning; configuration management tools handle the rest:

PhaseToolPurpose
Image creationPackerBuild hardened golden images
ProvisioningTerraformDeploy VMs, networks, users
ConfigurationAnsible / cloud-initPost-deploy software configuration
MonitoringPrometheus / VergeOS alertsObserve deployed infrastructure
  • Use remote state backends (S3, Consul, Terraform Cloud) for team collaboration
  • Never commit terraform.tfstate to version control — it may contain credentials
  • Lock state files to prevent concurrent modifications in multi-user environments
  • Use variables for sensitive values (var.vergeos_password) — never hardcode credentials
  • Mark sensitive outputs with sensitive = true to prevent accidental exposure in logs
  • Restrict provider permissions — create a dedicated VergeOS API user with minimum required access
  • Separate environments into workspaces or directories (dev/, staging/, prod/)
  • Create reusable modules for common patterns (e.g., a “web-server” module with VM + network + firewall rules)
  • Pin provider versions to avoid unexpected breaking changes during upgrades