n8n est un outil d’automation open-source, un mini ETL. Il est donc self-hostable et permet de déclencher des actions en low-code, des envois de notifications sur évenement tels que des crons.

Pour ma part, je l’utilise principalement pour faire du traitement sur flux RSS et m’envoyer une notification sur celles qui pourraient m’intéresser.

C’est devenu une solution commerciale tout en maintenant un tiers open-source sur le modèle de la licence Sustainable Use. Concrètement, cela signifie que certaines fonctionnalités ne seront pas accessible sur le tiers gratuit, dont la possibilité d’utiliser des variables globales dans un workflow.

C’est fort dommage lorsqu’on souhaite faire un workflow résiliant. Supposons un workflow qui se déclenche tous les jours pour extraire les éléments du jour et les envoyer sur Discord. La solution marche jusqu’à ce qu’elle ne marche plus, pour une raison X ou Y, et lorsque l’on a réparé le workflow, il n’y a aucun mécanisme de reprise pour les jours où le workflow n’a pas fonctionné. Pour corriger le tir, on utilise une variable pour stocker la date de dernière exécution, et la mettre à jour à chaque fois qu’un workflow réussit… mais pas dans la version gratuite.

En palliatif, et c’est la solution que je détaille ici, on peut utiliser une base de données externe de type KVP (Key-Value Pair). J’ai choisit Consul car même si ce n’est pas son usage principal, pouvoir interagir avec lui en HTTP est un énorme plus depuis n8n.

Poper une instance Consul fonctionnelle, quick and ugly

Je déconseille vivement de déployer Consul comme ce qui suit. La documentation de Consul est bien mieux faite. Là c’est plus pour voir l’interaction avec n8n.

Dans /srv/consul (ou peu importe là où vous aller stocker la stack), créée deux dossiers owné par 100:1000 avec le mode 0755:

  • config
  • data

Le fichier pour docker compose /srv/consul/compose.yaml :

services:
  consul:
    image: hashicorp/consul
    command: agent -config-file=/consul/config/consul.hcl -bootstrap-expect=1
    environment:
      TZ: Europe/Paris
    volumes:
      - ./config:/consul/config
      - ./data:/consul/data

Le routage avec Consul est fait avec Traefik, et la communication se fera sur le port HTTP non-SSL 8500. Cela n’apparaît pas sur ce compose.yaml.

Et enfin le fichier de configuration final de Consul /srv/consul/config/consul.hcl :

data_dir = "/consul/data"
log_level = "INFO"
node_name = "server-1"
server = true
encrypt = "tenXbvEhmkkkyh4J1ZtbkoJn+86o5OtTSShL2luQaRk="
bind_addr = "{{ GetInterfaceIP \"eth0\" }}"
ui_config {
    enabled = true
}

acl = {
    enabled = true
    default_policy = "deny"
    enable_token_persistence = true

    tokens {
        agent = "7a2a784a-cfdc-439c-bb7b-343dc990e59f"
    }
}
addresses {
    http = "0.0.0.0"
}

Pour obtenir une secret key pour le paramètre encrypt, exécutez simplement consul keygen.

Initialement vous devrez démarrer Consul avec le bloc acl suivant :

acl = {
    enabled = true
    default_policy = "allow"
    enable_token_persistence = true
}

Cela activera les ACL sur un fonctionnement “tout autorisé sauf”, puis suivre la documentation permettant d’activer les ACL.

Un workflow type

On suppose ici une instance Consul fonctionnelle et avec les ACL activées.

Prenons un workflow existant. On va le préfixer avec une action pour récupérer des variables depuis Consul, et suffixer avec une action pour mettre à jour ces variables. Le workflow ressemblera alors plus ou moins à ça :

Création d’un accès dans Consul

Il va falloir au préalable créer un token dans Consul avec les bons droits. Pour un workflow nommé gamepower, et pour garder les choses en ordre, ce token sera limité à lire et écrire sur le path n8n/gamepower dans le magasin de clé valeur (KV store). Cela simplémente en deux temps :

  • la création de la policy, qui décrit un ensemble d’accès
  • l’attachement de cette policy à token d’accès

Ci-dessous la policy en question :

key "n8n/gamerpower" {
	policy = "write"
}

J’ai nommé cette policy rw-kvp-n8n-gamerpower, toujours dans l’idée de m’y retrouver facilement dans les policies. Puis on crée un nouveau token Consul, sur lequel on attache cette policy.

Il restera ensuite à créer un credential dans n8n, de type Header Auth pour faire passer l’en-tête HTTP X-Consul-Token qui contiendra le token d’accès.

Récupération des variables depuis Consul

Le plus dur est fait, il reste maintenant à ajouter les deux opérations relatives à Consul dans le workflow, c’est-à-dire deux requêtes REST vu que Consul est API-first.

Pour récupérer les variables, qui sont stockées sous la forme d’un objet JSON, on fait un appel HTTP à http://consul:8500/v1/kv/n8n/gamerpower?raw=true

Le JSON récupérée étant vu par n8n comme un bête string, on va lui coller directement derrière une opération pour parser l’objet. Ca se fait avec un nœud de type “Edit field”.
On le paramètre le nœud en mode manuel, et on marque l’output du nœud précédent comme un objet.

Sauvegarde des variables dans Consul

Pour sauvegarder son état dans Consul, c’est la même chose que pour la récupération, mais avec un PUT : http://consul:8500/v1/kv/n8n/gamerpower

Dans le cas où le workflow se retrouve à traiter plusieurs items, on souhaitera que la mise à jour dans Consul ne s’exécute qu’une seule fois. Ca se fait dans l’onglet Settings en cochant “Execute once”

Source

https://developer.hashicorp.com/consul/docs/reference/agent/configuration-file/encryption#_encrypt