UniFi Terraform adoption
What: a tf/unifi HCP workspace that imports all nine UniFi networks, DHCP Guard included,
through our provider fork (app.terraform.io/fzymgc-house/unifi), plus the doc corrections the
spikes turned up.
Approach: import-only adoption with the View Only credential. The plan is 9 to import,
0 to change, so adoption writes nothing to the controller, and the controller rejects any write
that slips through.
Riskiest assumption: that an arm64 agent-pool run can install the private provider and reach
unifi.fzymgc.house:443. Spikes 004 and 006 proved everything around this except the run
itself; the workspace’s first plan settles it.
Evidence: .planning/spikes/001–006; runbook docs/operations/terraform-provider-fork.md.
1. Decisions you’ll probably want to tweak
Section titled “1. Decisions you’ll probably want to tweak”| # | Decision | Alternative | Cost of changing later |
|---|---|---|---|
| D1 | Workspace credential: View Only (unifi/readonly). Plans and the import-only apply work; any change that needs a write fails loudly at apply, because the controller refuses it |
Add unifi/admin now so merged config changes (e.g. a guard list) apply |
Small: a Vault path, one policy line, and an ephemeral-path swap. Until then, controller changes happen in the UI and the next plan shows the drift |
| D2 | Scope: all nine networks. Guard can be switched on for any network, and an unmanaged network is invisible to the plan | Only the four vlan-only networks, or only Main |
Adding one later is an import block and a resource; dropping one is a removed {} block. The five corporate networks carry inert leftovers (stale subnets, dhcpd_start 192.168.2.6), marked as such in one file comment |
| D3 | One PR for the whole branch: spikes, registry.tf (already applied), docs, the Vault role and policy, the workspace entry, and tf/unifi |
Two PRs: spikes, registry and docs now; adoption after | Cheap either way. One PR works because the workspace doesn’t exist at merge, so the tf/vault and tf/unifi runs can’t race (see §3 ordering) |
| D4 | Import blocks stay after adoption (repo convention) | Remove after the first apply | Trivial |
| D5 | The todo’s “unifi skill” is dropped. A docs/operations/unifi.md runbook plus the plan itself replace it: the pre-cut check becomes “read dhcpd_ip_1..3” or “look at the plan” |
Build the skill anyway (inventory, guard dump, pre-cut verb) | The spike 001 scripts (unifi_session.py, probe_admin_activity.py) are the skill’s core if it’s wanted later |
2. Known unknowns
Section titled “2. Known unknowns”| Unknown | Default | Pivot signal |
|---|---|---|
| Agent pod → controller (spike 004) | Proceed. Nodes are on Main, and tpi-alpha-4’s node IP already reaches the controller | First plan fails with a connect timeout → check node egress and Firewalla Main→Core. The Lab-VLAN cutover (mahfn5xfva) may move the source address later; re-plan after it |
| Agent installs the private provider (spike 006) | Proceed. HashiCorp’s docs say org runs install private providers automatically | init fails on registry auth → check the agent token’s org scope |
| Controller drift before merge | The plan is the check | First plan ≠ 0 to change → reconcile networks.tf or the UI before the apply |
Workspace Terraform ~> 1.15.0 vs local 1.16.3 |
required_version = "~> 1.15" like the other modules |
init or lock complaints |
3. Mechanical work
Section titled “3. Mechanical work”tf/vault:vault_policy.terraform_unifi(read onsecret/data/fzymgc-house/infrastructure/unifi/readonlyonly) andvault_jwt_auth_backend_role.tfc_unifibound tomain-cluster-unifi, modelled ontfc_dns_records.tf/hcp-terraform:main-cluster-unifi = { dir = "tf/unifi", tags = ["main-cluster", "unifi"] }(agent mode by default).tf/unifi:versions.tf(fork, exact pin),terraform.tf(cloud block,ephemeral "vault_kv_secret_v2"for the credential,provider "unifi"),imports.tfandnetworks.tffrom spike 005’sapi-truth, and.terraform.lock.hcllocked forlinux_arm64+darwin_arm64.- Docs: new
docs/operations/unifi.md(what the controller governs, credentials, what Terraform manages, the admin-activity drift check, the DHCP Guard pre-cut check); fixdns.md(the list isdhcpd_ip_1..3, drop “trust the live test overdhcpguard_ip”, keep the.20.1rollback note);docs/reference/network.mdpointer; operations index. - Todo: close
2026-08-24-bring-the-unifi-configuration-into-the-repothrough its GSD verb, not by hand. - Ordering after merge:
tf/vaultauto-applies the role → the operator appliestf/hcp-terraform(creates the workspace) → queue its first run → plan 9 to import, 0 to change → the import-only apply writes state only. That run closes spikes 004 and 006. - Verification before the PR: local plan against the published provider (already 9/0),
terraform fmt, and speculative plans oftf/vaultandtf/hcp-terraform.
Review (answered 2026-09-19)
Section titled “Review (answered 2026-09-19)”- D1:
unifi/adminnow (not the recommendation). The workspace readssecret/fzymgc-house/infrastructure/unifi/admin(accountautomation-admin, Network: Full Management) through policyterraform-unifi;unifi/readonlystays for agents and probes. Merged config changes apply to the controller, and the first run is still import-only. - D2: all nine networks.
- D3: one PR.
- D5: the unifi skill is dropped;
docs/operations/unifi.mdand the plan replace it.