Docker bind mount fails when mounting a file that doesn't exist on
the host (creates a directory instead). In CI, the container's
$WORK_DIR path differs from the host path, so the file mount failed.
Changed to mount a single answer-server/ directory containing both
default.toml and answers/ subdirectory. Replaced two TF variables
(answer_files_dir, default_answer_file) with one (answer_server_dir).
Layout: $WORK_DIR/answer-server/default.toml + answers/<mac>.toml
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Changed Terraform ISO resource from for_each=pve_instances (per-node)
to for_each=pve_isos (per-version). With HTTP answer server, both
nodes of the same version share the same generic ISO.
New pve_isos variable maps version to ISO path. pve_instances now
has pve_version field instead of iso_local_path. VMs reference
their version's ISO via auto_iso[each.value.pve_version].
Updated run-integration.sh tfvars generation and -target flags
for both provision and cleanup to use the new schema.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace 4 per-node auto-install ISOs (~4GB) with 2 generic ISOs
(~2GB) served by an HTTP answer server that routes per-node configs
by MAC address.
New flow:
1. Deterministic MAC addresses assigned per node (AA:BB:CC:00:VV:NN)
2. Per-MAC answer.toml files generated in answers/ directory
3. HTTP answer server (slothcroissant/proxmox-auto-installer-server)
managed by Terraform, serves answer files on port 8000
4. Generic ISOs prepared with --fetch-from http --url pointing to
the answer server
5. PVE installer POSTs system info, server matches MAC to answer file
Benefits:
- 50% reduction in ISO disk/tmp usage (2 ISOs instead of 4)
- Faster ISO preparation (2 builds instead of 4)
- Answer files can be updated without rebuilding ISOs
- First-boot script embedded in generic ISO via --on-first-boot
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major provisioning pipeline changes:
Terraform:
- Add kreuzwerker/docker provider to manage iSCSI and NFS storage
containers alongside PVE VMs in a single Terraform config
- New storage.tf with Docker container, image, and volume resources
- docker_host_ip variable for PVE nodes to reach storage services
Provisioning:
- Replace docker-compose storage management with Terraform
- Replace create-api-token.sh with wait-for-pve.sh (IP discovery +
API readiness + auth verification only — no token creation)
- Tests use root@pam credentials, not API tokens
Cleanup:
- Replace preflight-cleanup.sh loop with terraform destroy
- Supports version filtering: cleanup 9 destroys only PVE 9 resources
- Full cleanup also removes config.json and tfvars
New commands:
- taint [8|9|all]: marks VMs for recreation on next provision
- dev.ps1 -Reprovision: runs taint before provision to force VM rebuild
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provision two PVE nodes per version (a/b) for future cluster testing,
plus Docker-based iSCSI target and NFS server for shared storage tests.
Multi-node changes:
- Each PVE version gets two nodes: 9a/9b and 8a/8b (4 VMs total)
- Parameterized answer.toml FQDN for unique hostnames per node
- Per-node auto-install ISOs with unique answer files
- Node name discovered from FQDN and included in test config
- API token creation handles pre-existing tokens (delete + recreate)
- New test env vars: PVETEST_HOST_B, PVETEST_APITOKEN_B
- Removed preflight cleanup from provision (use explicit cleanup instead)
Docker storage services:
- New docker-compose.storage.yml with iSCSI (tgt) and NFS containers
- Host networking so PVE nodes can reach storage services
- Docker socket mounted into dev-infra container for host Docker access
- Docker CLI added to dev-infra Dockerfile stage
- New test env vars: PVETEST_STORAGE_VM_IP, PVETEST_ISCSI_IQN, PVETEST_NFS_EXPORT
Other fixes:
- first-boot.sh installs open-iscsi on PVE nodes
- preflight-cleanup.sh handles empty ISO filename gracefully
- TMPDIR set to work dir to avoid /tmp overflow during ISO uploads
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CI workflow: PVE_PASSWORD now reads from secrets.PVE_TEST_PASSWORD
- variables.tf: removed default password, requires TF_VAR env var
- Integration README: examples use <your-test-password> placeholder
- create-api-token.sh: example IP changed to pve.example.com
- .gitignore: added .env/.env.* exclusion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restructures the integration test workflow from a monolithic sequential
job into separate provision → test → cleanup stages:
- provision: creates ALL nested PVE VMs in a single terraform apply
(parallel), waits for APIs, creates tokens, passes outputs to tests
- test: matrix [pve9, pve8] consumes provision outputs, no provisioning
- cleanup: always runs, API-only teardown for all VMs
Terraform refactored to for_each with pve_instances map variable,
enabling parallel ISO upload and VM creation.
New caching scripts reduce redundant downloads:
- ensure-base-iso.sh: downloads PVE ISOs to /opt/pve-isos if missing
- ensure-cloud-images.sh: caches cloud image + OVA with 7-day TTL
- prepare-auto-iso.sh: --cache-dir flag with hash-based skip
Runner no longer needs manual ISO provisioning (zero-touch setup).
cleanup-images bumped to min-versions-to-keep: 3 to survive overlapping
runs. All jobs gated against dependabot.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use proxmox_virtual_environment_file resource to upload the auto-install
ISO via the API. terraform destroy now cleans up both the VM and ISO.
- Remove manual upload-to-pve.sh and cleanup-pve-storage.sh scripts.
- Commit .terraform.lock.hcl for reproducible CI builds.
- Replace iso_file_id variable with iso_local_path and iso_storage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Workflow now provisions a throwaway nested PVE VM via Terraform, runs
integration tests against it, then destroys it. Uses proxmox-auto-install-assistant
to bake the answer file and a first-boot script (installs qemu-guest-agent)
directly into the ISO. IP is discovered via the QEMU guest agent on the
parent PVE, eliminating the need for static IP configuration.
Supports both PVE 8.x and 9.x via workflow_dispatch version selector.
Skip provisioning with skip_provision=true to test against a pre-existing PVE.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove ISO upload and answer-file resources (pre-provisioned manually)
- Remove null_resource wait/token steps (token created out-of-band)
- Switch iso_file to iso_file_id referencing an existing Proxmox file ID
- Add lifecycle ignore_changes for started and cdrom
- Update README with proxmox-auto-install-assistant ISO prep instructions
- Update default variables to match homelab environment
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Provisions a throwaway nested Proxmox VE instance on an existing host
using bpg/proxmox provider. Includes unattended install via answer file,
API wait script, and automatic API token creation. Designed for CI-driven
integration test environments.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>