Capture current Ansible control plane state

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
This commit is contained in:
Dmitry
2026-08-26 21:39:28 +03:00
co-authored by Claude Opus 5
parent 4bafa7d09e
commit c676be81ec
126 changed files with 10583 additions and 44 deletions
+295
View File
@@ -0,0 +1,295 @@
# 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/<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-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=<host>
PROXMOX_USER=<user@realm>
PROXMOX_TOKEN_ID=<token_id>
PROXMOX_TOKEN_SECRET=<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 сами разберут шаги.