variable "hypervisors" { description = "Per-hypervisor configuration. Keys must match provider aliases in providers.tf (e.g. hv2, hv3)." type = map(object({ api_url = string # e.g. https://192.168.1.10:8006/ node_name = string storage = string })) } variable "ipam_endpoint" { description = "Base URL of the PHPIPAM API, e.g. https://ipam.example.com/api" type = string default = "" } variable "network_subnets" { description = "Named map of CIDR ranges managed by PHPIPAM. Only used when enable_ipam = true." type = map(string) default = {} } variable "ansible_user" { description = "User created on each managed host for Ansible access." type = string } variable "search_domain" { description = "DNS search domain set on all managed hosts." type = string } variable "dns_nameservers" { description = "DNS nameserver(s) set on all managed hosts." type = string } variable "technitium_host" { description = "URL of the Technitium DNS Server API (e.g. http://192.168.0.3:5380). Required once Technitium is running." type = string default = "" } variable "technitium_enabled" { description = "Set to false to stop Terraform from managing Technitium DNS zones/records, without changing anything else. Still requires technitium_api_token in Infisical to actually turn on." type = bool default = true } variable "dns_zones" { description = "Additional Technitium DNS zones to create, beyond the auto-managed search_domain zone. Keyed by zone name." type = map(object({ type = optional(string, "Primary") forwarder = optional(string) })) default = {} } variable "dns_records" { description = "Manually managed DNS records. Each targets a zone by name (the search_domain zone or one from dns_zones). A record in the search_domain zone whose name matches an auto-added host replaces that host record instead of conflicting with it." type = list(object({ zone = string name = string # subdomain label, or "@" for the zone apex type = string # A, AAAA, CNAME, NS, TXT, MX value = string # IP / target / text / mail exchanger ttl = optional(number) priority = optional(number) # required for MX records })) default = [] } variable "caddy_host" { description = "Caddy admin API endpoint. When using the SSH tunnel this is the endpoint as seen from the caddy host (e.g. http://localhost:2019). Leave empty to disable Caddy management." type = string default = "" } variable "caddy_ssh_host" { description = "SSH target (user@host:port) used to tunnel to the Caddy admin API. Empty to reach caddy_host directly." type = string default = "" } variable "caddy_ssh_host_key" { description = "SSH host key of the caddy host, known_hosts format (get it with: ssh-keyscan ). Required when caddy_ssh_host is set." type = string default = "" } variable "caddy_proxies" { description = "Reverse-proxy sites keyed by name. Each maps a hostname to one or more upstream backends (Caddy dial targets, e.g. \"192.168.0.40:32400\"). protocol picks plain HTTP on :80 (default) or HTTPS on :443 with automatic certificates. Set path to restrict the route to specific request paths." type = map(object({ host = string upstreams = list(string) protocol = optional(string, "http") path = optional(list(string)) })) default = {} } variable "ansible_inventory_path" { description = "Path where the generated Ansible inventory file is written. Defaults to ../ansible/inventories/generated.yml relative to this module, which points to the parent repo when used as a git submodule." type = string default = "./ansible/inventories/generated.yml" } # LXC, VM and Flatcar VM definitions per hypervisor, keyed by the same names # used in hypervisors and providers.tf. All three maps default to {} so a node # can be declared with any subset of workload types. variable "nodes" { type = map(object({ lxc = optional(map(object({ hostname = string vmid = number template = string os_type = optional(string, "debian") unprivileged = bool onboot = bool tags = string cores = optional(number, 1) memory = number swap = number disk_size = string nic_name = string bridge = string vlan = optional(number) ip = string nameserver = optional(string) gw = string nic2 = optional(object({ nic_name = optional(string, "eth1") bridge = optional(string, "vmbr0") vlan = optional(number) ip = string gw = optional(string) })) })), {}) machines = optional(map(object({ hostname = string vmid = number ip = string vlan = optional(number, 0) template = string full_clone = bool onboot = bool ciupgrade = optional(bool, false) tags = string agent = number memory = number disk_size = optional(string, "32") balloon = number cpu_type = string cores = number sockets = number vcpus = number bios = string machine = string bridge = string nic2 = optional(object({ bridge = optional(string, "vmbr0") vlan = optional(number) ip = string gw = optional(string) })) })), {}) flatcar = optional(map(object({ hostname = string vmid = number ip = string gw = optional(string) vlan = optional(number, 0) bridge = optional(string, "vmbr0") onboot = optional(bool, true) tags = optional(string, "") cores = optional(number, 2) cpu_type = optional(string, "x86-64-v2-AES") memory = optional(number, 4096) disk_size = optional(number, 32) qemu_guest_agent = optional(bool, false) # needs a Butane unit running qemu-ga in a container butane = optional(string) # inline Butane YAML butane_file = optional(string) # path relative to this directory })), {}) })) default = {} } # Flatcar release imported onto every node that runs Flatcar VMs. Pin a version # and copy its sha512 from the image's .DIGESTS file; see opentofu/README.md. variable "flatcar_image" { type = object({ channel = optional(string, "stable") version = string sha512 = string datastore = optional(string, "local") }) default = { version = "4593.2.5" sha512 = "21fdba07ffc73aac80aa40f1f99e0460e2d53b1c2815a774d5e2940d2b5cfa78fb2c86391fbf3bb76e28e8ece1ca41333f30ce18d1dd3f0c016e95bed120aba8" } } variable "snippets_datastore" { description = "Datastore holding Ignition snippets for Flatcar VMs. Needs the snippets content type enabled on every node." type = string default = "local" }