🇫🇷N8n pour déployer des environnements OpenVSCode Server à la demande sur Clever Cloud

Frederic AlixFrederic Alix
8 min read

Présentation

Connaissez-vous OpenVSCode Server ? OpenVSCode Server est un projet open-source qui permet de déployer un environnement de développement Visual Studio Code (VSCode) sur un serveur distant. Il offre une expérience similaire à celle de VSCode en local, mais avec l'avantage de pouvoir accéder à votre environnement de développement depuis n'importe quel navigateur web. Cela facilite la collaboration, l'accès aux ressources cloud et la configuration d'environnements de développement homogènes pour les équipes.

Le projet OpenVSCode Server est maintenu par Gitpod, une entreprise qui fournit des environnements de développement basés sur le cloud. Gitpod a développé OpenVSCode Server pour étendre les fonctionnalités de Visual Studio Code et offrir aux développeurs une expérience de développement en ligne plus riche et plus accessible.

OpenVSCode Server prend en charge les extensions et les fonctionnalités principales de VSCode. Il se déploie facilement sur la plateforme de Clever Cloud, mais je souhaite pouvoir en créer et supprimer de façon automatisée. Dans cet article, je vais détailler une solution pour répondre à mes besoins en utilisant le moteur de workflow n8n. Petit rappel, n8n est un logiciel qui permet d'automatiser des tâches sous forme de workflow.

Notre feuille de route

Dans un premier temps, nous allons déployer une instance n8n sur Clever Cloud.
n8n sera utilisé afin de créer de futures instances OpenVSCode Server qui seront hébergées chez notre fournisseur cloud favori.
Nous aurons donc besoin d'installer l'outil clever-tools dans cette instance afin de permettre à n8n de déployer des conteneurs chez Clever Cloud.
Ensuite, nous allons créer un workflow dans n8n qui se chargera de créer et de supprimer une instance OpenVSCode Server.

Installation de n8n

PreRequis

clever-tools

Assurez-vous d'avoir installé clever-tools sur votre workstation: Doc

Il est important d'avoir déjà paramétré le CLI de Clever afin de récupérer le token et le secret. Nous verrons plus loin, que c'est n8n qui se chargera de créer des instances Docker sur la plateforme de Clever Cloud. Il utilisera la commande clever et aura besoin d'un fichier de configuration incluant votre token et un secret. Donc, si vous n'avez jamais encore utilisé ce CLI, lancez la commande suivante et suivez les instructions :

clever login

Création du fichier package.json, du script run.sh et copie du répertoire clever-cloud

mkdir /var/tmp/n8n
cd /var/tmp/n8n
cp -rp ~/.config/clever-cloud ./
git init

Créez le fichier package.json

{
  "name": "n8n",
  "version": "0.221.1",
  "engines": {
    "node": "16.9"
 },
  "dependencies": {
    "n8n": "0.221.1"
  }
}

Créez le fichier run.sh

#!/bin/bash
set -x
./node_modules/.bin/n8n start

Ajoutez les trois fichiers au repository git

chmod a+x run.sh
git add package.json run.sh clever-cloud
git commit -m "Init n8n launch"

Création de l'instance

clever create cc-n8n --type node --org <YOUR_ORGA_ID> --region par
clever config update --enable-force-https
clever scale --alias cc-n8n --flavor XS
clever scale --alias cc-n8n --build-flavor S
clever addon create postgresql-addon cc-n8n-db --link cc-n8n --org <YOUR_ORGA_ID> --region par --plan xs_sml --yes
clever addon create fs-bucket n8n-fs-data --plan s --link cc-n8n --org <YOUR_ORGA_ID> --region par --yes
clever env set PORT 8080
clever env set N8N_VERSION 0.221.1
clever env set N8N_PORT `clever env | grep -w PORT| awk -F = '/PORT/ { print $2}'|sed s/\"//g`
clever env set N8N_PROTOCOL https
clever env set N8N_HOST `clever domain|awk '{print $1}'`
clever env set WEBHOOK_TUNNEL_URL "https://`clever domain|awk '{print $1}'`/"
clever env set VUE_APP_URL_BASE_APP "https://`clever domain|awk '{print $1}'`/"
clever env set EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS true
clever env set EXECUTIONS_DATA_SAVE_ON_ERROR all
clever env set N8N_USER_FOLDER /app/n8n-data/
clever env set DB_TYPE postgresdb
clever env set DB_POSTGRESDB_DATABASE `clever env | awk -F = '/POSTGRESQL_ADDON_DB/ { print $2}'|sed s/\"//g`
clever env set DB_POSTGRESDB_HOST `clever env | awk -F = '/POSTGRESQL_ADDON_HOST/ { print $2}'|sed s/\"//g`
clever env set DB_POSTGRESDB_PORT `clever env | awk -F = '/POSTGRESQL_ADDON_PORT/ { print $2}'|sed s/\"//g`
clever env set DB_POSTGRESDB_USER `clever env | awk -F = '/POSTGRESQL_ADDON_USER/ { print $2}'|sed s/\"//g`
clever env set DB_POSTGRESDB_PASSWORD `clever env | awk -F = '/POSTGRESQL_ADDON_PASSWORD/ { print $2}'|sed s/\"//g`
clever env set GENERIC_TIMEZONE "Europe/Paris"
clever env set CC_FS_BUCKET /n8n-data:`clever env | awk -F = '/BUCKET_HOST/ { print $2}'|sed s/\"//g`
clever env set CC_PRE_RUN_HOOK "cp -rp clever-cloud ~/.config/"
clever env set CC_RUN_COMMAND "./run.sh"

Lancement de l'application

Lancez la commande de déploiement:

clever deploy

Connectez-vous sur l'interface de n8n. Pour afficher l'URL de votre instance, tapez la commande : clever domain

Créez votre compte n8n et vous devriez arriver sur cet écran:

OpenVSCode Server

Création du Dockerfile

Nous allons créer un modèle de fichier Dockerfile qui sera utilisé par n8n pour créer une instance OpenVSCode Server sur la plateforme de Clever Cloud.

Connectez-vous en SSH sur l'instance n8n:

cd /var/tmp/n8n
clever ssh

Maintenant, nous allons créer un répertoire modèle sur le fs-bucket de n8n et écrire un fichier Dockerfile.

####### LES COMMANDES SUIVANTES SE FONT SUR L'INSTANCE N8N SE TROUVANT CHEZ CLEVER CLOUD ######

cd /app/n8n-data/
mkdir modele
cd modele

Créez le fichier Dockerfile:

Déconnectez vous de votre session ssh:

logout

Création du workflow n8n

Nous allons créer, sur votre poste de travail, un fichier JSON qui nous permettra d'importer un workflow dans n8n. Ce dernier inclut l'ensemble des tâches pour créer une instance OpenVSCode à la demande sur la plateforme de Clever Cloud.

Création du fichier openvscodeserver.json

Avec l'aide de votre éditeur de code favori (vim power !!! \o/ ), créez le fichier openvscodeserver.json

{
  "name": "OpenVSCode Server",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "da4da152-c7ac-40a5-9743-9362d9d05d94",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "3d011ea4-8a5a-463c-bd1f-7350fdc9378c",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        460,
        460
      ],
      "webhookId": "da4da152-c7ac-40a5-9743-9362d9d05d94"
    },
    {
      "parameters": {
        "command": "=#!/bin/bash\ncd /app/n8n-data\ncp -rp modele {{ $json.body.login }}\ncd {{ $json.body.login }}\nclever create --type docker --org {{ $json.body.clever_orga }} --alias ovscodesrv-{{ $json.body.login }} --region par ovscodesrv-cc-{{ $json.body.login }}\nclever config update --enable-sticky-sessions --enable-force-https --enable-zero-downtime\nclever scale --flavor M\nclever env set CC_MOUNT_DOCKER_SOCKET true\nclever env set VSCODE_TOKEN {{ $json.body.password }}\nclever env set LOGIN {{ $json.body.login }}\nclever env set USERNAME {{ $json.body.login }}"
      },
      "id": "a08b2d77-4e07-42be-b10c-02cc485f5b9e",
      "name": "Creation instance",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        680,
        460
      ]
    },
    {
      "parameters": {
        "command": "=cd /app/n8n-data/{{ $node.Webhook.json.body.login }}\nclever domain\n"
      },
      "id": "3828321b-37e8-43fa-ad78-fb3830765054",
      "name": "Extraction url",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        900,
        460
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={\n\"url_ovscodesrv\":\"https://{{ $json[\"stdout\"] }}/?tkn={{ $node[\"Webhook\"].json[\"body\"][\"password\"] }}\"\n}",
        "options": {}
      },
      "id": "8ad06f65-5e6d-4941-b7dd-65a6e526f4a5",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        1120,
        460
      ]
    },
    {
      "parameters": {
        "command": "=cd /app/n8n-data/{{ $node[\"Webhook\"].json[\"body\"][\"login\"] }}\ngit init\ngit add Dockerfile\ngit config user.email \"unemail@monemail.com\"\ngit config --global user.name \"monuser\"\ngit commit -m \"deploy ovscodesrv\"\nclever deploy\nexit 0\n\n"
      },
      "id": "42d6b120-6e58-4526-8bdb-ebbb62cb4316",
      "name": "Execute Command",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        1340,
        460
      ]
    },
    {
      "parameters": {
        "httpMethod": "DELETE",
        "path": "8de6a9be-f70b-42bb-86a2-77d8ab1e6b1e",
        "responseCode": 204,
        "options": {}
      },
      "id": "74ca1221-3a06-4b2f-975d-37680ec9e1af",
      "name": "Webhook delete",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        460,
        680
      ],
      "webhookId": "8de6a9be-f70b-42bb-86a2-77d8ab1e6b1e"
    },
    {
      "parameters": {
        "command": "=cd /app/n8n-data/{{ $json[\"query\"][\"login\"] }}\nclever delete --yes\nwait 2\ncd ..\nrm -r {{ $json[\"query\"][\"login\"] }}\n\n\n\n"
      },
      "id": "5570025c-5051-41eb-bab2-a26c8f162c9e",
      "name": "Delete instance",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        680,
        680
      ]
    }
  ],
  "pinData": {},
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Creation instance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Creation instance": {
      "main": [
        [
          {
            "node": "Extraction url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extraction url": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Respond to Webhook": {
      "main": [
        [
          {
            "node": "Execute Command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook delete": {
      "main": [
        [
          {
            "node": "Delete instance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {},
  "versionId": "aa2ed598-e1fd-40c0-ba05-d4886e9f2a0d",
  "id": "1",
  "meta": {
    "instanceId": "faba38ba469281b3fa19b6c786fb85738c25cc6e23bb4c11bb541576dd1813f6"
  },
  "tags": []
}

Import du workflow dans n8n

Connectez-vous sur votre interface n8n et importez le workflow:

Cliquez sur le bouton "Active" afin d'activer ce workflow dans n8n

Il ne nous reste plus qu'à tester l'ensemble. Avant cela, vous aurez besoin de l'URL du webhook permettant de créer une instance. Pour obtenir l'URL, double-cliquez sur le nœud webhook et copiez l'URL :

En avant la musique !

Création d'une instance OpenVSCode Server

Il ne nous reste plus qu'a créer une instance OpenVSCode Server en faisant appel à notre webhook.
Nous allons utiliser curl avec quelques paramètres :

loginchoisissez un login systeme
passwordindiquez un mot de passe
clever_orgaindiquez l'organisation id clever cloud où vous souhaitez lancer l'instance OpenVSCode Server

N'oubliez pas de remplacer l'URL par celle que vous avez récupérée à l'étape précédente.

curl -X POST -H "Content-Type: application/json" -d '{"login":"cowboycaramel","password":"unBoMcstnDlpdfEn2023","clever_orga":"orga_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}' https://app-059e4678-0765-4da9-9ebf-aac2bdc96bb2.cleverapps.io/webhook/da4da152-c7ac-40a5-9743-9362d9d05d94|jq

Quelques secondes après avoir lancé la commande, le retour de celle-ci vous fournira l'URL de connexion.:

En général, le temps de création ne devrait pas dépasser 1 minutes 20.
Dans l'onglet Executions, vous trouverez un rapport d'éxectution:

Maintenant, utilisons l'url dans un navigateur web retourné par curl:

Vous pouvez désormais créer autant d'instances que vous le souhaitez. Pensez à modifier le login dans la commande curl. Il est possible d'améliorer le workflow pour vérifier qu'une instance du même nom n'existe pas déjà, mais cela ne rentre pas dans le cadre de cet article qui n'est qu'une introduction aux nombreuses possibilités offertes par la combinaison de n8n et Clever Cloud.

Suppression d'une instance OpenVSCode Server

Comme pour la création d'une instance OpenVSCode Server, nous avons besoin de l'URL du webhook de suppression. Comme vu précédemment, double-cliquez dessus et copiez l'URL. Ajoutez à la fin de cette dernière, le paramètre login=<login_de_l_instance>.

Par exemple, si l'URL de mon webhook de suppression est https://app-059e4678-0765-4da9-9ebf-aac2bdc96bb2.cleverapps.io/webhook/8de6a9be-f70b-42bb-86a2-77d8ab1e6b1e et que le login de mon instance est cowboycaramel, cela donnera la commande curl suivante :

curl -X DELETE "https://app-059e4678-0765-4da9-9ebf-aac2bdc96bb2.cleverapps.io/webhook/8de6a9be-f70b-42bb-86a2-77d8ab1e6b1e/?login=cowboycaramel"

Après quelques seconde, l'instance cowboycaramel sera détruite.

Conclusion

J'espère que cet article vous aura plu et, pourquoi pas, donné des idées pour vos futurs projets.
Si vous cherchez une expertise sur les environnements de Clever Cloud, n'hésitez pas à m'écrire à frederic.alix@pancasat.com.

0
Subscribe to my newsletter

Read articles from Frederic Alix directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Frederic Alix
Frederic Alix

Depuis l'âge tendre de six ans, l'informatique a été mon terrain de jeu et, plus tard, elle est devenue ma vocation professionnelle pour plus de 25 ans maintenant. Mon intérêt s'est toujours porté sur le fascinant monde des serveurs informatiques, ce qui m'a amené à déployer des infrastructures robustes pour des entités renommées telles qu'EDF, RTL, RTL2, FunRadio, Axa, Orange, et SFR, parmi tant d'autres. Ma passion réside dans l'optimisation des systèmes Linux et le déploiement d'applications web en Java, Node.js, Go, et au-delà. La supervision des systèmes et des applications occupe également une place spéciale dans mon cœur professionnel, ajoutant une couche supplémentaire de satisfaction à mon quotidien déjà loin de l'ennui. En dehors de mon amour pour la technologie, je suis un fervent lecteur de littérature science-fiction et fantastique. Le cinéma et la musique sont mes compagnons fidèles dans la quête de l'évasion et de l'inspiration. J'apprécie les plaisirs simples de la vie et je chéris chaque opportunité de rencontrer de nouvelles personnes, élargissant ainsi mon cercle d'amis et enrichissant mon parcours de vie avec des échanges enrichissants. Avec chaque projet et chaque interaction, je continue à apprendre et à grandir, cherchant toujours à contribuer et à innover dans l'espace technologique, tout en appréciant les belles nuances de la vie.