# AGENTS.md ## Project Summary **HomeLab infras** is a GitOps-like repository for managing home infrastructure through Ansible. - Management: `ansible/` (playbooks, roles, inventory) - Documentation: Obsidian vault `/home/ada/Documents/Vaults/SecondBrain/02 Projects/HomeLab/` - Active infrastructure: Proxmox VE cluster (`cloud-pc`, `mini-pc`), PBS, OpenVPN, ZeroTier - Archive: `archive/2026-07-proxmox-migration/` (historical NixOS/Docker configs, reference only) ## Design Goal **Ansible-first infrastructure**: HomeLab configuration is managed through Ansible inventory, roles and playbooks. Direct server changes are allowed only for break-glass recovery or read-only diagnostics; afterwards the intended state must be captured in Ansible. ## Obsidian Integration Project documentation lives in `/home/ada/Documents/Vaults/SecondBrain/02 Projects/HomeLab/`. Use it as wiki: - **Read** before making infra changes — context, decisions, constraints. - **Update** after making changes — document non-obvious decisions, new patterns, lessons learned. - Key files: `HomeLab.md`, `Notes/Текущее состояние HomeLab после миграции на Proxmox.md`, `Log.md`. When introducing infra changes, update the relevant Obsidian note to keep documentation in sync. ## Operating Model - User: passwords, SSH access, base network reachability. - Agent: infrastructure changes via `ansible/` files. - Prefer adding/updating a role or playbook over ad-hoc commands. - For every new VM, LXC container, or managed host, provision the user's SSH public key by default unless explicitly told otherwise. - Run smallest safe Ansible check before broader changes. - Do not commit secrets (`.env`, tokens, keys, real passwords). ## Quick Start ```bash cd ansible # Setup (once) python3 -m venv .venv . .venv/bin/activate pip install -r requirements.txt ansible-galaxy collection install -r requirements.yml -p collections # Basic connectivity check ansible-playbook playbooks/check.yml # Privileged tasks ansible-playbook playbooks/.yml -K # Proxmox API tasks (from .env) cp .env.example .env # Edit .env with real values . ./.env ansible-playbook playbooks/pve-*.yml ``` ## Active Infrastructure ### Nodes | Name | Role | LAN IP | Notes | |---|---|---:|---| | `ru-vps` | Public VPS, JumpHost, qdevice, OpenVPN server | `157.22.231.198:3422` | OpenVPN `10.78.0.1` | | `cloud-pc` | Proxmox VE node, PBS LXC, storage | `192.168.1.5` | Main node | | `mini-pc` | Proxmox VE node | `192.168.1.10` | Secondary node | | `pbs` | Proxmox Backup Server LXC | `192.168.1.20` | On cloud-pc | | `ovpn-mini` | OpenVPN gateway LXC | `192.168.1.23` | OpenVPN `10.78.0.2` | | `vaultwarden` | Vaultwarden LXC | `192.168.1.24` | | | `gitea` | Gitea LXC | `192.168.1.25` | | | `memoir-bot` | Telegram memoir bot LXC | `192.168.1.26` | | | `mihomo` | Local proxy/UI LXC | `192.168.1.27` | UI `:8080`, API `:9090` | ### Inventory Groups - `homelab` — ru-vps - `pve_nodes` — cloud-pc, mini-pc - `lxc_infra` — pbs, ovpn-mini, vaultwarden, gitea, memoir-bot, mihomo - `vpn_openvpn` — ru-vps, ovpn-mini - `shell_hosts` — ru-vps, cloud-pc, mini-pc - `servers` — all managed hosts ### Transport - **OpenVPN**: ru-vps (10.78.0.1) ↔ ovpn-mini (10.78.0.2), port 8443/tcp - **JumpHost**: SSH to cloud-pc/mini-pc via ProxyJump ru-vps ## Directory Structure ``` ansible/ ├── ansible.cfg # Ansible configuration ├── inventory/ │ └── hosts.yml # Canonical host list and variables ├── playbooks/ # Entry points │ ├── check.yml # Connectivity check │ ├── pve-*.yml # Proxmox API tasks (need .env) │ ├── openvpn-*.yml # OpenVPN transport setup │ └── *.yml # Other tasks ├── roles/ # Reusable units │ ├── backup_audit/ # PBS/restic backup audit │ ├── bash_config/ # Unified bash config │ ├── base/ # Base packages/config │ ├── docker/ # Docker setup │ ├── openvpn_gateway/ # OpenVPN client gateway │ ├── pve_lxc/ # Proxmox LXC creation │ └── ufw/ # Firewall rules ├── tasks/ # Task snippets └── requirements.txt/yml # Dependencies archive/2026-07-proxmox-migration/ # Historical configs (reference only) ``` ## Common Playbooks ```bash # Check connectivity and expected IPs ansible-playbook playbooks/check.yml # Bootstrap Proxmox API token from mini-pc (requires sudo) ansible-playbook playbooks/bootstrap-pve-api-token.yml -K # OpenVPN transport setup (requires privilege) ansible-playbook playbooks/openvpn-vps-mini.yml -K ansible-playbook playbooks/openvpn-check.yml # Unified bash config for shell hosts ansible-playbook playbooks/bash-config.yml # Install user's SSH public key on all managed hosts ansible-playbook playbooks/user-ssh-key.yml # Backup audit (PBS + restic offsite) ansible-playbook playbooks/backup-audit.yml ``` ## Proxmox API Tasks Proxmox playbooks require environment variables: ```bash # From .env file PROXMOX_HOST= PROXMOX_USER= PROXMOX_TOKEN_ID= PROXMOX_TOKEN_SECRET= PROXMOX_VALIDATE_CERTS=false ``` Usage: ```bash . ./.env ansible-playbook playbooks/pve-ovpn-mini.yml ansible-playbook playbooks/pve-vaultwarden.yml ansible-playbook playbooks/pve-gitea.yml ``` Or bootstrap token directly from node: ```bash ansible-playbook playbooks/bootstrap-pve-api-token.yml -K ``` ## Secrets Policy - Never commit real secrets to git. - Use `.env` files (in `.gitignore`), Ansible vault, or runtime prompt. - Store `.env.example` templates in repo. - Keep: passwords, tokens, private keys, PBS secrets, TLS keys outside repo. ## Workflow 1. **Read Obsidian** — understand context, constraints, prior decisions. 2. **Make change** — edit/add role/playbook in `ansible/`. 3. **Test safe** — run smallest applicable check/playbook. 4. **Update Obsidian** — document non-obvious decisions and changes. ## Archive Policy - `archive/2026-07-proxmox-migration/` contains historical NixOS, Docker Compose, GitOps configs. - Use archived files only as reference when porting behavior to Ansible. - Do not edit archived files for active infrastructure. - Restore services via new Ansible roles/playbooks, not by moving old files back. ## Token Economy Принципы минимизации токенов при управлении инфраструктурой. ### Delegate Heavy Reading Когда нужно анализировать большие логи или выводы — делегируй субагенту: ``` agent("Read this log and summarize key errors") ``` **Субагент использует для:** - Анализа логов (journalctl, docker logs, PBS logs) - Summarization больших файлов - Поиска паттернов в выводах - Диагностики статусов **Основной агент для:** - Принятия решений на основе конспекта - Сложных рассуждений над findings - Изменения кода и архитектуры ### Prefer Scripts Over LLM Для повторяющихся задач — скрипты, а не объяснения: ```bash # Вместо: "проверь статус всех LXC" ansible/scripts/check-lxc-status.sh # Вместо: "верифицируй PBS backup jobs" ansible/scripts/check-pbs-backups.sh ``` Паттерн: написать один раз → переиспользовать. LLM только пишет или вызывает. ### Focused Context — читай только нужное Вместо чтения всего файла — только релевантные части: ```python # Вместо всего inventory.yml Read(file_path, offset=1, limit=50) # только hosts vars # Или grep для конкретного хоста grep("mini-pc", "inventory/hosts.yml") ``` ### Tool Limits — ограничивай вывод команд ```bash # Вместо: journalctl -u openvpn (тысячи строк) journalctl -u openvpn --since "1 hour ago" -n 100 # Вместо: docker logs (весь лог) docker logs --tail 50 gitea ``` Всегда ограничивай вывод: `--tail`, `--since`, `-n`, `head`. ### Batch Operations — группируй задачи Вместо нескольких запусков — один с несколькими role: ```python # Плохо ansible-playbook playbooks/bash-config.yml ansible-playbook playbooks/docker.yml ansible-playbook playbooks/ufw.yml # Хорошо — один плейбук ansible-playbook playbooks/base-setup.yml # включает bash, docker, ufw ``` ### State Caching — не перечитывай статичное Структура инфры меняется редко. Не перечитывай `hosts.yml`, если структура не изменилась. Кэшируй в memory стабильные данные: network topology, storage layout. ### Structured Output — избегай повторного парсинга Когда субагент анализирует логи — проси сразу JSON с findings: ```json { "summary": "OpenVPN handshake fails due to certificate expired", "findings": ["cert expired 2026-07-01", "client retries every 5s"], "relevant_lines": ["Jul 08 10:23:01 TLS auth error"] } ``` Работа со структурированным результатом вместо повторного чтения логов. ### Declarative Over Imperative Описывай желаемое состояние, а не шаги: ```yaml # Плохо: каждый раз перечислять шаги "Создай LXC, установи Docker, добавь пользователя..." # Хорошо: декларативно lxc_container: name: "vaultwarden" features: ["docker", "autostart"] user: "ansible" ``` Ansible/Terraform сами разберут шаги.