Skip to content

Commit 2255c7b

Browse files
committed
feat(vm): add brownfield override variables
1 parent 9d502de commit 2255c7b

3 files changed

Lines changed: 99 additions & 5 deletions

File tree

modules/workloads/vm/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,37 @@ module "app_vm" {
119119
}
120120
```
121121

122+
### Importing a brownfield VM
123+
124+
When a VM already exists (e.g. created via the Harvester UI) and you want to
125+
bring it under Terraform management without forcing destructive renames, set
126+
the `*_name` / `*_auto_delete` / `input_devices` overrides to match the VM's
127+
current spec. Defaults target greenfield conventions; override only to match
128+
existing state.
129+
130+
```hcl
131+
module "legacy_vm" {
132+
source = "github.com/wso2-enterprise/open-cloud-datacenter//modules/workloads/vm?ref=v0.x.y"
133+
134+
name = "legacy-host"
135+
namespace = "team-ns"
136+
cpu = 2
137+
memory = "8Gi"
138+
disk_size = "40Gi"
139+
image_name = "default/image-abc12" # match the existing image ID
140+
network_name = "team-ns/vlan-600"
141+
142+
# Brownfield overrides — match what the Harvester UI created
143+
disk_name = "disk-0"
144+
disk_auto_delete = false
145+
network_interface_name = "default"
146+
ssh_key_ids = ["default/shared-key"]
147+
input_devices = [{ name = "tablet", type = "tablet", bus = "usb" }]
148+
}
149+
```
150+
151+
After declaring the module, `terraform import module.legacy_vm.harvester_virtualmachine.this <namespace>/<name>` and run `terraform plan` — the plan should show zero changes.
152+
122153
### Referencing images from the management phase
123154

124155
```hcl
@@ -152,6 +183,12 @@ locals {
152183
| `wait_for_lease` | Wait for IP lease on primary NIC. Set false for static cloud-init IPs. | `bool` | `true` | no |
153184
| `user_data` | Cloud-init user-data YAML. Creates a cloud-init secret when set. | `string` | `null` | no |
154185
| `network_data` | Cloud-init network-data config (requires `user_data` to be set). | `string` | `""` | no |
186+
| `disk_name` | Name of the root disk volume. Override to match brownfield VMs. | `string` | `"rootdisk"` | no |
187+
| `disk_auto_delete` | Whether the root disk's PVC is deleted with the VM. | `bool` | `true` | no |
188+
| `network_interface_name` | Name of the primary NIC. Override to match brownfield VMs. | `string` | `"nic-1"` | no |
189+
| `restart_after_update` | Whether Terraform restarts the VM when its spec changes. | `bool` | `true` | no |
190+
| `ssh_key_ids` | Existing Harvester SSH key IDs (`namespace/name`) to attach. | `list(string)` | `[]` | no |
191+
| `input_devices` | Input devices (e.g. USB tablet) to attach. | `list(object)` | `[]` | no |
155192

156193
## Outputs
157194

modules/workloads/vm/main.tf

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,33 @@ resource "harvester_ssh_key" "this" {
2525
resource "harvester_virtualmachine" "this" {
2626
name = var.name
2727
namespace = var.namespace
28-
restart_after_update = true
28+
restart_after_update = var.restart_after_update
2929

3030
cpu = var.cpu
3131
memory = var.memory
3232

3333
run_strategy = var.run_strategy
3434
machine_type = "q35"
3535

36-
ssh_keys = var.create_ssh_key ? [harvester_ssh_key.this[0].id] : []
36+
ssh_keys = concat(
37+
var.create_ssh_key ? [harvester_ssh_key.this[0].id] : [],
38+
var.ssh_key_ids,
39+
)
3740

3841
network_interface {
39-
name = "nic-1"
42+
name = var.network_interface_name
4043
wait_for_lease = var.wait_for_lease
4144
network_name = var.network_name
4245
}
4346

4447
disk {
45-
name = "rootdisk"
48+
name = var.disk_name
4649
type = "disk"
4750
size = var.disk_size
4851
bus = "virtio"
4952
boot_order = 1
5053
image = var.image_name
51-
auto_delete = true
54+
auto_delete = var.disk_auto_delete
5255
}
5356

5457
dynamic "disk" {
@@ -62,6 +65,15 @@ resource "harvester_virtualmachine" "this" {
6265
}
6366
}
6467

68+
dynamic "input" {
69+
for_each = var.input_devices
70+
content {
71+
name = input.value.name
72+
type = input.value.type
73+
bus = input.value.bus
74+
}
75+
}
76+
6577
dynamic "cloudinit" {
6678
for_each = local.effective_user_data != null ? [1] : []
6779
content {

modules/workloads/vm/variables.tf

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,51 @@ variable "additional_disks" {
107107
default = []
108108
}
109109

110+
# --- Brownfield overrides ---
111+
# These let the module wrap VMs that were created outside Terraform (e.g. via
112+
# the Harvester UI) without forcing destructive renames on import. Defaults
113+
# match greenfield conventions; override only when matching existing state.
114+
115+
variable "disk_name" {
116+
type = string
117+
description = "Name of the root disk volume. Harvester-UI-created VMs use \"disk-0\"; module-created VMs use \"rootdisk\"."
118+
default = "rootdisk"
119+
}
120+
121+
variable "disk_auto_delete" {
122+
type = bool
123+
description = "Whether the root disk's PVC is deleted when the VM is deleted. UI-created VMs typically have this false."
124+
default = true
125+
}
126+
127+
variable "network_interface_name" {
128+
type = string
129+
description = "Name of the primary network interface. Harvester-UI-created VMs use \"default\"; module-created VMs use \"nic-1\"."
130+
default = "nic-1"
131+
}
132+
133+
variable "restart_after_update" {
134+
type = bool
135+
description = "Whether Terraform restarts the VM to apply spec changes. Set false to defer restarts on live VMs."
136+
default = true
137+
}
138+
139+
variable "ssh_key_ids" {
140+
type = list(string)
141+
description = "Existing Harvester SSH key IDs (namespace/name) to attach, in addition to any key created by create_ssh_key. Use this to reference pre-existing shared keys."
142+
default = []
143+
}
144+
145+
variable "input_devices" {
146+
type = list(object({
147+
name = string
148+
type = string
149+
bus = optional(string, "usb")
150+
}))
151+
description = "Input devices (e.g. USB tablet) to attach. Harvester-UI-created VMs include a tablet by default; module-created VMs add none."
152+
default = []
153+
}
154+
110155
# --- Scheduled backups ---
111156

112157
variable "backup_schedule" {

0 commit comments

Comments
 (0)