ilia 69a39e5e5b Add POTE app project support and improve IP conflict detection (#3)
## Summary

This PR adds comprehensive support for deploying the **POTE** application project via Ansible, along with improvements to IP conflict detection and a new app stack provisioning system for Proxmox-managed LXC containers.

## Key Features

### 🆕 New Roles
- **`roles/pote`**: Python/venv deployment role for POTE (PostgreSQL, cron jobs, Alembic migrations)
- **`roles/app_setup`**: Generic app deployment role (Node.js/systemd)
- **`roles/base_os`**: Base OS hardening role

### 🛡️ Safety Improvements
- IP uniqueness validation within projects
- Proxmox-side IP conflict detection
- Enhanced error messages for IP conflicts

### 📦 New Playbooks
- `playbooks/app/site.yml`: End-to-end app stack deployment
- `playbooks/app/provision_vms.yml`: Proxmox guest provisioning
- `playbooks/app/configure_app.yml`: OS + application configuration

## Security
-  All secrets stored in encrypted vault.yml
-  Deploy keys excluded via .gitignore
-  No plaintext secrets committed

## Testing
-  POTE successfully deployed to dev/qa/prod environments
-  All components validated (Git, PostgreSQL, cron, migrations)

Co-authored-by: ilia <ilia@levkin.ca>
Reviewed-on: #3
2026-01-01 11:19:54 -05:00

82 lines
2.4 KiB
Markdown

# Role: `proxmox_vm`
Provision Proxmox guests via API. This role supports **both**:
- **LXC containers** (`proxmox_guest_type: lxc`) via `community.proxmox.proxmox`
- **KVM VMs** (`proxmox_guest_type: kvm`) via `community.general.proxmox_kvm`
The entry point is `roles/proxmox_vm/tasks/main.yml`, which dispatches to `tasks/lxc.yml` or `tasks/kvm.yml`.
## Requirements
- Ansible (project tested with modern Ansible; older 2.9-era setups may need adjustments)
- Proxmox VE API access
- Collections:
- `community.proxmox`
- `community.general` (for `proxmox_kvm`)
- Python lib on the control machine:
- `proxmoxer` (installed by `make bootstrap` / `requirements.txt`)
## Authentication (vault-backed)
Store secrets in `inventories/production/group_vars/all/vault.yml`:
- `vault_proxmox_host`
- `vault_proxmox_user`
- `vault_proxmox_password` (or token auth)
- `vault_proxmox_token_id` (optional)
- `vault_proxmox_token` (optional)
- `vault_ssh_public_key` (used for bootstrap access where applicable)
## Key variables
Common:
- `proxmox_guest_type`: `lxc` or `kvm`
- `proxmox_host`, `proxmox_user`, `proxmox_node`
- `proxmox_api_port` (default `8006`)
- `proxmox_validate_certs` (default `false`)
LXC (`tasks/lxc.yml`):
- `lxc_vmid`, `lxc_hostname`
- `lxc_ostemplate` (e.g. `local:vztmpl/debian-12-standard_*.tar.zst`)
- `lxc_storage` (default `local-lvm`)
- `lxc_network_bridge` (default `vmbr0`)
- `lxc_ip` (CIDR), `lxc_gateway`
- `lxc_cores`, `lxc_memory_mb`, `lxc_swap_mb`, `lxc_rootfs_size_gb`
KVM (`tasks/kvm.yml`):
- `vm_id`, `vm_name`
- `vm_cores`, `vm_memory`, `vm_disk_size`
- `vm_storage`, `vm_network_bridge`
- cloud-init parameters used by the existing KVM provisioning flow
## Safety guardrails
LXC provisioning includes a VMID collision guardrail:
- If the target VMID already exists but the guest name does not match the expected name, provisioning fails.
- Override only if you really mean it: `-e allow_vmid_collision=true`
## Example usage
Provisioning is typically orchestrated by `playbooks/app/provision_vms.yml`, but you can call the role directly:
```yaml
- name: Provision one LXC
hosts: localhost
connection: local
gather_facts: false
tasks:
- name: Create/update container
ansible.builtin.include_role:
name: proxmox_vm
vars:
proxmox_guest_type: lxc
lxc_vmid: 9301
lxc_hostname: projectA-dev
lxc_ip: "10.0.10.101/24"
lxc_gateway: "10.0.10.1"
```