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:
@@ -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 сами разберут шаги.
|
||||
Reference in New Issue
Block a user