Ctrl K
ComunidadGuías…

AGENTS.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# AutoBott — Agent Guide

Ansible playbooks to manage self-hosted services on Debian servers (and basic Debian desktops).

## Project Overview

AutoBott automates the installation and configuration of a full self-hosted stack on Debian:
- Base system hardening, ZFS, VPN (WireGuard/Tailscale), backup (Borg/Borgmatic)
- Web stack: Caddy, PHP-FPM, Authelia, MariaDB
- Monitoring: Prometheus, Grafana, Alertmanager, Monit
- Media/Servarr: Jellyfin, Kavita, Sonarr, Radarr, etc.
- Productivity: Immich, Docmost, MediaWiki, Homepage
- Desktop: KDE, developer tools, desktop apps

## Documentation

Full project documentation lives in a **separate `docs` repository**, available
two ways:

- **Online:** https://ansible-autobott.github.io/docs/
- **Locally:** a colocated sibling directory next to this repo — `../docs`
  (on this machine: `/home/bott/.datos/edit/programacion/autobott/docs`).

It is a Hugo site; the Markdown sources live under `../docs/content/docs/`,
grouped into `Getting Started/`, `Guides/`, and `roles/`. Prefer the local copy
when it is present (it may be ahead of the published site); otherwise use the
online version.

## Development Setup

```bash
make prepare           # Create venv + install ansible==11.6.0 and deps
source venv/bin/activate
```

## Common Commands

```bash
# Lint (strict) — CI (.github/workflows/lint.yml) runs `make lint` on every PR
make lint
make lint-fix          # review the diff: the fixer can reflow Jinja/long lines

# Run playbook against real inventory
make run INV=../inventory/main.yaml HOST=myhost TAG=role_docker
make run-verbose INV=../inventory/main.yaml TAG=role_caddy

# Enroll a new host
make enroll INV=../inventory/main.yaml HOST=myhost ANSIBLE_USER=root

# Vagrant testing (Debian 13 VMs; Debian 14 placeholder)
make vagrant-up
make vagrant-run TAG=role_docker        # Test a specific role
make vagrant-test                        # Run validation tests (test.yaml)
make vagrant-destroy

# Secrets
make encrypt INV=../inventory/main.yaml KEY=mariadb_root_pass VALUE=s3cr3t
make decrypt INV=../inventory/main.yaml

# Release (clean git, on main branch)
# First bump autobot_version in roles/base/enroll/defaults/main.yaml, then tag.
# Pushing the tag triggers .github/workflows/release.yml, which publishes the
# GitHub release (with auto-generated notes).
make tag version=v0.2.0
```

## Before Opening a PR

Review whether the change should ship as a release. If it should, bump `autobot_version` in
`roles/base/enroll/defaults/main.yaml` **before** opening the PR, so the version bump is part
of the reviewed diff. Tagging later (`make tag`) triggers `.github/workflows/release.yml`, so
the version file must already reflect the intended release by the time the PR is merged.

## Architecture

### Playbook Structure

`autobott.yaml` has 4 plays:
1. **All hosts** — base, base-services, security foundation
2. **linux_servers** — web-base, monitoring, servarr, webservices
3. **linux_desktop** — KDE, gui-apps, cli-apps, dev-* toolchains
4. **post-setup** — finalization, version write

### Role Organization

```
roles/
  base/          # preconditions, enroll, linux-apt, linux-basic, zfs, nullmailer, smartd, hdparm
  base-services/ # wireguard, tailscale, docker, samba, mariadb, borg, borgmatic, goback
  security/      # lynis, malwarescan, crowdsec, firewall
  web-base/      # php-fpm, caddy, authelia, vhosts
  monitoring/    # prometheus, alertmanager, node_exporter, grafana, monit
  webservices/   # homepage, docmost, mediawiki, immich, mealie, etnafinance, radicale, fe26, phpmyadmin
  servarr/       # jellyfin, kavita, transmission, sonarr, radarr, prowlarr, lidarr, whisparr, romm, stash, xbvr
  desktop/       # linux-desktop, linux-kde, vbox-guest, gui-apps, cli-apps, dev-node, dev-go, dev-java, dev-k8s, dev-ai, dev-generic
  games/         # minecraft
  k8s/           # k3s
  validation/    # test roles
```

> The desktop app catalogue is split across several roles, each following the
> same pattern (a `<role>_config` selection mapping validated against a
> `<role>_available` list; per-app tasks in `tasks/apps/<app>.yaml`; per-app
> defaults in `defaults/main.yaml`):
> - **`desktop/gui-apps`** — GUI apps (via `gui_apps_config`)
> - **`desktop/cli-apps`** — general CLI utilities: ytdlp, linux-candy, dibs,
>   todo (via `cli_apps_config`)
> - **`desktop/dev-node`** — Node.js toolchain (via `dev_node_config`)
> - **`desktop/dev-go`** — Go toolchain + go-deps-view (via `dev_go_config`)
> - **`desktop/dev-java`** — jenv + maven (via `dev_java_config`)
> - **`desktop/dev-k8s`** — kubectl + k9s (via `dev_k8s_config`)
> - **`desktop/dev-ai`** — AI coding agents: herdr, claude-code, pi,
>   copilot-cli (via `dev_ai_config`)
> - **`desktop/dev-generic`** — other dev tools: vagrant, vault, github-cli
>   (via `dev_generic_config`)
>
> The candy-tools shared apt repo is used by both `cli-apps` (dibs, linux-candy,
> todo) and `dev-go` (go-deps-view); each role adds it idempotently.

### Role Conventions

Every role follows this layout:
```
roles/<category>/<role-name>/
  defaults/main.yaml   # All variables; always includes run_role_<name>: true
  tasks/main.yaml      # All tasks wrapped in block: with when: run_role_<name> guard
  handlers/main.yaml   # Handlers (if needed)
  templates/           # Jinja2 templates (.j2)
  meta/main.yaml       # Role metadata (if needed)
```

Some roles include an `About.md` file with detailed architecture decisions and technical context. Always check for this file when working on a role.

Key rules:
- Every role has a boolean `run_role_<name>: true` in defaults — this is how per-host opt-out works
- Tasks always use `block:` with `tags: [role_<rolename>]` and `when: run_role_<name>`
- Use `ansible.builtin.*` fully-qualified module names
- Variables follow `<rolename>_<setting>` pattern (e.g. `wireguard_port`, `mariadb_root_pass`)
- Sensitive defaults (passwords, keys) use empty string `""` — must be overridden in inventory
- User-configurable dicts: define `<role>_defaults` in defaults/, merge with inventory dict via `combine(recursive=True)`

### Inventory Structure

Per-host config lives in `inventory/host_vars/<hostname>/` with files grouped by category (base.yaml, webservices.yaml, etc.). Secrets are SOPS-encrypted `secrets.sops.yaml` files, decrypted at runtime by the `community.sops` vars plugin; the age private key lives at `<inventory-dir>/sops_key` (never commit a real key).

## Adding a New Role

1. Create `roles/<category>/<rolename>/defaults/main.yaml` and `tasks/main.yaml`
2. In defaults: define `run_role_<rolename>: true` and all variables
3. In tasks: wrap all tasks in `block:` guarded by `when: run_role_<rolename>` with `tags: [role_<rolename>]`
4. Add the role to the correct play in `autobott.yaml`
5. Test: `make vagrant-run TAG=role_<rolename>`
6. Lint: `make lint`

## Key Files

| File | Purpose |
|------|---------|
| `autobott.yaml` | Main playbook — add new roles here |
| `roles/base/enroll/defaults/main.yaml` | Contains `autobot_version` — bump before release |
| `Makefile` | All commands — read before running anything |
| `inventory/vagrant.yaml` | Vagrant test inventory |
| `.sops.yaml` | SOPS creation rules — which age keys encrypt which files; edit secrets via `make edit-secrets` |
| `CLAUDE.md` | Symlink to `AGENTS.md` — Claude Code reads the same guide |
| `../docs/content/docs/` | Full documentation sources (see [Documentation](#documentation)) |