Puppet, gestion des environnements avec GIT
La mise en place des environnements dynamiques dans le précédent billet nous a permit de séparer efficacement les différentes configurations et de les charger intelligemment suivant la configuration des machines esclaves.
L'ensemble de cette configuration étant gérée par des fichiers de configurations prenant la forme de fichiers plats il peut être intéressant d'appliquer un gestionnaire de versions sur celles-ci pour suivre l'évolution des changements.
De plus, la séparation strictes des environnements dans des sous-dossier nous permet de créer un petit système de branches et de tirer pleinement partit des fonctionnalités offertes par le gestionnaire pour les manipuler.
Pour ce projet j'ai préféré utiliser GIT.
Concept général
Cinq serveurs (virtuels) m'ont été alloués pour mon déploiement :
- Un servant de Puppet Master
- Un serveur Web de test
- Un serveur MySQL de test
- Un serveur Web de production
- Un serveur MySQL de production
Vous l'avez peut être compris mais je vais ici déclarer deux environnements sur mon serveur maître, un de "test" et un de "production". Chaque environnement sera versionné dans une branche différente issue du même dépôt.
Le concept est donc de faire des changements dans l'environnement de test et de le déployer sur les deux serveurs configurés pour recevoir ces modifications. Une fois le tout stabilisé, cette configuration sera fusionnée avec la branche de production et sera ainsi déployée sur les serveurs de productions.
J'ai ici volontairement limité le nombre d'environnements pour simplifier l'exercice. Quatre environnements sont généralement déployés :
- devel : branche ou branches de développement actif
- test : branche où sont validés les configuration
- acceptance : où sera validé la configuration par le client
- production
Cette structure nous apporte plusieurs avantages :
- Le fait d'utiliser un gestionnaire de versions permet d'assurer un véritable suivit des configurations, l'introduction d'une erreur pourra être ainsi retracée facilement.
- Le bascule progressif des configurations entre les différents environnement permet la mise en place d'étapes de validations intermédiaires, si possibles appliqués par des entités différentes (automatisé par des scripts ou par une personne physique).
- D'un point de vue macroscopique chaque "client" aura son propre dépôt
- Si des personnes physiques valident chaque étapes elles sont rendu pleinement responsables des modifications acceptées. Ce système permet alors d'éviter qu'un "stagiaire travaille directement en production".
Déploiement de la solution
La configuration du Puppet Master restant identique, nous allons plutôt nous pencher sur la configuration des environnements. Dans le dossier environments nous créons deux sous dossiers, test et production.
edhelas@edhelas-laptop:/etc/puppet/environments# ls -lisah 276260 4.0K drwxr-xr-x 5 root root 4.0K Nov 6 15:40 production 262146 4.0K drwxr-xr-x 5 root root 4.0K Nov 6 16:50 test
J'ai ici choisit de faire de production une sous branche de test. Commençons donc par créer notre environnement de test.
# cd test # mkdir manifests modules # cd manifests # touch nodes.pp site.pp
Le fichier site.pp restera vide pour notre exemple, nous allons déclarer notre configuration dans nodes.pp.
node basenode { # configuration commune à tous les nœuds } node 'web01-test', 'web01-prod' inherits basenode { include apache } node 'mysql01-test', 'mysql01-prod' inherits basenode { include mysql::server }
Ici nous déclarons que nos deux serveurs web chargerons posséderons un serveur apache, de même pour nos serveurs de base de donnée avec un serveur MySQL. N'oubliez pas d'installer au préalable les modules Puppet adéquats.
# puppet module install puppetlabs-mysql # puppet module install puppetlabs-apache
Même si nous déclarons les quatre serveurs dans notre fichier nodes.pp, seul deux d'entre eux seront affectés par celle-ci car le fichier se situe dans l'environnement test. Pourquoi avoir déclaré les quatre serveurs alors ? Car lors de la fusion de la branche de test avec celle de production aucune modification à l'intérieur des fichiers ne doit être faite.
Une fois notre configuration déclarée il ne nous reste plus qu'à la versionner le tout.
# cd environments/test/ # git init # git add manifests/ # git commit -a -m "First commit" # git push
Puis nous allons dans l'environnement de production et récupérons le code.
# git pull # git branch production # git checkout production
Le code que nous avons créé sera maintenant disponible dans les deux environnements.
Déploiement d'un nouveau changement
Maintenant que nos environnements sont disponibles tentons de voir ce qui se passe réellement lors de l'introduction d'une modification.
# cd environments/test/ # nano manifests/nodes.pp # git commit -a -m "Modifications importantes" # git push
Notre modification a été versionnée et se trouve sur la branche master de GIT. Nous pouvons alors demander à la personne en charge de l'environnement de production de vérifier et fusionner notre code.
# cd dossier_de_merge/ # git checkout master # git pull
On récupère notre modification, puis nous basculons sur la branche de production.
# git checkout production # git merge master
Les modifications seront alors fusionnées avec la branche de production. Il ne nous reste plus qu'à envoyer notre code sur le serveur puis de tirer la mise à jour dans l'environnement de production.
# git push # cd environments/production/ # git pull
Cette petite méthodologie amène de la rigueur dans l'évolution de vos configuration sur vos serveurs et si elle ne vous permet pas d'éviter le pire, vous saurez si qui taper si quelque chose est cassé en production :)