root 74eeabb354
Some checks failed
PR Checks / tofu-checks (pull_request) Failing after 2s
1/1 projects applied successfully.
feat: add tenant VM module for VM-as-a-Service (Step 5.2)
Reusable OpenTofu module for creating isolated tenant VMs with:
- Public IP on vmbr1 (bridged, firewall=true)
- Cloud-init: password auth, fail2ban, UFW hardening
- Per-VM Proxmox firewall (IN: SSH+ICMP, OUT: allow, block SMTP)

Includes test-tenant VM (185.47.204.227) for verification.

Changes:
- modules/tenant-vm/ — reusable module (VM + FW + cloud-init)
- environments/production/tenant-vms.tf — tenant VM definitions
- policies/security.rego — require firewall=true on vmbr1
- atlantis.yaml — trigger on module file changes
- main.tf — updated host prerequisites comment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 20:01:38 +01:00

47 lines
1.3 KiB
HCL

# Tenant VMs — isolated VMs with public IPs for third parties
# Each VM gets: public IP, password auth, fail2ban, UFW, Proxmox FW
#
# To add a new VM: add entry to local.tenant_vms, create PR
# To remove a VM: remove entry, create PR (OPA will warn about deletion)
#
# Cloud image dependency: proxmox_virtual_environment_download_file.ubuntu_2404_cloud (in main.tf)
locals {
tenant_vms = {
# "vm-name" = { vm_id = 2xx, public_ip = "185.47.204.2xx", password = "...", ... }
"test-tenant" = {
vm_id = 201
public_ip = "185.47.204.227"
password = "TestTenant2026!"
}
}
}
module "tenant_vm" {
source = "../../modules/tenant-vm"
for_each = local.tenant_vms
name = each.key
vm_id = each.value.vm_id
public_ip = each.value.public_ip
password = each.value.password
cpu_cores = lookup(each.value, "cpu_cores", 1)
ram_mb = lookup(each.value, "ram_mb", 1024)
disk_gb = lookup(each.value, "disk_gb", 20)
started = lookup(each.value, "started", true)
depends_on = [proxmox_virtual_environment_download_file.ubuntu_2404_cloud]
}
output "tenant_vms" {
description = "Tenant VM details"
value = {
for name, vm in module.tenant_vm : name => {
vm_id = vm.vm_id
public_ip = vm.public_ip
username = vm.username
}
}
}