# OpenTofu / provider documentation -- sources, versions, and fetch method

Read this before writing or extending anything under `repo opentofu/` (the
VR1 DC-DC infrastructure-as-code, D-103). Built up during the 2026-07-09
OpenTofu delivery; see `repo opentofu/README.md` for the full, per-module
account (schema notes, an "Audit pass" section, and every finding's exact
sourcing) -- this file is the index into that plus the fetch methodology,
so a future session does not have to rediscover it by trial and error.

## The core lesson: doc-summarization is lossy, real example code is not

Every provider doc page fetched this session went through a summarizing
model, which reliably got FIELD NAMES right but repeatedly lost or
mis-stated CALL SYNTAX (block vs. attribute style, exact nesting). The
`opentofu/` scaffold shipped with a real syntax bug from trusting doc
summaries alone (fixed once real example `.tf` files were fetched and
read directly -- see `repo opentofu/README.md`'s syntax-bug note). **For any
new provider/resource: find real example `.tf`/`.go` source before trusting
a doc-summary's syntax claims.** Doc-summaries are fine for "what fields
exist"; they are not reliable for "how do I write this."

## Fetch gotchas

- The Terraform/OpenTofu Registry's own doc pages (`registry.terraform.io/
  providers/.../docs`) are client-side-rendered -- a plain fetch returns only
  the page shell, no content. Go straight to the provider's GitHub repo
  instead.
- GitHub's raw file URLs need the CORRECT default branch (varies: `main` for
  some repos, `master` for others -- check `api.github.com/repos/<org>/<repo>`
  for the `default_branch` field first, don't guess).
- A general web search's own synthesized "summary" of a doc page can itself
  be wrong (encountered once this session: a search summary confidently
  named the wrong branch and file path). Treat search-result summaries as
  leads to verify, not answers -- always follow through to the primary
  source.
- When a fetch refuses to "reproduce verbatim" (copyright caution), ask for
  a specific, narrow thing instead -- "list bare field names only, no
  prose" reliably works where "reproduce this page" does not.
- `api.github.com/repos/<org>/<repo>/contents/<path>` (a JSON directory
  listing) is a reliable way to discover the REAL current file layout when
  a guessed raw-file path 404s -- doc reorganizations happen (one provider
  moved from `website/docs/r/*.markdown` to `docs/resources/*.md` between
  the versions training data and current reality disagree on).

## Providers used in `repo opentofu/`

### `dmacvicar/libvirt` (pinned `0.9.8`, confirmed 2026-07-09)

**Before writing any `libvirt_domain`, read `references/platform-traps.md`
section 1.** Four schema-level traps there have each cost real time and none
of them is a validate-time error: bare `memory` is KiB not MiB; no `features`
block means `acpi=off`; no `cpu` block means no `svm` (nested KVM silently
impossible); and "will be updated in-place" still BOUNCES the guest.

- Registry: https://registry.terraform.io/providers/dmacvicar/libvirt/latest
  (JS-rendered -- use the GitHub repo for actual content)
- GitHub: https://github.com/dmacvicar/terraform-provider-libvirt (default
  branch `main`; there is no `CHANGELOG.md` -- the release NOTES on the
  releases page are the changelog, and they are unusually informative:
  `.../releases/tag/v0.9.0` is the breaking-rewrite rationale, `v0.9.1` is the
  0.9.0->0.9.1 attribute-rename migration guide)
- **Version boundary that invalidates most examples on the internet:** 0.9.0
  (2025-11-08) is a compatibility-BREAKING rewrite (plugin framework, "HCL maps
  almost 1:1 to libvirt XML"); the legacy provider lives on the `v0.8` branch.
  0.9.1 then code-generated the schema and renamed attributes again. Anything
  0.8-era -- including model memory -- is wrong for this pin.
- Docs: `docs/resources/*.md`, `docs/data-sources/*.md` (NOT the older
  `website/docs/r/*.markdown` layout some search results/training data
  reference -- that's stale)
- **Real example `.tf` files (the higher-value source): `examples/*.tf`** --
  `domain_with_network.tf`, `alpine_cloudinit.tf` were the two that resolved
  every syntax question this session. Fetch these FIRST for any new
  resource, before the doc pages.
- Key fact: this provider code-generates its schema as a 1:1 mirror of
  libvirt's own domain/network/pool XML (confirmed via a general search of
  provider discussion, not the docs pages themselves) -- when a Terraform
  schema question stalls, libvirt's own native XML docs
  (https://libvirt.org/formatdomain.html, https://www.libvirt.org/pci-addresses.html)
  are a legitimate, stable cross-reference for what a nested attribute is
  likely to be named/shaped, since the mapping is direct.

### `canonical/maas` (pinned `2.7.2`, confirmed 2026-07-09)
- Registry: https://registry.terraform.io/providers/canonical/maas/latest
  (same JS-rendering issue -- use GitHub)
- GitHub: https://github.com/canonical/terraform-provider-maas (default
  branch `master` -- NOT `main`, confirmed by checking `default_branch`
  directly rather than assuming)
- Docs: `docs/resources/*.md`, `docs/index.md` (provider block config)
- Moved from an older `maas/maas` registry namespace -- use `canonical/maas`,
  not `maas/maas`, for anything current.
- Key lesson (see `repo opentofu/README.md`'s "MAAS registration + tc netem
  research" section for the full account): `maas_vm_host` (register a virsh
  chassis) and `maas_vm_host_machine` (MAAS composes/creates a new VM
  itself) are NOT interchangeable -- read the schema (which fields are
  INPUTS) before assuming a resource matches a design intent just because
  its name sounds related.

### OpenTofu core (language features, not a provider)
- `local-exec` provisioner: https://opentofu.org/docs/language/resources/provisioners/local-exec/
- `terraform_data` (built-in, replaces the older `null_resource` for
  provisioner-only use): https://opentofu.org/docs/language/resources/tf-data/
  (note the URL slug is `tf-data`, not `terraform_data` or `terraform-data`)
- Both pages rendered cleanly on a direct fetch (static docs, no JS-rendering
  issue) -- these were the most reliable fetches of the whole session.

### OPNsense (not a Terraform provider -- the guest OS itself)

**SUPERSEDED RESEARCH WARNING (2026-07-12/13).** `repo opentofu/README.md`'s
"OPNsense deployment research" section and the 2026-07-09 changelogs describe a
**config-ISO / Configuration-Importer** delivery path. That path is DEAD and its
code is DELETED:
- **D-112:** the Configuration Importer can NEVER fire on a pre-installed nano
  image (upstream `opnsense-importer` probes for a read-only root and exits
  before scanning media). The ISO was inert; nothing was ever going to read it.
- **D-113 (ADOPTED 2026-07-13, option a2):** OPNsense STAYS, but config moves to
  the **REST API**. `opentofu/templates/opnsense-config.xml.tmpl`,
  `scripts/opnsense-render-config.sh` and `scripts/opnsense-build-config-iso.sh`
  are DELETED, along with the module's `config_seed` volume + cdrom disk.
  **A rendered-`config.xml` push would now CLOBBER live API-managed DHCP.**

Current path: `scripts/opnsense-api.sh` (REST client) +
`scripts/opnsense-bootstrap-apikey.sh` (mints a key via OPNsense's own model
over SSH). Traps, exact endpoints, the mandatory `service/reconfigure` step, the
60-second firewall auto-rollback, and the tcsh trap: `references/platform-traps.md`
section 4.

- Official docs: https://docs.opnsense.org/manual/install.html;
  REST API: https://docs.opnsense.org/development/how-tos/api.html;
  26.1 release notes (ISC-DHCP left core; dnsmasq is the new default):
  https://docs.opnsense.org/releases/CE_26.1.html
- Still-valid finding from the 2026-07-09 research: cloud-init is unreliable on
  FreeBSD, so `modules/cloudinit-vm` genuinely does not apply to OPNsense
  (https://forum.opnsense.org/index.php?topic=42517.0), and the nano image (not
  the installer image) is the one to use.
- Historical only (the ISO mechanism these describe cannot fire on nano):
  https://github.com/opnsense/core/issues/5733, .../issues/10017.

## Where the full findings live (don't duplicate here, it will drift)

**Caveat first (2026-07-13):** `repo opentofu/README.md` predates D-112/D-113
and its "OPNsense deployment research" section still describes the DELETED
config-ISO path -- see the superseded-research warning above before acting on
anything it says about OPNsense. Its libvirt schema notes also predate the four
domain traps in `references/platform-traps.md` section 1. Everything else in it
still stands.

`repo opentofu/README.md` is the authoritative, per-module account --
schema notes, what's confirmed vs. assumed per attribute, and a dated
"Audit pass" section recording a later re-review (a real documentation
error was found and fixed there: an early claim that libvirt interface
list-order directly sets OPNsense's LAN/WAN role conflated two separate
mechanisms -- read that section before trusting anything about NIC
ordering/roles). Treat this file as the index/methodology; treat that one
as the ground truth for what each module actually does and why.
