Proxaform is a free, open-source orchestration tool for provisioning and tearing down Proxmox LXC containers, using a combination of Bash, Terraform, and Ansible. It wraps the full lifecycle — dependency setup, infrastructure provisioning, and post-deploy configuration — into three simple scripts.
- One-command environment bootstrap (installs Terraform, Ansible and
yqif missing) - Interactive prompts to define new container configurations, saved as reusable
.tfvarsfiles - Automatic SSH key injection — no keys to copy or paste
- Automatic Ansible inventory generation with group assignment
- Waits for SSH availability before running your playbook
- Playbook selection menu — any
.yml/.yamlfile underplaybooks/is available immediately - Guarded, confirmation-gated teardown that also cleans up the inventory
- Full run logging to timestamped files under
logs/
New to Proxaform? Follow the step-by-step guide:
- Getting Started — prerequisites, Proxmox user & permissions, running
setup.sh, and how the SSH key works - First Deployment — what
.tfvarsfiles are, how to create them, and a full walkthrough of deploying a container - Teardown — safely removing a deployed container
For those already comfortable with Proxmox, Terraform and Ansible.
Requirements: Ubuntu/Debian or RHEL-family control machine with sudo and nc; a Proxmox VE user with the required privileges; an Ubuntu LXC template on your Proxmox storage.
git clone https://github.com/asbedb/proxaform.git && cd proxaform
./setup.sh # install deps, create SSH key -> secrets/id_ed25519.pub
./deploy.sh playbooks/networking/ping.yml # provision a container + run a playbook
./destroy.sh # tear it downKey points:
.tfvarsfiles live insecrets/. Create one via thedeploy.shwizard, or copyterraform/terraform.tfvars.examplethere and edit it. One.tfvarsfile = one container — its state is stored alongside it as<name>.tfstate.authorised_ssh_keyis automatic.deploy.shinjectssecrets/id_ed25519.pub; do not put it in your.tfvars.- Passwords are prompted, not stored. Terraform asks for
proxmox_privileged_user_passwordandcontainer_root_passwordat deploy/destroy time. - Inventory groups matter. Every node joins
proxmox_nodes; add the group named in your playbook'shosts:line when prompted.
See the .tfvars reference for every variable.
proxaform/
├── setup.sh # One-time environment bootstrap
├── deploy.sh # Provision a container + run a playbook against it
├── destroy.sh # Tear down a previously deployed container
├── docs/ # Step-by-step guides
├── terraform/ # Terraform configuration + terraform.tfvars.example
├── playbooks/ # Ansible playbooks, grouped by category
├── roles/ # Ansible roles used by the playbooks
├── inventory/ # Generated Ansible inventory (hosts.yml)
├── secrets/ # SSH public key, .tfvars and .tfstate files (gitignored)
└── logs/ # Timestamped run logs (gitignored)
secrets/andlogs/are excluded from version control via.gitignore, along with*.tfvars,*.tfstate*,hosts.ymland other sensitive Terraform artifacts.- Passwords are not written into
.tfvarsfiles created by the wizard; Terraform prompts for them each timedeploy.shordestroy.shruns. If you add them to a hand-written.tfvarsfile, they are stored in plain text. - Terraform variables carrying credentials are marked
sensitive = true, which redacts them fromplan/applyconsole output. - Terraform state stores applied values (including passwords) in plaintext. The state files in
secrets/should be treated as secrets — if you sync, back up, or share them, consider encryption or a remote encrypted backend. insecure = trueis set on the Proxmox provider for convenience with self-signed certificates — replace this with proper TLS verification in production environments.
Issues and pull requests are welcome on GitHub.
MIT License. See LICENSE for details.