## 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
117 lines
4.1 KiB
YAML
117 lines
4.1 KiB
YAML
---
|
||
# Role: pote
|
||
# Purpose: Deploy POTE (Python/venv + cron) from a Git repo via SSH.
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Git / source
|
||
# -----------------------------------------------------------------------------
|
||
pote_git_repo: ""
|
||
pote_git_branch: "main"
|
||
|
||
# SSH private key used to clone/pull (vault-backed). Keep this secret.
|
||
# Prefer setting `vault_pote_git_ssh_key` in your vault; `vault_git_ssh_key` is supported for compatibility.
|
||
pote_git_ssh_key: "{{ vault_pote_git_ssh_key | default(vault_git_ssh_key | default('')) }}"
|
||
|
||
# Host/IP for known_hosts (so first clone is non-interactive).
|
||
pote_git_host: "10.0.30.169"
|
||
pote_git_port: 22
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# User / paths
|
||
# -----------------------------------------------------------------------------
|
||
pote_user: "poteapp"
|
||
pote_group: "{{ pote_user }}"
|
||
pote_app_dir: "/home/{{ pote_user }}/pote"
|
||
pote_venv_dir: "{{ pote_app_dir }}/venv"
|
||
pote_python_bin: "python3.11"
|
||
|
||
# Environment file
|
||
pote_env_file: "{{ pote_app_dir }}/.env"
|
||
pote_env_file_mode: "0600"
|
||
|
||
# Logs
|
||
pote_logs_dir: "/home/{{ pote_user }}/logs"
|
||
pote_log_level: "INFO"
|
||
pote_log_file: "{{ pote_logs_dir }}/pote.log"
|
||
|
||
# Monitoring / alerting (optional)
|
||
pote_market_tickers: ""
|
||
pote_alert_min_severity: ""
|
||
|
||
# Optional API keys
|
||
pote_quiverquant_api_key: ""
|
||
pote_fmp_api_key: ""
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# System deps
|
||
# -----------------------------------------------------------------------------
|
||
pote_system_packages:
|
||
- git
|
||
- ca-certificates
|
||
- python3.11
|
||
- python3.11-venv
|
||
- python3.11-dev
|
||
- python3-pip
|
||
- build-essential
|
||
- postgresql
|
||
- postgresql-contrib
|
||
- postgresql-client
|
||
- libpq-dev
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Database
|
||
# -----------------------------------------------------------------------------
|
||
pote_db_host: "localhost"
|
||
pote_db_port: 5432
|
||
pote_db_name: "potedb"
|
||
pote_db_user: "poteuser"
|
||
# Prefer env-specific vault vars; fall back to a generic one if present.
|
||
pote_db_password: >-
|
||
{{
|
||
vault_pote_db_password
|
||
| default(
|
||
(vault_pote_db_password_dev | default(vault_db_password_dev | default(''), true)) if pote_env == 'dev'
|
||
else (vault_pote_db_password_qa | default(vault_db_password_qa | default(''), true)) if pote_env == 'qa'
|
||
else (vault_pote_db_password_prod | default(vault_db_password_prod | default(''), true)) if pote_env == 'prod'
|
||
else '',
|
||
true
|
||
)
|
||
}}
|
||
|
||
# Convenience computed URL (commonly used by Python apps)
|
||
pote_database_url: "postgresql://{{ pote_db_user }}:{{ pote_db_password }}@{{ pote_db_host }}:{{ pote_db_port }}/{{ pote_db_name }}"
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# SMTP / email
|
||
# -----------------------------------------------------------------------------
|
||
pote_smtp_host: "mail.levkin.ca"
|
||
pote_smtp_port: 587
|
||
pote_smtp_user: ""
|
||
pote_smtp_password: "{{ vault_pote_smtp_password | default(vault_smtp_password | default('')) }}"
|
||
pote_from_email: ""
|
||
pote_report_recipients: ""
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Automation / cron
|
||
# -----------------------------------------------------------------------------
|
||
pote_enable_cron: true
|
||
|
||
# "minute hour" (e.g. "0 6")
|
||
pote_daily_report_time: "0 6"
|
||
# "minute hour dow" (e.g. "0 8 0" => Sunday 08:00)
|
||
pote_weekly_report_time: "0 8 0"
|
||
# "minute hour" for */6 style (e.g. "0 */6")
|
||
pote_health_check_time: "0 */6"
|
||
|
||
pote_daily_report_enabled: true
|
||
pote_weekly_report_enabled: true
|
||
pote_health_check_enabled: true
|
||
|
||
# Commands (adjust to your repo’s actual scripts)
|
||
pote_daily_job: "{{ pote_app_dir }}/scripts/automated_daily_run.sh >> {{ pote_logs_dir }}/daily_run.log 2>&1"
|
||
pote_weekly_job: "{{ pote_app_dir }}/scripts/automated_weekly_run.sh >> {{ pote_logs_dir }}/weekly_run.log 2>&1"
|
||
pote_health_check_job: "{{ pote_venv_dir }}/bin/python {{ pote_app_dir }}/scripts/health_check.py >> {{ pote_logs_dir }}/health_check.log 2>&1"
|
||
|
||
# Environment name for templating/logging (dev|qa|prod)
|
||
pote_env: "{{ app_env | default('prod') }}"
|