Saltar a contenido

ADR-028: IaC — Ansible + Semaphore + OpenTofu

Estado: aceptado

Contexto

SmallCountry requería un sistema de Infrastructure as Code que permitiera la reconstruibilidad total desde cero (principio 2), la convergencia automática del estado declarado, y la trazabilidad de todos los cambios (principio 1). El sistema debía ser operable por una sola persona.

Decisión

Tres herramientas complementarias con responsabilidades separadas:

Ansible — Configuración declarativa. Roles idempotentes para instalar y configurar servicios dentro de los LXC. Es la herramienta principal de convergencia del estado deseado.

Semaphore — Interfaz de ejecución para Ansible. Programa playbooks, mantiene historial de ejecuciones, y permite rollback. Es la capa de orquestación operativa.

OpenTofu — Aprovisionamiento de infraestructura. Define LXCs, redes, datasets ZFS y recursos de Proxmox como código. Estado actual: planificado, no implementado. Se adoptará cuando la infraestructura lo justifique (múltiples nodos, complejidad de red que requiera gestión declarativa de topología).

Alternativas consideradas

Herramienta Alternativa Por qué se descartó
Ansible Chef/Puppet Mayor complejidad. Requieren agentes. Ansible es agentless via SSH.
Ansible Scripts bash No son idempotentes. No garantizan convergencia. Viola principio 2.
Semaphore AWX Mayor consumo de recursos. Sobredimensionado para una sola persona.
Semaphore Ejecución manual Sin trazabilidad ni historial. Viola principio 1.
OpenTofu Terraform Cambio de licencia de HashiCorp (BSL). Viola principio 23.
OpenTofu Pulumi Mayor complejidad. Requiere lenguajes de programación para config.

Consecuencias

  • ✅ Playbooks Ansible idempotentes y versionados en Forgejo
  • ✅ Semaphore como capa de ejecución con historial y rollback
  • ✅ OpenTofu preparado para cuando la topología lo requiera
  • ✅ Todo el código de infraestructura es trazable (principio 1)
  • ❌ OpenTofu aún no implementado — los LXC se crean manualmente o via scripts
  • ❌ Tres herramientas que aprender (mitigado: Semaphore abstrae Ansible; OpenTofu es deferred)