Saltar a contenido

01 fuente unica

Principio

La infraestructura y la configuración de SmallCountry se definen como código:
se escriben en code-server, se versionan en Forgejo, se planifican con OpenTofu, se despliegan mediante Forgejo Actions y se aplican declarativamente con Ansible usando roles idempotentes.
Cualquier cambio que no recorra este flujo completo es una divergencia que detiene el sistema y exige reconciliación humana.

Ciclo de vida de un cambio

  1. **Escritura en code-server
    Desde el entorno de desarrollo accesible por navegador se editan simultáneamente los módulos de OpenTofu, los roles de Ansible, la documentación y los prompts de IA. Es el único punto de entrada para cualquier modificación del sistema.

  2. **Versionado en Forgejo
    Todo el código se aloja en el repositorio central, que actúa como fuente de verdad, registro OCI de imágenes y motor de CI/CD (integración y despliegue continuo).
    El flujo de trabajo es: feature-branch → Pull Request → revisión humana → merge a main.

  3. **Planificación con OpenTofu
    Cada Pull Request ejecuta tofu plan. El resultado se compara con el estado real de Proxmox VE a través de su API (interfaz de programación).
    Si existe deriva —cambios ejecutados fuera de Git— el flujo se detiene, se genera un commit forense en una rama quarantine y se notifica al administrador. Este mecanismo garantiza que la deriva nunca quede sin auditar.

  4. **Aplicación declarativa con Ansible
    Tras la creación o actualización de los LXC (contenedor ligero de Proxmox) por OpenTofu, Ansible entra en juego aplicando roles declarativos. Cada rol describe el estado final deseado (paquetes instalados, ficheros de configuración, contenedores Docker activos, certificados TLS (cifrado de comunicaciones) presentes) sin preocuparse del estado actual.
    La idempotencia está verificada: ejecutar el mismo rol cien veces produce exactamente el mismo resultado seguro que ejecutarlo una sola vez.

  5. Consolidación
    Al finalizar el despliegue, el estado real del sistema coincide exactamente con el declarado en Forgejo. Cualquier intervención manual futura que se salte este flujo será detectada como deriva y forzará una reconciliación documentada.

graph TD
    subgraph Escritura [Escritura]
        direction LR
        A[code-server] --> B[Módulos OpenTofu / Roles Ansible / Documentación]
    end

    subgraph Versionado [Versionado]
        direction LR
        C[Forgejo] --> D[Pull Request]
        D --> E[Revisión humana]
        E --> F[Merge a main]
    end

    subgraph Planificacion [Planificación]
        direction LR
        G[Forgejo Actions] --> H[tofu plan]
        H --> I[Detección de drift]
        I --> J[¿Divergencia?]
        J -->|Sí| K[Commit forense + notificación]
        J -->|No| L[tofu apply]
    end

    subgraph Aplicacion [Aplicación declarativa]
        direction LR
        M[OpenTofu] --> N[Creación / actualización de LXCs]
        N --> O[Ansible Semaphore]
        O --> P[Roles declarativos idempotentes]
    end

    subgraph Consolidacion [Consolidación]
        direction LR
        Q[Estado real = Estado declarado] --> R[ZFS snapshot]
    end

    Escritura --> Versionado
    Versionado --> Planificacion
    Planificacion --> Aplicacion
    Aplicacion --> Consolidacion

    style Escritura fill:#f9a8d4,stroke:#c2185b,color:#000
    style Versionado fill:#f48fb1,stroke:#c2185b,color:#000
    style Planificacion fill:#90caf9,stroke:#1565c0,color:#000
    style Aplicacion fill:#a5d6a7,stroke:#2e7d32,color:#000
    style Consolidacion fill:#ffe082,stroke:#f57f17,color:#000

Ansible como motor declarativo

En SmallCountry, Ansible no se usa como un simple ejecutor de comandos, sino como garante del estado deseado. Cada servicio tiene su propio rol, estructurado según las mejores prácticas:

Archivo / Carpeta Propósito
roles/authentik/tasks/main.yml Tareas declarativas: instalar paquetes, crear volúmenes, desplegar docker-compose
roles/authentik/handlers/main.yml Acciones reactivas: reiniciar el servicio si cambia la configuración
roles/authentik/templates/ Plantillas de configuración (authentik.conf.j2, docker-compose.yml.j2)
roles/authentik/vars/main.yml Variables específicas del rol (versión de la imagen, puertos, secretos referenciados desde Vault)
roles/authentik/meta/main.yml Dependencias: requiere que el rol docker esté aplicado primero
### Propiedades clave
Propiedad Descripción
Declaratividad estricta Las tareas describen el estado final deseado, no los pasos para alcanzarlo.
Idempotencia real Se emplean condiciones como creates, when o changed_when para que Ansible decida si debe actuar o si el estado ya es correcto, evitando reinicios innecesarios.
Roles atómicos y desacoplados El rol authentik no sabe en qué red ni en qué LXC se ejecuta; esa información se la proporciona OpenTofu. Así se puede reutilizar el mismo rol en distintos entornos sin modificarlo.
Secretos como código Las variables sensibles (contraseñas, tokens OIDC (protocolo de autenticación OpenID Connect), claves API) se generan, se cifran con Ansible Vault y se versionan en Forgejo. En el momento del despliegue se inyectan sin que nunca existan en texto plano en producción.
Separación de responsabilidades OpenTofu crea y dimensiona el LXC (recursos, red, almacenamiento); Ansible lo provisiona (Docker, configuración, certificados). No se mezclan responsabilidades.

Stack necesario

  • code-server – Entorno de desarrollo desde navegador.
  • Forgejo – Repositorio Git, CI/CD y registro OCI.
  • OpenTofu – Infraestructura como código (módulos declarativos).
  • Forgejo Actions – Pipelines de planificación y despliegue.
  • Ansible + Semaphore – Configuración declarativa con roles.
  • Ansible Vault – Cifrado de secretos.
  • Script de detección de drift – Compara plan de OpenTofu con estado real de Proxmox VE.
  • ZFS – Snapshots pre‑cambio para rollback instantáneo.

Relaciones con otros principios

Flujo de remediación automática

Cuando el sistema detecta una degradación —un servicio caído, un recurso al límite, una métrica fuera de SLO (objetivo de nivel de servicio)— se activa una cadena de corrección que atraviesa todas las capas del ecosistema:

  1. SkyEye detecta — una alerta de Prometheus, un healthcheck fallido de Uptime Kuma, o una anomalía detectada por los agentes nocturnos de IA
  2. n8n interpreta — recibe el evento, consulta el runbook correspondiente y decide la acción (reiniciar servicio, escalar recurso, notificar)
  3. Semaphore ejecuta — lanza el playbook de Ansible apropiado de forma controlada y registrada
  4. Ansible converge — aplica el estado deseado de forma idempotente, devolviendo el sistema a su condición normal

Todo este flujo deja trazabilidad completa en Forgejo. Si en algún punto se requiere intervención humana, el sistema notifica y espera. La automatización acelera, pero nunca sustituye el criterio cuando la situación lo exige.


Mecanismo 10: Perfiles de Energía   |   Principio 2: Reconstruibilidad total


Secciones relacionadas