Saltar a contenido

Agregar un servicio nuevo a SmallCountry

Guía paso a paso para incorporar un nuevo servicio al ecosistema, desde la decisión de arquitectura hasta el despliegue verificado. Cada paso existe para garantizar que la incorporación respeta los principios inmutables y no introduce fragilidad.


Checklist previa: la Regla de Oro

Antes de empezar, aplica las seis preguntas de la Regla de Oro para Añadir Componentes:

  1. ¿Rompe algún principio fundamental?
  2. ¿Añade complejidad sin un beneficio claro?
  3. ¿Es realmente imprescindible para alguien? (al menos un perfil de usuario concreto que lo use semanalmente)
  4. ¿Cabe dentro del presupuesto de complejidad?
  5. ¿Tiene definido su consumo energético? (reposo y carga, ¿depende de Ra o de Horus?)
  6. ¿Estará documentado su despliegue y su recuperación?

Si cualquier respuesta es "no" o "no sé", el servicio no entra. La Regla de Oro no frena la innovación: garantiza que cada pieza nueva hace el sistema mejor, no solo más grande.


Paso 1 — Proponer ADR si la decisión es significativa

No todo cambio necesita un ADR. Sí lo necesita cuando:

  • Introduce una tecnología nueva no usada antes en SmallCountry (nuevo motor de BD, nuevo protocolo, nuevo paradigma).
  • Cambia una decisión arquitectónica existente.
  • Implica una excepción a los estándares establecidos (ej. Docker en lugar de LXC, MySQL en lugar de PostgreSQL).
  • Tiene implicaciones de licencia: verifica que el software cumple con ADR-023 — Software libre. Si es privativo, el ADR debe justificar la excepción explícitamente y proponer un plan de migración futura.

El ADR se escribe en docs/adr/ siguiendo el formato estándar (contexto, decisión, alternativas consideradas, consecuencias) y se numera secuencialmente.

Si la decisión no es significativa (p.ej. añadir una app más a un stack ya existente, usar una tecnología ya aprobada), documenta la decisión como comentario en el playbook de Ansible y continúa.


Paso 2 — Elegir ID de LXC y asignar recursos

Según ADR-018 — LXC como unidad de aislamiento, cada servicio corre en su propio LXC sobre Proxmox. Docker se usa solo como excepción justificada.

  1. Elige un ID de LXC no usado:
  2. Consulta el Inventario de servicios para ver IDs ocupados.
  3. El rango 100–199 está reservado para infraestructura (Tier A).
  4. El rango 200–299 para servicios de usuario (Tier B).
  5. El rango 300–399 para IoT y finca (Tier C).
  6. El rango 400–499 para experimentales (Tier D).
  7. Asígnale un ID coherente con su tier.

  8. Asigna recursos (CPU, RAM, Disco):

  9. Estima el consumo consultando la documentación oficial del servicio.
  10. Para RAM: asigna lo recomendado + 256 MB de margen para el sistema operativo del LXC.
  11. Para disco: calcula datos de aplicación + logs + backups temporales. Usa ZFS (sistema de archivos con integridad de datos) con compresión activada.
  12. Registra la asignación en la tabla del Inventario de servicios.

  13. Crea el LXC:

  14. Usa la plantilla de Debian estable (actualmente Debian 12).
  15. Asígnale el ID, CPU, RAM y disco decididos.
  16. Base de datos: según ADR-019 — PostgreSQL estándar, si el servicio necesita base de datos relacional, usa PostgreSQL. Si el servicio solo se distribuye con soporte para otro motor (ej. MySQL), documéntalo como excepción en el ADR correspondiente.

Paso 3 — Configurar bridge y VLAN

Cada servicio se conecta a uno de los tres bridges de Proxmox según su ámbito:

Bridge Subred Ámbito
vmbr1 10.10.10.0/24 Infraestructura y administración
vmbr2 10.10.20.0/24 Servicios de usuario (familia, empresa)
vmbr3 10.10.30.0/24 IoT y finca
  1. Selecciona el bridge según el ámbito del servicio.
  2. Asigna una IP estática dentro de la subred correspondiente. La IP suele coincidir con el ID del LXC (ej. LXC 150 → 10.10.20.150).
  3. Aplica política Default Deny entre bridges: el movimiento lateral entre subredes solo se permite con reglas explícitas de firewall. Si el servicio necesita comunicarse con otro en distinto bridge, documenta la regla.
  4. Registra la configuración de red en OpenTofu (modules/proxmox/) o en la configuración del LXC.

Paso 4 — Escribir rol de Ansible (o documentar despliegue manual)

Todo servicio debe tener un playbook de Ansible que garantice la reconstruibilidad total.

  1. Crea el rol en roles/[nombre-servicio]/:

    roles/[nombre-servicio]/
    ├── tasks/
    │   └── main.yml
    ├── templates/
    ├── files/
    └── vars/
        └── main.yml
    

  2. Crea el playbook en deploy-[nombre-servicio].yml:

  3. Instala dependencias del sistema.
  4. Si usa Docker (excepción documentada): despliega con docker compose.
  5. Si es instalación nativa: configura servicio systemd, archivos de configuración, usuario de sistema.
  6. Configura PostgreSQL si el servicio lo requiere: crea base de datos, usuario y permisos.
  7. Aplica hardening básico: firewall local (nftables/iptables), usuario no root para el servicio, permisos mínimos.

  8. Registra en Semaphore: crea proyecto y template deploy en Ansible Semaphore para ejecución controlada (carril lento) o automatizada (carril rápido), según Dos Carriles de Cambio.

  9. Si el despliegue es manual (ej. dispositivo IoT sin acceso SSH, firmware propietario):

  10. Documenta cada paso en la ficha técnica (sección "Para el administrador").
  11. Registra el procedimiento en docs/operaciones/diario.md.
  12. El administrador es responsable de mantener la ficha actualizada ante cambios manuales.

Paso 5 — Configurar provider en Authentik (si necesita OIDC/SAML)

Si el servicio expone una interfaz web y debe ser accesible para usuarios, intégralo con Authentik:

  1. Crea un Provider en Authentik:
  2. Tipo: OAuth2/OIDC (preferido) o SAML según soporte del servicio.
  3. Scopes típicos: openid profile email.
  4. Redirige al callback del servicio.

  5. Crea una Application en Authentik vinculada al provider.

  6. Asigna grupos según el perfil de acceso:

  7. familia para servicios del hogar.
  8. empresa para servicios de trabajo.
  9. admin para acceso restringido.
  10. finca para IoT y campo.

  11. Verifica que el flujo de login funciona: https://[servicio].sc → redirige a https://authentik.sc → login → redirige de vuelta.

  12. Documenta la configuración en la ficha técnica del servicio (sección "En Authentik").


Paso 6 — Añadir registro DNS en Pi-hole

Cada servicio necesita un nombre de dominio dentro de la red de SmallCountry:

  1. Añade el registro A en Pi-hole:
    [servicio].sc  →  [IP del LXC]
    
  2. Si el servicio expone múltiples nombres (ej. collabora.sc además de nextcloud.sc), añade cada uno.
  3. Usa el dominio .sc (SmallCountry) según ADR-007 — Dominio .sc.
  4. Verifica con dig servicio.sc @10.10.10.1 (IP de Pi-hole).

Paso 7 — Añadir bloque reverse_proxy en Caddy

Si el servicio tiene interfaz web, necesita entrada en Caddy:

  1. Añade el bloque en el Caddyfile (o en la configuración del LXC de Caddy, LXC 102):
    [servicio].sc {
        forward_auth authentik.sc {
            uri /api/auth
        }
        reverse_proxy [IP del LXC]:[puerto]
    }
    
  2. forward_auth solo si el servicio usa Authentik (Paso 5).
  3. Si el servicio maneja su propia autenticación, omite forward_auth.

  4. Recarga Caddy para aplicar la configuración sin interrupción:

    caddy reload --config /etc/caddy/Caddyfile
    

  5. Verifica con curl -I https://servicio.sc.


Paso 8 — Crear ficha técnica desde la plantilla

Copia y completa la plantilla de ficha:

  1. Copia docs/fichas/_plantilla.md a docs/fichas/programas/[nombre-servicio].md.
  2. Completa todas las secciones con la información recopilada en los pasos anteriores:
  3. Logo, estado, versión.
  4. Descripción y rol de usuario.
  5. Tabla de integraciones.
  6. Servicios de los que depende.
  7. Sección "Para el administrador": LXC ID, IP, recursos, almacenamiento, healthcheck, logs, backups, problemas comunes.
  8. Sección "Para el arquitecto": diagrama mermaid, configuración de red, DNS, Caddy, Authentik, orquestación.
  9. Enlaces de interés.

  10. No dejes placeholders [___] sin rellenar. Si un dato no aplica, escribe "No aplica" o elimina la sección.

  11. La ficha queda versionada en el repositorio infra-core/ junto con el playbook.

Paso 9 — Actualizar mkdocs.yml nav

Añade la nueva ficha al índice de navegación para que sea visible en la documentación:

  1. Edita mkdocs.yml.
  2. Busca la sección "Fichas por programa" dentro de "Referencia".
  3. Añade la entrada en la categoría que corresponda:
  4. Infraestructura para servicios de red, almacenamiento, automatización.
  5. Seguridad y red para identidad, proxy, VPN, firewall.
  6. Observabilidad para métricas, logs, alertas.
  7. IoT y finca para sensores, actuadores, gateway energético.
  8. IA y voz para LLM, agentes, speech-to-text.
  9. Usuario para servicios de hogar y familia.
  10. Media para contenido multimedia.
  11. Empresa para herramientas de negocio.
  12. Conocimiento y herramientas para ciencia, desarrollo, utilidades.
    - Nombre del servicio: fichas/programas/[nombre-servicio].md
    

Paso 10 — Verificar con CI

Antes de considerar el servicio como desplegado, verifica que pasa las comprobaciones automáticas:

  1. Ejecuta el playbook en modo check (ansible-playbook --check) para validar sintaxis e idempotencia.
  2. Verifica el pipeline de CI/CD en Forgejo Actions (.forgejo/workflows/[servicio].yml):
  3. plan: OpenTofu plan sin errores.
  4. snapshot ZFS: copia de seguridad previa al cambio.
  5. apply: despliegue efectivo.
  6. verify: healthcheck del servicio (curl, docker exec healthcheck).
  7. Si hay drift (divergencia entre el estado deseado y el real), el pipeline se detiene y genera un commit forense.
  8. Verifica observabilidad:
  9. ¿Aparece en Grafana? Añade dashboard si no existe.
  10. ¿Está monitorizado en Uptime Kuma? Añade monitor HTTP o TCP.
  11. ¿Genera logs visibles en Victoria Logs?
  12. Prueba el acceso de usuario: abre https://[servicio].sc desde un dispositivo de la familia conectado a la VPN (red privada virtual).
  13. Registra en el diario de operaciones (docs/operaciones/diario.md): fecha, servicio, LXC ID, IP, incidencias.

Resumen rápido

Paso Acción Responsable
1 ADR (si aplica) Arquitecto
2 LXC ID + recursos Hefesto — IaC
3 Bridge + VLAN Hermes — Red
4 Rol Ansible / playbook Hefesto — IaC
5 Provider Authentik Jano — Identidad
6 DNS Pi-hole Hermes — Red
7 Caddy reverse_proxy Hermes — Red
8 Ficha técnica Argos — Observabilidad
9 mkdocs.yml nav Argos — Observabilidad
10 CI + verificación Hefesto — IaC

Secciones relacionadas