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
- Tu equipo tiene un repo Git con playbooks Ansible.
- Creas proyecto en Semaphore, apuntando al repo.
- Defines inventory (producción, staging, etc).
- Cargas SSH key con acceso a los hosts.
- Creas templates: “deploy web service”, “rotate certs”, “restart postgres”.
- 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 | Sí | Sí |
| 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.