Files
infra/AGENTS.md
T
DmitryandClaude Opus 5 c676be81ec 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
2026-08-26 21:39:28 +03:00

10 KiB
Raw Blame History

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-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

# 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 .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

Для повторяющихся задач — скрипты, а не объяснения:

# Вместо: "проверь статус всех 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 сами разберут шаги.