Sync documentation with the actual infrastructure
lint / yamllint + ansible-lint + syntax-check (push) Canceled after 0s

The host table listed 9 hosts against 16 in the inventory, the role tree
did not match roles/, and the documented setup path used a venv that no
longer works.

Describe the current entry points instead: nix develop, make, and the
ssh_config include that makes `ssh gitea` work by hand. Point at
`make docs` as the way to regenerate the host table rather than editing
it, since that is what drifted.

Also record what is deliberately incomplete: lxc_docker_host and
compose_service exist but are not wired into any playbook, and LXC
creation is still split between direct pct create over SSH and the
pve_lxc API role.

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 22:10:38 +03:00
co-authored by Claude Opus 5
parent ef234b17f5
commit 7700ed5a88
2 changed files with 189 additions and 97 deletions
+144 -78
View File
@@ -34,113 +34,178 @@ When introducing infra changes, update the relevant Obsidian note to keep docume
## Quick Start
Окружение собрано в Nix — venv и системные пакеты не нужны.
```bash
cd ansible
nix develop # или один раз: direnv allow
# 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
# Один раз на клон: galaxy-коллекции
ansible-galaxy collection install -r ansible/requirements.yml -p ansible/collections
```
Дальше всё управление идёт через `make` из каталога `ansible/`:
```bash
cd ansible
make help # список всех целей — начинать отсюда
make check # связность и ожидаемые IP
make status # сводное состояние всей инфраструктуры (read-only)
make lint # ansible-lint + yamllint
make docs # актуальная таблица хостов из inventory
make deploy-gitea # playbooks/pve-gitea.yml, .env подхватывается сам
make dry-gitea # то же в режиме --check --diff
make update-gitea # бэкап -> обновление -> health-check
```
`make` без аргументов печатает `help`. Опасные цели (`mihomo-harden`, `monitoring`,
`update-all`) требуют явного `CONFIRM=1`. Дополнительные флаги — через `EXTRA`:
```bash
make status EXTRA="--limit '!gyro'"
```
`gyro` использует шифрованный `host_vars/gyro/vault.yml`, поэтому для него нужен
`--ask-vault-pass` (цель `make gyro` добавляет флаг сама).
### SSH руками
Транспорт описан в `ansible/ssh_config` — один источник правды и для Ansible,
и для терминала. Чтобы заработал `ssh gitea`, добавь в `~/.ssh/config`:
```
Include /home/ada/Documents/Projects/HomeLab/infras/ansible/ssh_config
```
SSH берёт первое совпадение: Include в начале файла — побеждают настройки репозитория,
в конце — личные записи из `~/.ssh/config.d/`. На Ansible порядок не влияет, он ходит
с явным `-F`.
## Active Infrastructure
Каноничный источник — `ansible/inventory/hosts.yml` и реестр сервисов
`ansible/inventory/group_vars/all/services.yml`. Актуальную таблицу всегда можно
получить командой `make docs`, поэтому здесь — только опорная картина.
### 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 |
| `ru-vps` | Public VPS, JumpHost, qdevice, OpenVPN server, Caddy | `157.22.231.198:3422` | OpenVPN `10.78.0.1` |
| `cloud-pc` | Proxmox VE node, 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` |
| `pbs` | Proxmox Backup Server LXC (CT 120) | `192.168.1.20` | Прямой доступ, без ProxyJump |
| `ovpn-mini` | OpenVPN gateway LXC (CT 132) | `192.168.1.23` | OpenVPN `10.78.0.2`, без ProxyJump |
| `vaultwarden` | Vaultwarden LXC (CT 140) | `192.168.1.24` | `pass.ada-dev.ru` |
| `gitea` | Gitea LXC (CT 141) | `192.168.1.25` | `git.ada-dev.ru`, SSH `:2222` |
| `memoir-bot` | Telegram memoir bot LXC (CT 142) | `192.168.1.26` | образ собирается локально |
| `mihomo` | Local proxy/UI LXC (CT 143) | `192.168.1.27` | UI `:8080`, API `:9090`, proxy `:7890/:7891` |
| `adguard` | AdGuard Home LXC (CT 144) | `192.168.1.28` | DNS `:53`, UI `:3000` |
| `docker-test` | Песочница/кандидат в CI-раннеры (CT 145) | `192.168.1.29` | |
| `monitoring` | Monitoring LXC (CT 146) | `192.168.1.30` | Uptime Kuma активен, Prometheus заморожен |
| `hermes-ai` | AI-хост (CT 147) | `192.168.1.31` | ходит наружу через mihomo |
| `emergency-bot` | Telegram-бот break-glass доступа (CT 148) | `192.168.1.32` | |
| `grimmory` | Grimmory + MariaDB (CT 149) | `192.168.1.34` | `books.ada-dev.ru` |
| `gyro` | Investment allocator (CT 150) | `192.168.1.35` | vault-переменные, outbound-only |
### Inventory Groups
- `homelab` — ru-vps
- `pve_nodes` — cloud-pc, mini-pc
- `lxc_infra`pbs, ovpn-mini, vaultwarden, gitea, memoir-bot, mihomo
- `lxc_infra`все LXC (13 шт.)
- `monitoring_server` — monitoring
- `monitoring_exporters` — хосты с Node Exporter
- `monitoring_smart_exporters` — cloud-pc, mini-pc
- `vpn_openvpn` — ru-vps, ovpn-mini
- `shell_hosts` — ru-vps, cloud-pc, mini-pc
- `servers`all managed hosts
- `shell_hosts` — ru-vps, cloud-pc, mini-pc, hermes-ai
- `servers`все управляемые хосты
Общие переменные живут в `inventory/group_vars/`, а не в `hosts.yml`:
`group_vars/all/main.yml` (сеть, доступ, OpenVPN), `group_vars/lxc_infra/main.yml`
(LXC ходят под root без sudo), `group_vars/all/services.yml` (реестр сервисов).
### 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
- **OpenVPN**: ru-vps (10.78.0.1) ↔ ovpn-mini (10.78.0.2), порт 8443/tcp
- **JumpHost**: SSH к нодам и LXC через ProxyJump `ru-vps`; исключения — `pbs` и
`ovpn-mini`, они доступны напрямую по LAN
- Всё это описано в `ansible/ssh_config`; Ansible подключает его через
`ansible_ssh_common_args` в `group_vars/all/main.yml` (путь считается от
`inventory_dir`, поэтому не зависит от cwd и места клона)
## 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
flake.nix / .envrc # Nix dev-окружение (ansible, линтеры, python-зависимости)
.ansible-lint / .yamllint # Конфигурация линтеров
.gitea/workflows/lint.yml # CI: yamllint + ansible-lint + syntax-check
archive/2026-07-proxmox-migration/ # Historical configs (reference only)
ansible/
├── Makefile # ЕДИНАЯ точка входа для ручного управления (make help)
├── ansible.cfg
├── ssh_config # Транспорт: ProxyJump, пользователи, ключи
├── scripts/
│ └── gen-inventory-docs.py
├── inventory/
│ ├── hosts.yml # Только адреса и индивидуальные факты хостов
│ ├── group_vars/
│ │ ├── all/main.yml # Общие переменные
│ │ ├── all/services.yml # Реестр сервисов homelab_services
│ │ └── lxc_infra/main.yml
│ └── host_vars/gyro/ # main.yml + шифрованный vault.yml
├── playbooks/
│ ├── check.yml # Связность и ожидаемые IP
│ ├── status.yml # Read-only сводка по всей инфраструктуре
│ ├── reverse-proxy.yml # Единый Caddy-плейбук по реестру сервисов
│ ├── pve-*.yml # Создание LXC (нужен .env)
│ ├── *-update.yml # Обновления: бэкап -> апдейт -> health-check
│ └── openvpn-*.yml
├── roles/
│ ├── lxc_docker_host/ # LXC под Docker: пакеты, fuse-overlayfs, ufw
│ ├── compose_service/ # compose.yml + systemd-юнит + health-check
│ ├── pve_lxc/ # Создание LXC через Proxmox API
│ ├── backup_audit/ # Аудит PBS и restic
│ ├── monitoring_*/ # Prometheus-стек (заморожен), экспортеры
│ ├── uptime_kuma/ # Активный мониторинг
│ ├── emergency_access/ # Break-glass reverse SSH
│ ├── emergency_bot/ # Telegram-бот break-glass
│ ├── gyro/ # Investment allocator
│ ├── openvpn_gateway/ # OpenVPN транспорт
│ └── bash_config/ # Единый bash-конфиг
└── tasks/
archive/2026-07-proxmox-migration/ # Историческое, только как справка
```
Роли `lxc_docker_host` и `compose_service` созданы, но пока не подключены ни к одному
плейбуку — миграция `pve-*.yml` на них не выполнена. Пример использования и перечень
того, что меняется на живом хосте при переходе, — в `roles/compose_service/README.md`.
## Common Playbooks
Предпочитай `make` — он сам грузит `.env` и защищает опасные цели.
```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
make check # связность и ожидаемые IP
make status # read-only сводка: хосты, юниты, диски, VPN, бэкапы
make deploy-<service> # playbooks/pve-<service>.yml
make dry-<service> # то же с --check --diff
make update-<service> # gitea | vaultwarden | adguard | mihomo | grimmory
make reverse-proxy # Caddy на ru-vps по реестру сервисов
make backup-audit # аудит PBS + offsite restic
make openvpn-check # проверка транспорта ru-vps <-> ovpn-mini
make bash-config # единый bash-конфиг на shell_hosts
make user-ssh-key # разложить публичный ключ на все хосты
```
Обновления всегда идут в порядке: свежий бэкап/аудит -> обновление -> health-check.
Образы закреплены по `tag@sha256:digest`; floating-теги и авто-апдейтеры не используются.
## Proxmox API Tasks
Proxmox playbooks require environment variables:
Плейбукам `pve-*.yml` нужны переменные Proxmox API. Держи их в `ansible/.env`
(файл в `.gitignore`, шаблон — `.env.example`):
```bash
# From .env file
PROXMOX_HOST=<host>
PROXMOX_USER=<user@realm>
PROXMOX_TOKEN_ID=<token_id>
@@ -148,19 +213,20 @@ PROXMOX_TOKEN_SECRET=<secret>
PROXMOX_VALIDATE_CERTS=false
```
Usage:
`make` подхватывает `.env` сам и падает с внятным сообщением, если его нет —
руками `. ./.env` делать не нужно:
```bash
. ./.env
ansible-playbook playbooks/pve-ovpn-mini.yml
ansible-playbook playbooks/pve-vaultwarden.yml
ansible-playbook playbooks/pve-gitea.yml
make env-check # проверить, что .env на месте и заполнен
make dry-gitea # сначала всегда --check --diff
make deploy-gitea
```
Or bootstrap token directly from node:
Выпустить токен, если его ещё нет:
```bash
ansible-playbook playbooks/bootstrap-pve-api-token.yml -K
make bootstrap-pve-token # прямо с ноды, нужен sudo
make bootstrap-monitoring-token # отдельный read-only токен для мониторинга
```
## Secrets Policy