Semaphore: UI para Ansible cuando el equipo crece

Panel de control con switches e indicadores LED representando automatización de operaciones

Semaphore (o Semaphore UI) es la interfaz web open source para ejecutar playbooks de Ansible. Simple, ligera, auto-hosteable. Nació como alternativa pragmática a AWX (upstream open-source de Ansible Tower / Red Hat Ansible Automation Platform) — menos features, pero muchísimo más simple de operar. Para equipos medianos que han superado “ejecutar desde laptop” pero no necesitan la complejidad de AWX, es la opción sensata.

Qué resuelve Semaphore

Los problemas que aparecen cuando el equipo crece:

  • Auditoría: ¿quién ejecutó qué playbook cuándo y sobre qué hosts?
  • Permisos: ¿qué usuarios pueden correr qué playbooks sobre qué inventory?
  • Historial: ¿qué salida dio esa ejecución de hace una semana?
  • Schedules: playbooks periódicos sin dedicar un cron host.
  • Secretos centralizados: vault keys, SSH keys, sin distribuir por laptops.

Sin UI centralizada, todo esto se vuelve ad-hoc y frágil.

Arquitectura

Componentes mínimos:

  • Servidor Semaphore (Go, binario único).
  • Base de datos: MySQL/MariaDB, PostgreSQL, o BoltDB embebido.
  • Ansible disponible en el servidor o container.

No hay workers distribuidos ni colas complejas. Para equipos de <100 ejecuciones simultáneas, basta.

Instalación Docker

version: "3.8"
services:
  semaphore:
    image: semaphoreui/semaphore:latest
    ports:
      - "3000:3000"
    environment:
      SEMAPHORE_DB_DIALECT: postgres
      SEMAPHORE_DB_HOST: postgres
      SEMAPHORE_DB_USER: semaphore
      SEMAPHORE_DB_PASS: ${DB_PASS}
      SEMAPHORE_DB: semaphore
      SEMAPHORE_PLAYBOOK_PATH: /tmp/semaphore
      SEMAPHORE_ADMIN_PASSWORD: ${ADMIN_PASS}
      SEMAPHORE_ADMIN_NAME: admin
      SEMAPHORE_ADMIN_EMAIL: admin@example.com
    volumes:
      - semaphore_data:/etc/semaphore
      - semaphore_tmp:/tmp/semaphore
    depends_on:
      - postgres

  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: semaphore
      POSTGRES_PASSWORD: ${DB_PASS}
      POSTGRES_DB: semaphore
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  semaphore_data:
  semaphore_tmp:
  postgres_data:

Arrancar y loguearse en http://localhost:3000 con admin.

Conceptos clave

Project: un espacio aislado con su inventory, keys, templates.

Inventory: lista de hosts. Puede ser estático (lista directa) o dinámico (script, AWS, etc).

Key Store: SSH keys, passwords, vault passwords. Usados al ejecutar playbooks.

Repository: repo Git donde viven tus playbooks. Semaphore hace pull y ejecuta.

Task Template: asocia un playbook + inventory + keys. Es lo que se ejecuta.

Schedule: un template que corre en cron.

Flujo típico

  1. Tu equipo tiene un repo Git con playbooks Ansible.
  2. Creas proyecto en Semaphore, apuntando al repo.
  3. Defines inventory (producción, staging, etc).
  4. Cargas SSH key con acceso a los hosts.
  5. Creas templates: “deploy web service”, “rotate certs”, “restart postgres”.
  6. Team members ejecutan templates desde UI, con log en vivo.

Todo con permisos: admin puede todo, otros solo lo que les asignas.

Permisos y RBAC

Semaphore tiene:

  • Admin global: manage usuarios, settings.
  • Project owner: manage su proyecto.
  • Manager: puede ejecutar + editar templates.
  • Task runner: solo ejecutar templates existentes.
  • Guest: read-only.

Para equipos con separación dev/ops clara, esto cubre. Para multi-tenancy complejo, AWX tiene más granularidad.

Integración con CI/CD

Semaphore expone API REST. Patterns comunes:

  • Gitea / GitHub Actions llama a Semaphore API tras PR merge.
  • Webhook de repo a Semaphore para rebuild de inventory dinámico.
  • ChatOps: bot de Slack que ejecuta templates via API.
  • Monitoring: alertas disparan templates de remediación.

Ejemplo curl:

curl -X POST https://semaphore.example.com/api/project/1/tasks \
  -H "Cookie: semaphore=..." \
  -d '{"template_id": 5, "debug": false}'

Semaphore vs AWX

Aspecto Semaphore AWX
Complejidad deploy Simple (Docker) Complejo (Kubernetes recomendado)
Base de datos PostgreSQL simple PostgreSQL + Redis
RBAC Básico-medio Avanzado
Custom collections
Workflows Limitados Avanzados (graph)
Notifications Básico Avanzado
Soporte comercial Sí (Red Hat)
Consumo recursos Bajo (~500MB RAM) Alto (~4GB RAM)
Learning curve Baja Media-alta

Semaphore para equipos <50 con necesidades moderadas. AWX para equipos grandes con requisitos complejos.

Dónde queda corto

Ser honesto:

  • Workflows multi-paso complejos: AWX los hace mejor.
  • Enterprise SSO con SAML complex: Semaphore tiene OIDC básico.
  • Multi-organización: Semaphore es “proyectos”, AWX tiene orgs.
  • Escalado horizontal: Semaphore corre en un nodo; AWX distribuye.
  • Fine-grained metrics: AWX tiene más observabilidad built-in.

Casos reales

Patrones que vemos:

  • Empresa de 20-50 admins: Semaphore como centralized runner.
  • MSP gestionando 100 clientes: un proyecto por cliente en Semaphore.
  • Team de platform engineering: self-service para dev teams via templates pre-aprobados.
  • Compliance: audit log para demostrar quién hizo qué cuándo.

Seguridad

Checklist operacional:

  • HTTPS obligatorio via reverse proxy (Traefik, Nginx).
  • Auth integrada con OIDC o LDAP si tienes.
  • SSH keys con passphrase o Vault para secrets.
  • Backup regular del volumen data + dump DB.
  • Monitorización de intentos fallidos de login.
  • Actualizar versiones — leer changelog.

Integración con HashiCorp Vault

Semaphore puede consultar secretos de Vault en tiempo de ejecución:

- name: fetch secret
  set_fact:
    api_key: "{{ lookup('hashi_vault', 'secret=secret/data/api token=VAULT_TOKEN') }}"

Con VAULT_TOKEN en Semaphore como env var. Secretos nunca en disco.

Conclusión

Semaphore es la opción pragmática para equipos medianos que quieren una UI para Ansible sin la complejidad de AWX. Su foco en simplicidad es su fuerza: instalas en minutos, operas sin dolor, cubre casos reales. Para organizaciones grandes con requisitos de workflow complejos, SSO empresarial y multi-tenancy, AWX sigue siendo la referencia. La elección debe basarse en tamaño del equipo y sofisticación de necesidades. Muchas veces, lo simple es lo correcto.

Síguenos en jacar.es para más sobre Ansible, automatización y DevOps práctico.

Entradas relacionadas