Exploring the roots and future of Internet Relay Chat

ChatOps sur IRC : quand on déployait avant Slack

En 2012, GitHub a publié un talk qui a changé la façon dont les équipes techniques pensaient le déploiement. Jesse Newland expliquait comment GitHub déployait son code en production : quelqu'un tapait hubot deploy github to production dans un channel IRC, et le bot s'occupait du reste. Pas de SSH sur le serveur, pas de script lancé à la main, pas de "j'ai déployé, mais j'ai oublié de prévenir". Tout était visible, traçable, et collaboratif. Ils ont appelé ça le ChatOps. Mais pour ceux d'entre nous qui traînaient sur IRC depuis les années 1990, ce n'était que la formalisation d'une pratique qui existait déjà.

Les origines du ChatOps

L'idée de contrôler des systèmes depuis un client IRC n'est pas née en 2012. Dès la fin des années 1990, les administrateurs système qui passaient leur journée sur IRC avaient des bots qui remontaient des alertes dans les channels techniques. Un Nagios qui envoyait ses notifications dans #monitoring au lieu d'envoyer un mail que personne ne lisait. Un script qui affichait le résultat d'un df -h en réponse à !disk. C'était du ChatOps avant que le terme n'existe.

Ce que GitHub a fait en 2012, c'est systématiser l'approche. Au lieu de scripts bricolés, un framework. Au lieu de bots ad hoc, un bot extensible avec un écosystème de plugins. Au lieu de "quelques commandes utiles", une philosophie : tout ce qui peut être fait dans un terminal peut être fait dans le chat, et tout ce qui est fait dans le chat est vu par toute l'équipe.

J'ai adopté le ChatOps sur IRC en 2013 dans une équipe de six développeurs. Notre channel #ops sur un serveur IRC interne est devenu le centre névralgique de l'infrastructure. Les déploiements, les rollbacks, les checks de santé, les métriques — tout passait par là. Quand quelqu'un arrivait le matin, il scrollait le channel pour savoir ce qui s'était passé la nuit. C'était un journal d'opérations automatique, enrichi par les commentaires humains.

Hubot : le bot qui a lancé le mouvement

Hubot est un framework de bot écrit en CoffeeScript (puis JavaScript) par GitHub. Il est agnostique vis-à-vis du service de chat — des adaptateurs existent pour IRC, Slack, XMPP, et d'autres. L'adaptateur IRC utilise la bibliothèque node-irc.

# Installation de Hubot avec l'adaptateur IRC
npx yo hubot --adapter irc

# Configuration via variables d'environnement
export HUBOT_IRC_SERVER="irc.interne.example.com"
export HUBOT_IRC_PORT=6697
export HUBOT_IRC_ROOMS="#ops,#dev"
export HUBOT_IRC_NICK="hubot"
export HUBOT_IRC_USESASL=true
export HUBOT_IRC_SASL_USER="hubot"
export HUBOT_IRC_SASL_PASSWORD="motdepasse"
export HUBOT_IRC_USESSL=true

# Lancement
npx hubot --adapter irc

La force de Hubot, c'était son système de scripts. Un script Hubot est un fichier JavaScript ou CoffeeScript qui enregistre des patterns de messages et des fonctions de réponse. L'écosystème comptait des centaines de scripts communautaires :

// scripts/deploy.js
module.exports = function(robot) {
  robot.respond(/deploy (\S+) to (\S+)/i, function(msg) {
    var app = msg.match[1];
    var env = msg.match[2];
    var user = msg.message.user.name;

    msg.reply("Déploiement de " + app + " vers " + env + " lancé par " + user);

    // Appel à l'API de déploiement
    robot.http("https://deploy.internal/api/deploy")
      .header('Content-Type', 'application/json')
      .post(JSON.stringify({app: app, env: env, user: user}))(function(err, res, body) {
        if (err) {
          msg.reply("Erreur de déploiement : " + err);
        } else {
          msg.reply("Déploiement terminé : " + body);
        }
      });
  });

  robot.respond(/status (\S+)/i, function(msg) {
    var app = msg.match[1];
    robot.http("https://monitor.internal/api/status/" + app)
      .get()(function(err, res, body) {
        var data = JSON.parse(body);
        msg.reply(app + " — CPU: " + data.cpu + "%, RAM: " + data.ram + "MB, Uptime: " + data.uptime);
      });
  });
};

Dans le channel IRC, la conversation ressemblait à ça :

<marco> hubot deploy api-v2 to staging
<hubot> Déploiement de api-v2 vers staging lancé par marco
<hubot> Déploiement terminé : v2.4.1 déployé sur 3 instances
<laura> marco: tu peux checker les logs ? j'ai un doute sur la migration
<marco> hubot status api-v2
<hubot> api-v2 — CPU: 12%, RAM: 340MB, Uptime: 2m
<marco> laura: les métriques sont bonnes, je vérifie les logs
<marco> hubot logs api-v2 --lines 50
<hubot> https://logs.internal/api-v2/latest (50 dernières lignes)
Conseil : La valeur du ChatOps ne vient pas des commandes elles-mêmes — un script shell fait la même chose. Elle vient de la visibilité. Quand marco déploie depuis #ops, toute l'équipe le sait. Si quelque chose casse cinq minutes après, tout le monde sait quand et qui a déployé. Cette transparence passive évite 90% des "c'est pas moi qui ai touché au serveur".

Lita et les alternatives

Hubot n'était pas le seul framework de ChatOps. Lita, écrit en Ruby, offrait une alternative avec un système de plugins plus structuré et un support natif de Redis pour la persistance :

# Gemfile pour Lita avec adaptateur IRC
source "https://rubygems.org"

gem "lita"
gem "lita-irc"
gem "lita-deploy"       # Plugin de déploiement
gem "lita-jira"         # Intégration JIRA
gem "lita-pagerduty"    # Intégration PagerDuty
# lita_config.rb
Lita.configure do |config|
  config.robot.name = "lita"
  config.robot.adapter = :irc

  config.adapters.irc.server = "irc.interne.example.com"
  config.adapters.irc.channels = ["#ops", "#dev"]
  config.adapters.irc.user = "lita"
  config.adapters.irc.password = "motdepasse"
  config.adapters.irc.ssl = true

  config.redis[:host] = "127.0.0.1"
  config.redis[:port] = 6379
end

D'autres outils se sont ajoutés à l'écosystème au fil des ans. Errbot (Python), StackStorm (automation event-driven avec interface chat), et même des bots IRC custom en Go ou Rust. Chaque équipe choisissait le framework qui correspondait à son stack technique.

Déployer depuis IRC

Le déploiement depuis IRC suivait généralement un workflow en quatre étapes : vérification, déploiement, validation, notification.

# Workflow de déploiement typique en ChatOps

# 1. Vérification pré-déploiement
<marco> hubot can-deploy api-v2 to production
<hubot> ✓ Tests CI passés (build #1247)
<hubot> ✓ Staging OK depuis 2h
<hubot> ✓ Pas de deploy lock actif
<hubot> ✓ Dernière alerte PagerDuty : il y a 6 jours
<hubot> → Prêt pour le déploiement

# 2. Déploiement
<marco> hubot deploy api-v2 to production
<hubot> Déploiement de api-v2 v2.4.1 vers production...
<hubot> Instance prod-1 : mise à jour... OK
<hubot> Instance prod-2 : mise à jour... OK
<hubot> Instance prod-3 : mise à jour... OK

# 3. Validation
<hubot> Smoke tests : 12/12 passés
<hubot> Temps de réponse moyen : 45ms (baseline: 42ms)
<hubot> Taux d'erreur : 0.01% (baseline: 0.01%)

# 4. Notification
<hubot> Déploiement terminé. api-v2 v2.4.1 en production.
<hubot> Durée totale : 3m12s

Le "deploy lock" était un mécanisme pour empêcher deux déploiements simultanés. Quand quelqu'un lançait un déploiement, le bot verrouillait l'environnement. Si un autre membre de l'équipe essayait de déployer, le bot refusait avec le nom de la personne ayant verrouillé et depuis combien de temps.

Attention : Le ChatOps sur IRC supposait que le channel était sécurisé. Un channel IRC non chiffré, sur un serveur public, avec des commandes de déploiement en production — c'est un cauchemar de sécurité. Le ChatOps IRC fonctionnait parce que les équipes utilisaient des serveurs IRC internes, avec TLS, authentification SASL, et channels accessibles uniquement aux membres de l'équipe. Ne faites jamais de ChatOps sur un réseau IRC public.

Intégration CI/CD

Les systèmes d'intégration continue de l'époque — Jenkins, Travis CI, CircleCI — avaient tous des plugins ou des webhooks pour envoyer des notifications IRC. Le channel #builds recevait le résultat de chaque build en temps réel :

# Configuration Jenkins → IRC (via le plugin IRC)
# Dans Jenkinsfile
post {
    success {
        ircNotify(
            channel: '#builds',
            message: "${env.JOB_NAME} #${env.BUILD_NUMBER} : SUCCESS (${env.BUILD_URL})"
        )
    }
    failure {
        ircNotify(
            channel: '#builds',
            message: "${env.JOB_NAME} #${env.BUILD_NUMBER} : FAILURE (${env.BUILD_URL})",
            colorCode: '4'  // Rouge
        )
    }
}

# Alternative avec un webhook HTTP → IRC bridge
# Un petit serveur HTTP qui relaie les webhooks vers IRC
from flask import Flask, request
import socket

app = Flask(__name__)

@app.route('/webhook/build', methods=['POST'])
def build_webhook():
    data = request.json
    status = data.get('status', 'unknown')
    project = data.get('project', 'unknown')
    message = f"Build {project}: {status}"
    send_to_irc('#builds', message)
    return 'OK', 200

def send_to_irc(channel, message):
    # Connexion IRC simplifiée
    sock = socket.socket()
    sock.connect(('irc.interne.example.com', 6667))
    sock.send(f'NICK buildbot\r\n'.encode())
    sock.send(f'USER buildbot 0 * :Build Bot\r\n'.encode())
    # Attendre le 001...
    sock.send(f'PRIVMSG {channel} :{message}\r\n'.encode())
    sock.send(b'QUIT\r\n')
    sock.close()

L'intégration monitoring → IRC était tout aussi directe. Nagios, Zabbix, Prometheus (via Alertmanager) — tous pouvaient envoyer des alertes dans un channel IRC. Le channel #alerts devenait le tableau de bord temps réel de l'infrastructure. Pas d'interface web à ouvrir, pas de mail à chercher dans sa boîte. L'alerte arrivait là où l'équipe regardait déjà.

Pourquoi IRC était idéal pour le ChatOps

IRC avait plusieurs propriétés qui en faisaient un support naturel pour le ChatOps, et que Slack a ensuite dû recréer :

Le texte brut. Pas de formatage riche, pas de réactions emoji, pas de threads imbriqués. Un message est une ligne de texte. Les commandes sont des chaînes de caractères parsables. Un bot IRC n'a pas besoin de comprendre le markdown ou les blocs de code — tout est du texte plat.

Le protocole ouvert. Écrire un bot IRC prend 50 lignes de Python. Écrire un bot Slack nécessite une app OAuth, des scopes de permissions, un endpoint HTTP, et la gestion des tokens de rafraîchissement. La barrière d'entrée d'IRC était incomparablement plus basse.

L'auto-hébergement. Votre serveur IRC interne était sous votre contrôle total. Pas de dépendance à un service tiers, pas de risque que l'API change, pas de limite de rate-limiting imposée par un fournisseur. Quand Slack a commencé à restreindre son API gratuite, les équipes ChatOps sur IRC n'ont rien remarqué.

La légèreté. IRC consomme quelques Ko de bande passante par heure. Un client IRC tourne sur n'importe quelle machine. Pas de client Electron à 500 Mo de RAM. Pour les équipes d'ops qui gardaient un terminal ouvert sur un serveur de monitoring, IRC était juste un autre panneau de tmux.

La migration vers Slack, puis Teams, puis Discord, a dilué certaines de ces qualités. Mais le principe du ChatOps — rendre les opérations visibles et collaboratives via un canal de communication partagé — reste intact. Seul le transport a changé.

Questions fréquentes

Le ChatOps sur IRC est-il encore viable en 2024 ?

Techniquement, oui. Hubot supporte toujours l'adaptateur IRC. Ergo fournit un serveur IRC moderne facile à déployer. En pratique, la plupart des équipes ont migré vers Slack ou Mattermost. Si votre équipe est déjà sur IRC et que vous voulez du ChatOps, rien ne vous empêche de le faire. Mais si vous partez de zéro, Mattermost (auto-hébergé, open source) est un choix plus pragmatique.

Comment sécuriser un channel IRC de ChatOps ?

Utilisez un serveur IRC interne (pas un réseau public), activez le TLS, exigez l'authentification SASL, et configurez le channel en mode invite-only (+i) ou avec une clé (+k). Les commandes sensibles (déploiement production, accès base de données) doivent être restreintes à une liste d'utilisateurs authentifiés côté bot.

Hubot est-il toujours maintenu ?

Le développement de Hubot a ralenti après le rachat de GitHub par Microsoft. Le dépôt est en mode maintenance — les bugs critiques sont corrigés, mais peu de nouvelles fonctionnalités sont ajoutées. Pour de nouveaux projets, considérez Errbot (Python) ou un bot custom adapté à votre stack.