--- # Common variables for all hosts timezone: America/Toronto locale: en_US.UTF-8 ansible_python_interpreter: /usr/bin/python3 # Debug settings ansible_debug_output: false # Security settings fail2ban_bantime: 3600 fail2ban_findtime: 600 fail2ban_maxretry: 3 # Maintenance settings maintenance_default_serial: "100%" # Default serial execution for maintenance maintenance_reboot_timeout: 300 # Reboot timeout in seconds maintenance_pre_reboot_delay: 5 # Delay before reboot in seconds # Global variables for all hosts # Tailscale configuration # Store your actual auth key in vault_tailscale_auth_key using ansible-vault # Example: ansible-vault create group_vars/all/vault.yml # vault_tailscale_auth_key: "tskey-auth-your-actual-key-here" # Default Tailscale settings - these tell the playbook to use your vault key tailscale_auth_key: "{{ vault_tailscale_auth_key | default('') }}" tailscale_accept_routes: true tailscale_accept_dns: true tailscale_ssh: false tailscale_hostname: "{{ inventory_hostname }}" # ----------------------------------------------------------------------------- # Proxmox + modular app projects (LXC-first) # # This repo can manage many independent apps ("projects"). Each project defines # its own dev/qa/prod guests (IPs/VMIDs/branches) under `app_projects`. # # Usage examples: # - Run one project: ansible-playbook -i inventories/production playbooks/app/site.yml -e app_project=projectA # - Run all projects: ansible-playbook -i inventories/production playbooks/app/site.yml # ----------------------------------------------------------------------------- # Proxmox API connection (keep secrets in vault) proxmox_host: "{{ vault_proxmox_host }}" proxmox_user: "{{ vault_proxmox_user }}" proxmox_node: "{{ vault_proxmox_node | default('pve') }}" proxmox_api_port: "{{ vault_proxmox_api_port | default(8006) }}" # Proxmox commonly uses a self-signed cert; keep validation off by default. proxmox_validate_certs: false # Prefer API token auth (store in vault): # - proxmox_token_id: "ansible@pve!token-name" # - vault_proxmox_token: "secret" proxmox_token_id: "{{ vault_proxmox_token_id | default('') }}" # Default guest type for new projects. (Later you can set to `kvm` per project/env.) proxmox_guest_type: lxc # Proxmox LXC defaults (override per project/env as needed) lxc_ostemplate: "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst" lxc_storage: "local-lvm" lxc_network_bridge: "vmbr0" lxc_unprivileged: true lxc_features_list: - "keyctl=1" - "nesting=1" lxc_start_after_create: true lxc_nameserver: "1.1.1.1 8.8.8.8" # Base OS / access defaults appuser_name: appuser appuser_shell: /bin/bash appuser_groups: - sudo # Store your workstation public key in vault_ssh_public_key appuser_ssh_public_key: "{{ vault_ssh_public_key }}" # App defaults (override per project) app_backend_port: 3001 app_frontend_port: 3000 # Default Node workflow commands (override per project if your app differs) app_backend_install_cmd: "npm ci" app_backend_migrate_cmd: "npm run migrate" app_backend_start_cmd: "npm start" app_frontend_install_cmd: "npm ci" app_frontend_build_cmd: "npm run build" app_frontend_start_cmd: "npm start" # Projects definition: add as many projects as you want here. # Each project has envs (dev/qa/prod) defining name/vmid/ip/gateway/branch and # optional env_vars (dummy placeholders by default). # # ----------------------------------------------------------------------------- # Proxmox VMID/CTID ranges (DEDICATED; avoid collisions) # # Proxmox IDs are global. Never reuse IDs across unrelated guests. # Suggested reservation table (edit to your preference): # - 9000-9099: pote # - 9100-9199: punimTagFE # - 9200-9299: punimTagBE # - 9300-9399: projectA (example) # ----------------------------------------------------------------------------- app_projects: projectA: description: "Example full-stack app (edit repo_url, IPs, secrets)." repo_url: "git@github.com:example/projectA.git" components: backend: true frontend: true # Repo is assumed to contain `backend/` and `frontend/` directories. repo_dest: "/srv/app" # Optional overrides for this project backend_port: "{{ app_backend_port }}" frontend_port: "{{ app_frontend_port }}" guest_defaults: guest_type: "{{ proxmox_guest_type }}" cores: 2 memory_mb: 2048 swap_mb: 512 rootfs_size_gb: 16 deploy: backend_install_cmd: "{{ app_backend_install_cmd }}" backend_migrate_cmd: "{{ app_backend_migrate_cmd }}" backend_start_cmd: "{{ app_backend_start_cmd }}" frontend_install_cmd: "{{ app_frontend_install_cmd }}" frontend_build_cmd: "{{ app_frontend_build_cmd }}" frontend_start_cmd: "{{ app_frontend_start_cmd }}" envs: dev: name: "projectA-dev" vmid: 9301 ip: "10.0.10.101/24" gateway: "10.0.10.1" branch: "dev" env_vars: APP_ENV: "dev" BACKEND_BASE_URL: "http://10.0.10.101:{{ app_backend_port }}" FRONTEND_BASE_URL: "http://10.0.10.101:{{ app_frontend_port }}" SECRET_PLACEHOLDER: "change-me" qa: name: "projectA-qa" vmid: 9302 ip: "10.0.10.102/24" gateway: "10.0.10.1" branch: "qa" env_vars: APP_ENV: "qa" BACKEND_BASE_URL: "http://10.0.10.102:{{ app_backend_port }}" FRONTEND_BASE_URL: "http://10.0.10.102:{{ app_frontend_port }}" SECRET_PLACEHOLDER: "change-me" prod: name: "projectA-prod" vmid: 9303 ip: "10.0.10.103/24" gateway: "10.0.10.1" branch: "main" pote: description: "POTE (python/venv + cron) project (edit repo_url, IPs, secrets)." repo_url: "gitea@10.0.30.169:ilia/POTE.git" # POTE deploys as a user-owned python app (not /srv/app) repo_dest: "/home/poteapp/pote" os_user: "poteapp" components: backend: false frontend: false guest_defaults: guest_type: "{{ proxmox_guest_type }}" cores: 2 memory_mb: 2048 swap_mb: 512 rootfs_size_gb: 16 # POTE-specific optional defaults (override per env if needed) pote_db_host: "localhost" pote_db_user: "poteuser" pote_db_name: "potedb" pote_smtp_host: "mail.levkin.ca" pote_smtp_port: 587 envs: dev: name: "pote-dev" vmid: 9001 ip: "10.0.10.114/24" gateway: "10.0.10.1" branch: "dev" qa: name: "pote-qa" vmid: 9002 ip: "10.0.10.112/24" gateway: "10.0.10.1" branch: "qa" prod: name: "pote-prod" vmid: 9003 ip: "10.0.10.113/24" gateway: "10.0.10.1" branch: "main" punimTagFE: description: "punimTag frontend-only project (edit repo_url, IPs, secrets)." repo_url: "git@github.com:example/punimTagFE.git" repo_dest: "/srv/app" components: backend: false frontend: true guest_defaults: guest_type: "{{ proxmox_guest_type }}" cores: 2 memory_mb: 2048 swap_mb: 512 rootfs_size_gb: 16 deploy: frontend_install_cmd: "{{ app_frontend_install_cmd }}" frontend_build_cmd: "{{ app_frontend_build_cmd }}" frontend_start_cmd: "{{ app_frontend_start_cmd }}" envs: dev: name: "punimTagFE-dev" vmid: 9101 ip: "10.0.10.121/24" gateway: "10.0.10.1" branch: "dev" env_vars: APP_ENV: "dev" SECRET_PLACEHOLDER: "change-me" qa: name: "punimTagFE-qa" vmid: 9102 ip: "10.0.10.122/24" gateway: "10.0.10.1" branch: "qa" env_vars: APP_ENV: "qa" SECRET_PLACEHOLDER: "change-me" prod: name: "punimTagFE-prod" vmid: 9103 ip: "10.0.10.123/24" gateway: "10.0.10.1" branch: "main" env_vars: APP_ENV: "prod" SECRET_PLACEHOLDER: "change-me" punimTagBE: description: "punimTag backend-only project (edit repo_url, IPs, secrets)." repo_url: "git@github.com:example/punimTagBE.git" repo_dest: "/srv/app" components: backend: true frontend: false guest_defaults: guest_type: "{{ proxmox_guest_type }}" cores: 2 memory_mb: 2048 swap_mb: 512 rootfs_size_gb: 16 deploy: backend_install_cmd: "{{ app_backend_install_cmd }}" backend_migrate_cmd: "{{ app_backend_migrate_cmd }}" backend_start_cmd: "{{ app_backend_start_cmd }}" envs: dev: name: "punimTagBE-dev" vmid: 9201 ip: "10.0.10.131/24" gateway: "10.0.10.1" branch: "dev" env_vars: APP_ENV: "dev" SECRET_PLACEHOLDER: "change-me" qa: name: "punimTagBE-qa" vmid: 9202 ip: "10.0.10.132/24" gateway: "10.0.10.1" branch: "qa" env_vars: APP_ENV: "qa" SECRET_PLACEHOLDER: "change-me" prod: name: "punimTagBE-prod" vmid: 9203 ip: "10.0.10.133/24" gateway: "10.0.10.1" branch: "main" env_vars: APP_ENV: "prod" SECRET_PLACEHOLDER: "change-me" mirrormatch: description: "Mirrormatch Prisma/Node backend (dev/qa/prod)." repo_url: "gitea@10.0.30.169:ilia/mirror_match.git" repo_dest: "/srv/app" backend_dir: "/srv/app" components: backend: true frontend: false # Next.js app listens on 3000 by default backend_port: 3000 guest_defaults: guest_type: "{{ proxmox_guest_type }}" cores: 2 memory_mb: 2048 swap_mb: 512 rootfs_size_gb: 16 deploy: backend_install_cmd: "npm ci" backend_build_cmd: "npm run build" backend_migrate_cmd: "npm run db:migrate" backend_start_cmd: "npm run start" envs: dev: name: "mirrormatch-dev" vmid: 9401 ip: "10.0.10.141/24" gateway: "10.0.10.1" branch: "dev" backend_migrate_cmd: "npm run db:push" backend_seed_cmd: "npm run db:seed" env_vars: APP_ENV: "dev" NODE_ENV: "production" PORT: "3000" DATABASE_URL: "{{ vault_mirrormatch_database_url_dev }}" NEXTAUTH_URL: "https://mirrormatchdev.levkin.ca" NEXTAUTH_SECRET: "{{ vault_mirrormatch_nextauth_secret_dev }}" AUTH_TRUST_HOST: "true" # Dev/QA often use Ethereal/console email; leave SMTP unset or fill if needed # SMTP_HOST: "" # SMTP_PORT: "" # SMTP_USER: "" # SMTP_PASSWORD: "" # SMTP_FROM: "" # Optional: provide if your Prisma workflow needs a shadow DB # SHADOW_DATABASE_URL: "{{ vault_mirrormatch_shadow_database_url_dev }}" qa: name: "mirrormatch-qa" vmid: 9402 ip: "10.0.10.144/24" gateway: "10.0.10.1" branch: "qa" backend_migrate_cmd: "npm run db:push" backend_seed_cmd: "npm run db:seed" env_vars: APP_ENV: "qa" NODE_ENV: "production" PORT: "3000" DATABASE_URL: "{{ vault_mirrormatch_database_url_qa }}" NEXTAUTH_URL: "https://mirrormatchqa.levkin.ca" NEXTAUTH_SECRET: "{{ vault_mirrormatch_nextauth_secret_qa }}" AUTH_TRUST_HOST: "true" # SMTP_HOST: "" # SMTP_PORT: "" # SMTP_USER: "" # SMTP_PASSWORD: "" # SMTP_FROM: "" # SHADOW_DATABASE_URL: "{{ vault_mirrormatch_shadow_database_url_qa }}" prod: name: "mirrormatch-prod" vmid: 9403 ip: "10.0.10.145/24" gateway: "10.0.10.1" branch: "main" backend_migrate_cmd: "npx prisma migrate deploy" env_vars: APP_ENV: "prod" NODE_ENV: "production" PORT: "3000" DATABASE_URL: "{{ vault_mirrormatch_database_url_prod }}" NEXTAUTH_URL: "https://mirrormatch.example.com" NEXTAUTH_SECRET: "{{ vault_mirrormatch_nextauth_secret_prod }}" AUTH_TRUST_HOST: "true" SMTP_HOST: "{{ vault_mirrormatch_smtp_host | default('') }}" SMTP_PORT: "{{ vault_mirrormatch_smtp_port | default('587') }}" SMTP_USER: "{{ vault_mirrormatch_smtp_user | default('') }}" SMTP_PASSWORD: "{{ vault_mirrormatch_smtp_password | default('') }}" SMTP_FROM: "{{ vault_mirrormatch_smtp_from | default('') }}"