No live infrastructure touched -- unapplied IaC/scripts only. Implements the mechanism identified in the same-day OPNsense deployment research (docs/changelog-20260709-opnsense-research.md).
scripts/opnsense-prep-image.shFILE (new): scripts/opnsense-prep-image.sh + tests/opnsense-prep-image/run-tests.sh.
WHAT: downloads the OPNsense nano image, decompresses it, converts raw -> qcow2, and grows it -- the preprocessing libvirt_volume's create.content.url can't do itself (it almost certainly performs a plain fetch, no decompression). No mirror URL is hardcoded -- OPNSENSE_MIRROR_BASE is a required env var (hard rule 2: never use an inferred value; OPNsense publishes multiple mirrors and a silently-hardcoded one risks going stale unnoticed).
HARNESS: 4/4 green, but only the guard-clause paths this environment can exercise -- qemu-img is genuinely absent here, so that failure path is real, not synthetic; the actual download/convert/resize behavior is UNTESTED (would need qemu-img + network access to a real mirror).
scripts/opnsense-build-config-iso.shFILE (new): scripts/opnsense-build-config-iso.sh + tests/opnsense-build-config-iso/run-tests.sh.
WHAT: builds a plain ISO9660 image containing /conf/config.xml, for OPNsense's Configuration Importer (see the OPNsense research changelog -- ISO9660 support was added to the Importer specifically for VM/cloud automation). Uses genisoimage/xorriso, whichever is present.
HARNESS: 3/3 green, same caveat -- neither ISO tool is present in this environment, so the missing-tool guard is exercised for real, but the actual ISO construction and whether OPNsense's Importer picks it up on a real boot are UNTESTED. The exact genisoimage/xorriso invocation is a reasonable, standard construction for a plain ISO9660 volume with one file at a fixed path -- not independently verified.
opentofu/modules/opnsense-edgeFILES (new): opentofu/modules/opnsense-edge/{main,variables,outputs}.tf.
WHAT: one OPNsense edge VM per call. Mechanically identical to modules/cloudinit-vm's shape (a backing_store overlay disk + a secondary volume attached as cdrom), but with the config-seed volume's create.content.url pointing directly at the ISO9660 file built by script 2 above -- no libvirt_cloudinit_disk resource involved (that's NoCloud-format, wrong for this). Two explicit variables, lan_network_name and wan_network_name, rather than a generic ordered list -- OPNsense's own interface-1-is-LAN/interface-2-is-WAN convention makes list-ordering a real silent-mistake risk, so the names are explicit instead. No PXE boot-order attribute used (unlike node-vm): this VM boots from its own pre-installed disk, not over the network, so the field flagged UNVERIFIED in node-vm/main.tf doesn't need touching here at all.
TWO THINGS FLAGGED, NOT PRESENTED AS FACT: (a) whether the Configuration Importer's ISO9660 support behaves as described on a real boot -- the research is well-sourced (a closed, milestone-targeted, core-developer- assigned GitHub issue plus a corroborating later bug report) but not independently tested this session; (b) whether devices.interfaces list order reliably maps to which NIC FreeBSD/OPNsense enumerates first vs. second -- assumed consistent with general libvirt XML ordering, not independently confirmed for this specific guest OS.
config_iso_path has no default and no fallback: the real config.xml content for any site's LAN/WAN/routing role is design work that hasn't happened. Not instantiated in root main.tf.
opentofu/README.md updated: the "Scope of this delivery" and OPNsense research sections both now describe this as BUILT (not just researched), with the schema notes section gaining a new entry on create.content.url accepting local filesystem paths (the mechanism both new scripts' outputs rely on, inferred from examples/alpine_cloudinit.tf's libvirt_cloudinit_disk.path usage, not independently named in the docs pages fetched this session). Workflow doc gap register item 4 and its summary-table row updated to match; companion visual tracker (same Artifact URL) redeployed.
REVERT: git rm -r opentofu/modules/opnsense-edge scripts/opnsense-prep-image.sh scripts/opnsense-build-config-iso.sh tests/opnsense-prep-image tests/opnsense-build-config-iso; revert the opentofu/README.md and workflow-doc sections if reverting fully.
Same underlying need as DOCFIX-144/145: a machine with the tofu binary, qemu-img, and genisoimage/xorriso to actually run the full chain -- opnsense-prep-image.sh for real, opnsense-build-config-iso.sh for real, then tofu apply the module and boot it, to confirm the Configuration Importer's ISO9660 behavior and the LAN/WAN interface-ordering assumption against a real OPNsense instance rather than sourced-but-unverified research.