Files
spinifex/scripts/ansible
joshsiv-mulga e7bbc64a45 feat(ansible): require --external-pool, drop NAT, forward EXTRA_VARS
spx admin init now rejects --external-mode=nat and demands --external-pool
when mode=pool. The ansible init role silently skipped pool flags when the
range was unset, so installs fell over inside the spx validator. Make
targets also swallowed `-e` (make's env-override flag), so operators could
not override pool start/end without editing defaults.yml.

- vars/defaults.yml: rename nat_gateway_ip → external_gateway_ip; add
  spinifex_external_no_external opt-out; document the spx flag contract.
- roles/init/tasks/main.yml: drop NAT branch; assert pool range upfront
  with a fail_msg pointing at EXTRA_VARS / defaults.yml; emit gateway,
  prefix-len, gateway-ip only when explicitly set (let spx auto-detect);
  honour --no-external.
- playbooks/dev-reset.yml: rename captured var; coerce legacy
  external_mode=nat to pool with a warn; tighten gateway regex with \b.
- Makefile: ansible-dev-* targets now forward EXTRA_VARS="key=val ..."
  through --extra-vars so `make` callers can override without editing
  defaults.yml.
- scripts/ansible/README.md: document pool requirement, both invocation
  styles (direct -e vs make EXTRA_VARS), NAT removal.
2026-05-25 09:33:53 +10:00
..

Ansible Dev Lifecycle (parallel to bash scripts)

Experimental Ansible-based lifecycle for a single-node Spinifex dev host. Lives alongside the existing scripts/dev-*.sh and scripts/reset-dev-env.sh; neither set is removed. Decide which to keep after parity testing.

Plan: docs/development/improvements/ansible-dev-lifecycle.md (mulga top-level). Bead: mulga-siv-9.

Prerequisites

Venv lives at sub-repo root (spinifex/.venv/) — one venv per sub-repo, shared by any future python tooling in spinifex. Bootstrap from spinifex/:

sudo apt install python3.13-venv
python3 -m venv .venv
source .venv/bin/activate
pip install 'ansible>=9'
ansible-galaxy collection install -r scripts/ansible/requirements.yml

Then cd scripts/ansible to run playbooks — ansible.cfg resolves the inventory and roles relative to CWD.

Playbooks

Playbook Purpose Bash parity
playbooks/dev-preflight.yml Dependency + port check dev-setup.sh §checks
playbooks/dev-teardown.yml Wipe state only (no reinstall) reset-dev-env.sh §teardown
playbooks/dev-install.yml Build + install + init + smoketest on clean box dev-install.sh
playbooks/dev-reset.yml Capture settings → teardown → build → install → init → smoketest reset-dev-env.sh (full)
playbooks/dev-deploy.yml Rebuild + swap binaries/microvm artifacts + restart (no setup.sh, no smoketest) make deploy

Upcoming (not yet implemented):

  • dev-mode-start.yml / dev-mode-stop.yml — parity with start-dev.sh / stop-dev.sh (lowest priority — deprecated bash scripts, CI-only callers).

Invocation

ansible-playbook playbooks/dev-preflight.yml
ansible-playbook playbooks/dev-teardown.yml
ansible-playbook playbooks/dev-install.yml
ansible-playbook playbooks/dev-reset.yml
ansible-playbook playbooks/dev-deploy.yml

Or via make (from spinifex/):

make ansible-dev-preflight
make ansible-dev-teardown
make ansible-dev-install
make ansible-dev-reset
make ansible-dev-deploy

When to use which

  • First-time / clean box → ansible-dev-install
  • Iterate on Go code, microvm initramfs, lb-agent → ansible-dev-deploy (fast)
  • Changed systemd units, helper scripts, logrotate, setup.sh → ansible-dev-reset (slow, full rebuild)
  • Need a clean slate without reinstall → ansible-dev-teardown

Variable overrides

Defaults in vars/defaults.yml. Override per run with -e:

ansible-playbook playbooks/dev-teardown.yml -e spinifex_wipe_ssh_keys=true

Useful overrides:

Var Default What it does
spinifex_wipe_legacy_home true Remove $HOME/spinifex (legacy dev-mode path)
spinifex_wipe_ssh_keys false Remove ~/.ssh/spinifex-key*
spinifex_wipe_aws_creds false Remove spinifex profile from ~/.aws/credentials
teardown_process_wait_seconds 30 Grace period for processes to exit
spinifex_region ap-southeast-2 Region passed to spx admin init
spinifex_az {{ region }}a AZ passed to spx admin init
spinifex_external_mode pool External networking mode — pool or empty (NAT removed)
spinifex_external_no_external false true → emit --no-external and skip external networking
spinifex_external_pool_start "" Required for pool mode — first IP of the static WAN pool
spinifex_external_pool_end "" Required for pool mode — last IP of the static WAN pool
spinifex_external_gateway "" WAN gateway (auto-detected when blank)
spinifex_external_prefix_len "" WAN prefix length (auto-detected when blank)
spinifex_external_gateway_ip "" OVN router external-IP override (--gateway-ip)

pool mode is mandatory unless you set spinifex_external_no_external=true. spx admin init rejects the run without a --external-pool range, so the init role asserts spinifex_external_pool_start/_end upfront. Either persist them in vars/defaults.yml, or pass them at invocation:

Direct ansible-playbook (use -e here — this is ansible's flag):

ansible-playbook playbooks/dev-install.yml \
  -e spinifex_external_pool_start=192.168.1.150 \
  -e spinifex_external_pool_end=192.168.1.250

Via make (use EXTRA_VARS= — make eats its own -e):

make ansible-dev-install \
  EXTRA_VARS="spinifex_external_pool_start=192.168.1.150 spinifex_external_pool_end=192.168.1.250"

dev-reset.yml automatically captures region, az, external_mode, pool range, gateway, prefix-len and gateway_ip from the existing /etc/spinifex/spinifex.toml before teardown and replays them into init. Legacy external_mode = "nat" is coerced to "pool" with a warn. Use -e to override.

Leak catalog

roles/teardown/README.md tracks every known state source. When teardown misses something, add it there and in roles/teardown/tasks/main.yml.