Quand j'ai préparé le cours sur Ansible Tower, une question revenait sans cesse : « D'accord, mais pour mes quatre serveurs, je fais comment ? » Parce que la réalité, c'est qu'AWX (la version open source de Tower) demande aujourd'hui un cluster Kubernetes et un opérateur, avec plusieurs composants à maintenir. Pour une petite équipe ou une infra personnelle, c'est disproportionné.
La réponse que je donne maintenant, c'est Semaphore UI. Les mêmes idées que Tower (projets, clés, inventaires, modèles de tâches, historique, droits), dans un seul conteneur Docker. Voici comment l'installer proprement et l'utiliser de débutant à expert.
Ce que fait Semaphore (et ce qu'il ne fait pas)
Semaphore est une interface web pour lancer vos automatisations en équipe, avec un historique complet et des accès contrôlés. Contrairement à ce que son nom historique (« Ansible Semaphore ») laisse penser, il ne se limite plus à Ansible : il lance aussi Terraform, OpenTofu, Terragrunt, et des scripts Bash, PowerShell ou Python.
Ce qu'il n'a pas, par rapport à Tower : pas de workflows graphiques avec branches conditionnelles, pas de sources d'inventaire dynamiques aussi riches, pas de surveys aussi poussés. Pour la grande majorité des petites et moyennes équipes, ce n'est pas un problème.
Étape 1 : l'installation avec Docker Compose
J'utilise PostgreSQL plutôt que la base embarquée : c'est ce que recommande le projet pour la production, et ça simplifie les sauvegardes. Et comme tous mes services, Semaphore passe derrière Traefik en HTTPS.
services:
semaphore-db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: semaphore
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: semaphore
volumes:
- semaphore-db:/var/lib/postgresql/data
networks: [internal]
semaphore:
image: semaphoreui/semaphore:v2.13.0 # à adapter : dernière version stable
restart: unless-stopped
depends_on: [semaphore-db]
environment:
SEMAPHORE_DB_DIALECT: postgres
SEMAPHORE_DB_HOST: semaphore-db
SEMAPHORE_DB_PORT: 5432
SEMAPHORE_DB_USER: semaphore
SEMAPHORE_DB_PASS: ${DB_PASSWORD}
SEMAPHORE_DB: semaphore
SEMAPHORE_ADMIN: admin
SEMAPHORE_ADMIN_NAME: Administrateur
SEMAPHORE_ADMIN_EMAIL: admin@monsite.fr
SEMAPHORE_ADMIN_PASSWORD: ${ADMIN_PASSWORD}
SEMAPHORE_ACCESS_KEY_ENCRYPTION: ${ENCRYPTION_KEY}
volumes:
- semaphore-data:/var/lib/semaphore
networks: [internal, traefik_web]
labels:
- traefik.enable=true
- traefik.http.routers.semaphore.rule=Host(`semaphore.monsite.fr`)
- traefik.http.routers.semaphore.entrypoints=websecure
- traefik.http.routers.semaphore.tls.certresolver=letsencrypt
- traefik.http.services.semaphore.loadbalancer.server.port=3000
volumes:
semaphore-db:
semaphore-data:
networks:
internal:
traefik_web:
external: true
Deux points importants :
SEMAPHORE_ACCESS_KEY_ENCRYPTIONest la clé qui chiffre tous les secrets du Key Store. Générez-la avechead -c32 /dev/urandom | base64, et sauvegardez-la en dehors du serveur. Sans elle, une restauration de base ne vous rendra que des secrets illisibles.- Le port 3000 n'est pas publié sur l'hôte : seul Traefik y accède, via le réseau Docker.
Un docker compose up -d, on ouvre https://semaphore.monsite.fr, et on se connecte avec le compte administrateur.
Le projet : l'unité d'organisation
Tout commence par un projet. Il regroupe tout ce qu'il faut pour automatiser : les clés, les dépôts, les inventaires, les variables et les modèles de tâches. Je crée en général un projet par équipe ou par grand périmètre (« Infra perso », « Clients », « Lab »).
Étape 2 : le Key Store
C'est le coffre à secrets du projet. On y range :
- les clés SSH pour se connecter aux serveurs et cloner les dépôts privés ;
- les identifiants (login / mot de passe, mot de passe
become) ; - les mots de passe Ansible Vault.
Une fois enregistrés, ils sont chiffrés et ne s'affichent plus jamais, même pour l'administrateur. On peut les remplacer, pas les relire.
Étape 3 : le dépôt
On renseigne l'URL du dépôt Git qui contient les playbooks, la branche, et la clé du Key Store pour y accéder. À chaque lancement, Semaphore récupère la dernière version : le dépôt reste la seule source de vérité, comme avec Tower.
Étape 4 : l'inventaire
Trois possibilités : l'écrire directement dans l'interface (format INI ou YAML), pointer vers un fichier du dépôt, ou un fichier sur le serveur Semaphore. On l'associe à la clé SSH qui permet de se connecter aux machines.
[web]
web1.monsite.fr
web2.monsite.fr
[monitoring]
10.8.0.3 # joignable via WireGuard
[all:vars]
ansible_user=deploy
Si vous avez cloisonné votre infra avec WireGuard (comme je le décris dans mon article dédié), placez Semaphore sur une machine du réseau VPN : il pourra joindre les adresses privées des serveurs, sans qu'aucun SSH ne soit exposé publiquement.
Étape 5 : les variables
Un groupe de variables (appelé environment dans l'interface) contient des variables Ansible au format JSON, des variables d'environnement, et des secrets. On le réutilise dans plusieurs modèles : un groupe « production », un groupe « recette ».
Étape 6 : le modèle de tâche
C'est l'équivalent du job template de Tower. Il assemble : quel playbook (chemin dans le dépôt), quel inventaire, quel dépôt, quel groupe de variables. On peut y ajouter des arguments CLI (--limit, --tags) et choisir le type : tâche classique, build (qui produit un artefact versionné) ou deploy (qui déploie un build précis).
Un clic sur « Run », et le journal s'affiche en direct, ligne par ligne, exactement comme dans votre terminal. Chaque exécution est conservée : qui l'a lancée, quand, avec quel commit, et le résultat complet.
Les questions au lancement
Pour les personnes qui ne connaissent pas Ansible, on ajoute des questions au modèle (l'équivalent des surveys de Tower) : la version à déployer, le nom d'un utilisateur à créer. Elles s'affichent dans un formulaire au lancement et deviennent des variables du playbook.
Niveau avancé
Les planifications
Un modèle peut se lancer selon une expression cron. Mon usage typique :
0 3 * * 0 # mises à jour de sécurité, chaque dimanche à 3 h
30 2 * * * # vérification des sauvegardes, chaque nuit
Les droits
Les droits se gèrent par projet, avec quatre rôles : propriétaire, gestionnaire, lanceur de tâches (task runner) et invité en lecture seule. L'authentification peut passer par LDAP ou OpenID Connect (Authentik, Keycloak, Google…), et l'authentification à deux facteurs est disponible pour les comptes locaux.
Les notifications
En cas d'échec, Semaphore prévient par e-mail, Telegram, Slack, Microsoft Teams, Rocket.Chat, Gotify ou DingTalk. On sait tout de suite quelle tâche a échoué, et on clique directement sur son journal.
Niveau expert
Les intégrations (webhooks)
Une intégration expose une URL secrète qui déclenche un modèle de tâche. Votre dépôt GitLab ou GitHub l'appelle à chaque push sur la branche principale, et le déploiement part tout seul. On peut filtrer sur le contenu du webhook (la branche, l'auteur) et en extraire des valeurs pour les passer en variables.
Les runners
Par défaut, les tâches s'exécutent dans le conteneur Semaphore lui-même. Pour lancer des tâches sur plusieurs machines, ou au cœur d'un réseau isolé, on ajoute des runners : de petits agents qui se connectent au serveur, récupèrent les tâches en attente et les exécutent sur place.
L'API
Tout ce que fait l'interface est disponible par l'API REST, avec un jeton créé dans votre profil :
curl -s -X POST \
-H "Authorization: Bearer $SEMAPHORE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"template_id": 3}' \
https://semaphore.monsite.fr/api/project/1/tasks
Les bonnes pratiques
- Une base de données sauvegardée (PostgreSQL ou MySQL en production), et la clé de chiffrement sauvegardée à part.
- Semaphore derrière un reverse proxy en HTTPS, idéalement accessible seulement via VPN.
- Tous les secrets dans le Key Store, jamais dans le dépôt.
- Un projet par équipe, avec le minimum de droits : la plupart des utilisateurs n'ont besoin que du rôle « lanceur de tâches ».
- Une version d'image fixée, et une lecture des notes de version avant chaque mise à jour.
Tower ou Semaphore ?
- Semaphore si vous êtes une petite ou moyenne équipe, que vous voulez quelque chose qui tourne en dix minutes, et que vos besoins sont « lancer des playbooks en équipe avec un historique ».
- AWX / Ansible Automation Platform si vous avez besoin de workflows complexes avec approbations, d'inventaires dynamiques poussés, d'un RBAC très fin, ou d'un support éditeur.
À retenir
Semaphore, c'est Tower en version légère. Un projet, des clés dans le Key Store, un dépôt, un inventaire, et un modèle de tâche pour tout lancer. Avec l'historique, les planifications, les notifications et les droits en bonus, dans un seul conteneur.