Découper la configuration d'Haproxy en plusieurs fichiers
Rédigé par Marc GUILLAUME | 1 commentaireTraduction (avec quelques adaptations) de : https://lazic.info/josip/post/splitting-haproxy-config/
Dès que vous avez plus d'un frontend, un backend et des directives d'écoute dans votre configuration HAProxy, vous vous retrouvez encombré avec son seul fichier monolithique. Il y a peu de solutions possibles à ce « problème », il existait cette solution python (plus en ligne), ou peut-être l'utilisation de plusieurs fichiers de configuration et leur spécification avec -f au démarrage d'haproxy (voirl la page man haproxy).
Bien qu'il n'y ait rien à redire à la solution ci-dessus, je pense qu'existe une meilleure approche avec un script qui vérifierait si la nouvelle configuration est valide avant de redémarrer HAProxy. Le script ci-dessous suppose que vous avez colordiff, et etckeeper installés et configurés. Si ce n'est pas le cas, vous devriez penser à le faire et utiliser etckeeper, cela pourra vous éviter bien des problèmes lorsque vous devrez annuler certains changements dans le répertoire /etc
.
Commencez par créer le répertoire /etc/haproxy/conf.d/
et divisez votre fichier haproxy.cfg en plusieurs fichiers préfixés par des chiffres dans l'ordre dans lequel vous souhaitez les voir apparaître dans la configuration finale.
Par exemple dans un fichier 00-global.cfg mettez les options globales que vous souhaitez voir apparaître tout en haut du fichier, et dans 99-global.cfg mettez tout ce que vous voulez voir à la toute fin du fichier de configuration final de HAProxy. Ensuite vous pouvez créer des fichiers de site, de ssl, ou de backend etc.
Si vous avez besoin de désactiver un de ces fichiers, par exemple 11-site1.cfg, renommez-le simplement en 11-site1.cfg.disabled, il ne sera plus pris en compte par le script. Il ne vous reste plus qu'à lancer le script ci-dessous dont l'original se trouve ici : https://gist.github.com/jlazic/e65f5bda141ffaed5640.
J'ai légèrement modifé le script original, notamment le test d'identité des fichiers et appelé directement colordiff qui renvoit 1 quand il y a des différences et 0 quand les fichiers sont identiques alors que si l'on pipe vers colordiff on obtient toujours 0 en valeur de sortie. Le test devait être soit :
if [ $? -ne 1 ]; then
ou bien
if [ $? -eq 0 ]; then
J'ai choisi le première solution.
J'ai également placé la mise à jour dans une fonction et rajouté la possibilité de passer un paramètre. Le script peut ainsi soit, par défaut comme l'original, être interactif et demander une validation de l'utilisateur, soit avec l'option -a effectuer la mise à jour automatiquement pour pouvoir l'utiliser via un autre script. La fonction permet de factoriser le code de mise à jour qui est le même que l'on valide en automatique ou via confirmation.
Il va recomposer un fichier haproxy.cfg à partir des divers fichiers actifs dans l'ordre de leurs numéros, voir si les fichiers sont différents et si ils le sont tester la syntaxe de ce fichier puis, si tout est bon demander de remplacer l'actuel fichier de configuration par ce nouveau fichier, faire un commit dans git, puis recharger haproxy. Le script figure ci-dessous.
#!/bin/bash #Requirements: etckeeper, diffcolor # script origin : https://lazic.info/josip/post/splitting-haproxy-config/ # 10 April 2020 : some modifications by Marc marc[at]yakati.com #This script concatenates multiple files of haproxy configuration into #one file, and than checks if monolithic config contains errors. If everything is #OK with new config script will write new config to ${currentcfg} and reload haproxy #Also, script will commit changes to etckeeper, if you don't use etckeeper you #should start using it. #Script assumes following directory structure: #/etc/haproxy/conf.d/ #├── 00-global.cfg #├── 15-lazic.cfg #├── 16-togs.cfg #├── 17-svartberg.cfg #├── 18-home1.cfg.disabled #└── 99-globalend.cfg #Every site has it's own file, so you can disable site by changing #it's file extension, or appending .disabled, like I do. currentcfg=/etc/haproxy/haproxy.cfg newcfg=/tmp/haproxy.cfg.tmp configdir=/etc/haproxy/conf.d timestamp=$(date "+%F %T") noninteractive='false' # If option -a if [ "$1" = -a ]; then noninteractive='true'; fi ###~~~~~~~~~~~~~~ # Update function # UpdateConfig() { printf "%s\n" " " printf "%s\n" "Working..." cat /etc/haproxy/conf.d/*.cfg > ${currentcfg} if [ "$?" -eq "0" ]; then printf "\t%s\n" "* Updating haproxy configuration"; else printf "\t%s\n" "* /!\WARNING : a problem occured updating haproxy configuration"; exit 1; fi printf "%s\n" "Running etckeeper..." etckeeper commit -m "${timestamp} Updating haproxy configuration" printf "%s\n" "Reloading haproxy..." service haproxy reload if [ "$?" -eq "0" ]; then printf "\t%s\n" "* Haproxy reloaded"; else printf "\t%s\n" " */!\WARNING : a problem occured reloading haproxy"; exit 1; fi } printf "%s\n" "Compiling *.cfg files from ${configdir}" ls ${configdir}/*.cfg cat ${configdir}/*.cfg > ${newcfg} printf "%s\n" "Differences between current and new config" colordiff -s -U 3 ${currentcfg} ${newcfg} if [ $? -ne 1 ]; then printf "%s\n" "You should make some changes first :)" rm -f ${newcfg} exit 1 #Exit if old and new configuration are the same fi printf "%s\n" "Checking if new config is valid..." haproxy -c -f ${newcfg} if [ $? -eq 0 ]; then printf "\t%s\n" "Check if there are some warnings in new configuration." if [ "${noninteractive}" != 'true' ]; then read -p "Should I copy new configuration to ${currentcfg} and reload haproxy? [y/N]" -n 1 -r if [[ $REPLY =~ ^[Yy]$ ]]; then UpdateConfig rm -f ${newcfg} exit 0 fi else UpdateConfig rm -f ${newcfg} exit 0 fi else printf "%s\n" "There are errors in new configuration, please fix them and try again." rm -f ${newcfg} exit 1 fi