VM 605 is pinned to saturn, so it cannot survive the conversion, and it has to
go before the node leaves the Proxmox cluster — afterwards the provider cannot
reach it and every plan errors.
Nothing uses it. Its purpose was cloning new Proxmox VMs, Proxmox is being
retired, and the one remaining VM definition sets template_name = null
explicitly rather than cloning from it.
The module default is changed to null for the same reason: it named a template
that no longer exists, which would only surface as an apply-time failure for
whoever created the next VM.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The agents are unprivileged Proxmox LXCs whose ip_config had only an ipv4
block — no IPv6 at all. So no matter how Docker/Woodpecker were configured
for v6 (daemon.json ip6tables, WOODPECKER_BACKEND_DOCKER_ENABLE_IPV6), the
step containers had no v6 uplink to NAT onto, and deploys to v6-only hosts
(proxy-1) failed 'Network unreachable'. IPv4 NAT works in these LXCs, so v6
NAT will too once the LXC actually has v6.
Add an optional ipv6 block to the proxmox_lxc module (auto/dhcp/static) and
set ipv6_address = "auto" (SLAAC off v40srv) for the agents.
NOTE: `initialization` is in the module's ignore_changes, so this does NOT
apply to running agents on a normal apply — they must be RECREATED to pick
up v6 (they're tagged `transient`). Recreate one at a time to keep CI up,
then re-run install-woodpecker-agent.yml on each.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
DNS: removed pve/home/auth/dash from caddy_srv_renner_uno.ingress_cnames
in opentofu/ingress.tf. pve is now fronted by the new K8s ingress-nginx
path (apps/pve Service + EndpointSlice with the three cluster IPs);
home and auth have been served by ingress-nginx for a while and the
live UniFi A records are owned by external-dns-unifi -- the orphan
CNAMEs in the file were drift that would have been re-created on next
apply, breaking the working setup. dash backend is dead (502 via
Caddy, confirmed via curl).
Compute: every Proxmox guest under tofu management is now flipped to
stopped/onboot=false, except LXC 250 (registry-mirror) which keeps
flux/woodpecker image pulls working:
LXCs (start=false, onboot=false, hastate="stopped"):
117 cloudflared -- replaced by K8s cloudflared Deployment
121 ical-proxy -- replaced by K8s apps/ical-proxy
212 audiobookshelf -- replaced by K8s audiobookshelf
225 immich -- replaced by K8s immich
226 loki -- retired
227 prometheus -- replaced by K8s monitoring
229 music-assistant -- replaced by K8s music-assistant
232/233/234 caddy -- this whole retirement work
260 netbird-gateway -- retired
130/131/132/133 authentik HA -- replaced by K8s authentik
VMs (vm_state="stopped", onboot=false):
102 fortress
103 home-assistant -- replaced by K8s home-assistant
108 influxdb
109 grafana -- replaced by K8s monitoring
111 paperless -- replaced by K8s paperless
Module change: removed `started` from the proxmox_vm module's
ignore_changes list. The previous behaviour ("Don't force start/stop
state") meant tofu would silently drop vm_state changes, leaving the
five VMs above running indefinitely. The trade-off is that any VM
manually stopped for maintenance (e.g. a K8s node) will be auto-
restarted on the next tofu apply -- be aware.
`hastate` is dead-code in both proxmox_lxc and proxmox_vm modules
(declared as a variable, not consumed anywhere). The hastate="stopped"
edits are documentation only -- Proxmox HA state still has to be
managed via the Proxmox UI / pve-ha-manager / API. If pve-ha is
holding any of these in started state, it will fight the tofu stop.
LAN-side CNAMEs on the per-LXC ingress_cnames lists (e.g.
photos.renner.uno on lxc_225 immich) are intentionally left alone
in this commit -- they'll either be auto-cleared by external-dns-unifi
once the K8s Ingress claims the name, or fall stale pointing at a
dead Caddy VIP. Cleaning those up is a follow-up sweep.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The earlier path_in_datastore (raw filesystem path) approach hit a
hardcoded PVE check: only root@pam can pass arbitrary filesystem
paths to qm. The Ansible API token can't, regardless of role.
Hardware Mappings sidestep this — a cluster-level PCI mapping
"osd-ssd" was created on PVE pointing to each node's freed NVMe;
the API token is allowed to attach mapped devices.
- proxmox_vm module: add `hostpci` variable + dynamic block, indexed
via list position (hostpci0, hostpci1, ...)
- vm_150/151/152: drop the virtio1 disk entry, add `hostpci = [{ mapping = "osd-ssd" }]`
- CephCluster: device renamed `vdb` -> `nvme0n1`. With PCI passthrough
the NVMe enumerates inside Talos via the nvme driver, not virtio-blk.
The path_in_datastore plumbing in the module stays — it's harmless
when unused and may serve other use cases later.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Each PVE node's second NVMe was evacuated from rpool via `zpool remove`
and wiped. Talos VMs 150/151/152 now consume their respective Crucial P3
directly via path_in_datastore, eliminating the Bluestore-on-ZVOL-on-ZFS
double-allocator path and ARC-vs-osd_memory_target contention.
Module gains an optional path_in_datastore disk field. When set,
datastore_id is forced to "" and size is omitted; existing ZVOL disks
are unaffected. Disk is in lifecycle.ignore_changes, so this only takes
effect on the next rebuild-k8s `-replace`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Music Assistant needs L2 reach to the IoT VLAN for mDNS / uPnP /
Chromecast / SlimProto discovery. Adds an optional
extra_network_bridges list to the proxmox_vm module and uses it to
give VM 153 a second NIC on v30iot, keeping v40srv as the primary
cluster interface.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rebuild-k8s pipeline was hanging on the destroy phase of `tofu apply
-replace` because BPG issues a graceful shutdown and waits up to 1800s
(provider default `timeout_shutdown_vm`) for Talos guests that don't
respond. Setting `stop_on_destroy = true` on all 4 K8s VMs switches the
provider to `qm stop` (hard power-off), so destroy is immediate.
- Module gains `stop_on_destroy` variable (default false preserves
existing behavior for every other VM).
- Opted in on k8s-1/2/3 (controlplane) and k8s-edge (worker).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The raw image is only ~8.6GB, leaving too little ephemeral storage
for Kubernetes pods. Specifying size=32G tells the provider to expand
the disk after importing the image.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a disk is imported from a file_id, the size comes from the image.
Setting both size and file_id causes the provider to fail with an
invalid volume ID error.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace NFS ISO dependency with proxmox_virtual_environment_download_file
that pulls the Talos nocloud image directly from factory.talos.dev to
each Proxmox node's local storage. VMs boot from the raw disk image
instead of CDROM, eliminating the Install NFS storage dependency.
- Add talos_image.tf with download_file resource per node
- Add file_id support to proxmox_vm module disk config
- Remove CDROM from K8s VM definitions
- Boot order changed to virtio0 only
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The BPG Proxmox provider deprecated the cdrom enabled attribute.
Remove it from the module and VM definitions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add cdrom and agent_enabled variables to the proxmox_vm module so VMs
can boot from ISO images. Attach Talos 1.10 nocloud ISO to the 3 K8s
VMs and disable QEMU guest agent (Talos doesn't support it).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mount point volume format needs numeric size without G suffix.
Restore separate taint and apply commands in pipeline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update Authentik HA LXC configuration
- Update Proxmox VM module
- Update Home Assistant and Paperless VM configs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create modules/dns_records/ for reusable DNS record management
- Update proxmox_vm module to use shared DNS module
- Update proxmox_lxc module to use shared DNS module
- Add moved blocks for zero-downtime state migration
- Remove duplicated unifi provider requirement from VM/LXC modules
Resolves MAINT-2 from infrastructure review.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add /etc/hosts fix to common role for all LXC containers
(Proxmox sets 127.0.1.1 which breaks services resolving own hostname)
- Add network_interface to ignore_changes in LXC module
(Prevents network disruption during tofu apply)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add features to ignore_changes in LXC module (API token limitations)
- Add device_passthrough support for GPU/device passthrough in LXC
- Normalize MAC addresses to uppercase for Proxmox compatibility
- Add architecture field to CPU block
- Add keyctl to features block
- Fix tag parsing to handle both comma and semicolon separators
- Add agent_trim and USB mapping support to VM module
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace Telmate/proxmox v3.0.2 with bpg/proxmox v0.95.0
- Convert modules/proxmox_vm to BPG resource syntax
- Convert modules/proxmox_lxc to BPG resource syntax
- Update vm_605_template.tf to use proxmox_virtual_environment_vm
- Fix API token format in providers.tf (remove duplicate @pam)
- Add comprehensive lifecycle ignore_changes to prevent unnecessary replacements
- Handle disk size parsing for both G and M suffixes
- Fix empty tags handling with compact()
- Temporarily switch to local backend (S3 backend has quorum issues)
Breaking changes:
- Resource types changed from proxmox_lxc/proxmox_vm_qemu to
proxmox_virtual_environment_container/proxmox_virtual_environment_vm
- State was recreated by importing all resources from Proxmox cluster
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created unifi_targets.txt and unifi_targets_strict.txt files to define DNS records for services including authentik, caddy, and others.
- Included ingress CNAMEs for modules such as audiobookshelf, gitea, grafana, and more.
- Ensured both files contain comprehensive lists of DNS records to support service discovery and routing.