Commit the accumulated infrastructure work that was living only in the working tree: monitoring stack, emergency access/bot, gyro allocator, grimmory, adguard, backup audit and the OpenCode agent definitions. Also ignore Python bytecode, local archives and Nix/direnv artifacts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
10 KiB
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
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/<name>.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-vpspve_nodes— cloud-pc, mini-pclxc_infra— pbs, ovpn-mini, vaultwarden, gitea, memoir-bot, mihomovpn_openvpn— ru-vps, ovpn-minishell_hosts— ru-vps, cloud-pc, mini-pcservers— 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
# 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:
# From .env file
PROXMOX_HOST=<host>
PROXMOX_USER=<user@realm>
PROXMOX_TOKEN_ID=<token_id>
PROXMOX_TOKEN_SECRET=<secret>
PROXMOX_VALIDATE_CERTS=false
Usage:
. ./.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:
ansible-playbook playbooks/bootstrap-pve-api-token.yml -K
Secrets Policy
- Never commit real secrets to git.
- Use
.envfiles (in.gitignore), Ansible vault, or runtime prompt. - Store
.env.exampletemplates in repo. - Keep: passwords, tokens, private keys, PBS secrets, TLS keys outside repo.
Workflow
- Read Obsidian — understand context, constraints, prior decisions.
- Make change — edit/add role/playbook in
ansible/. - Test safe — run smallest applicable check/playbook.
- 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
Для повторяющихся задач — скрипты, а не объяснения:
# Вместо: "проверь статус всех LXC"
ansible/scripts/check-lxc-status.sh
# Вместо: "верифицируй PBS backup jobs"
ansible/scripts/check-pbs-backups.sh
Паттерн: написать один раз → переиспользовать. LLM только пишет или вызывает.
Focused Context — читай только нужное
Вместо чтения всего файла — только релевантные части:
# Вместо всего inventory.yml
Read(file_path, offset=1, limit=50) # только hosts vars
# Или grep для конкретного хоста
grep("mini-pc", "inventory/hosts.yml")
Tool Limits — ограничивай вывод команд
# Вместо: 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:
# Плохо
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:
{
"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
Описывай желаемое состояние, а не шаги:
# Плохо: каждый раз перечислять шаги
"Создай LXC, установи Docker, добавь пользователя..."
# Хорошо: декларативно
lxc_container:
name: "vaultwarden"
features: ["docker", "autostart"]
user: "ansible"
Ansible/Terraform сами разберут шаги.