blue-green deployment ? Cela consiste à effectuer des montées de version en créant des VMs avec la nouvelle version de l’application, de faire une bascule sur le load-balancer avant de détruire les anciennes VMs. De qui se moque-t-on ?
Il faut bien se rendre à l’évidence pourtant. Cette approche est diablement efficace. Les tâches manuelles et fastidieuses se réduisent, une partie des loupés dûs à des configurations hétérogènes disparaissent. Du temps est gagné et il est possible de gérer de façon plus facile des centaines voire des milliers de machines. L’automate devient votre bras armé, c’est lui qui, par construction, effectue laborieusement toutes ces opérations répétitives que vous avez codées. Seul petit hic, quand vous lui demandez de faire une bêtise, il la fait avec obéissance, sur 1000 machines d’un coup...
Vient alors le moment des questions sur le sens de votre action :
Ces questions commencent à s’accumuler dans votre tête. Vous devenez propriétaire par la même occasion d’un petit patrimoine de code qui décrit votre infrastructure et qui commence à s’accumuler discrètement…
fix_mysql, version troisième âge :
# Édition du template Ansible de configuration de MySQL $ vim roles/mysql/templates/my.cnf # Édition du rôle Ansible MySQL $ vim roles/mysql/tasks/main.yml # Lancement en mode dry-run pour vérifier les changements à faire sur tous les serveurs de base de données de prod $ ansible-playbook -i inv/prod -l db-servers configure.yml --check --diff # Vrai lancement sur la plateforme sur tous les serveurs de base de données de prod $ ansible-playbook -i inv/prod -l db-servers configure.yml --diff -vvv # Oups, après une vérification manuelle, il faut repasser sur tous les serveurs pour corriger notre bêtise... $ vim roles/mysql/templates/my.cnf # Lancement sur la plateforme sur tous les serveurs de base de données de prod $ ansible-playbook -i inv/prod -l db-servers configure.yml --diff -vvv # Ouf, c’est réparé, personne n’a rien vu...
Dans cet exemple, un outil (Ansible, un choix parmi tant d’autres) permet de déployer un changement de configuration sur tous les serveurs de base de données. Comme il n’y a pas de garde-fou, si on fait une coquille, celle-ci se déploie sagement sur toutes les machines concernées. Reste alors à vite repasser derrière pour réparer…
#### Troisième âge : niveau de confort | |
#### Pourquoi ça marche<br><br>Comme avec les golden images : ce qui a fonctionné hier continuera de fonctionner demain.<br><br>Un rolling update revient à paramétrer des valeurs dans mon code.<br><br>Le code représente “la vérité” de ce qui est censé se passer en production, tout le monde peut s’y référer pour prendre une décision. | #### Pourquoi ça ne marche pas<br><br>Je n'écris pas de tests : j'ai du code mais je ne sais pas si il fonctionne à un instant T.<br><br>Je n'ai pas confiance dans l'idempotence de mon code et donc je ne peux pas l'appliquer en prod pour la réparer.<br><br>Je modifie à la main les machines dans le dos de mon automate et il casse tout en repassant |
Concernant la gestion du code que vous donnez à votre automate, une transformation s’opère et elle pourrait être la voie du salut. En allant voir ce qu’il se fait du côté des développeurs d’applications, vous vous rendez compte que c’est un nouveau monde parfois mal-connu qui s’ouvre à vous.
Et surtout cette fâcheuse manie de systématiquement écrire et exécuter des tests en automatique (et en continu) pour attraper toutes les erreurs (présentes ou futures sous forme de régressions) qui pourraient venir se cacher dans votre travail. Un rapide tour sur la toile montre qu’il existe pléthore de ces outils pour tester ses infrastructures (bats, serverspec, test-kitchen…).
Les développeurs ont donc mis au point tout un écosystème d’outils et de pratiques pour faire leur boulot.
En discutant avec eux, vous vous rendez compte qu’ils ont fait ça car ils aspirent à quelque chose qui résonne délicieusement en vous. Ils aiment faire du travail de qualité, rendre leur code beau, expressif, maintenable, bref, être aux petits soins avec lui… Ils ont même un terme pour ça : le software craftsmanship ou l’artisanat du logiciel.
Version quatrième âge de fix_mysql :
# Bascule sur la branche master pour récupérer la dernière version du code $ git checkout master # Mise à jour par rapport au référentiel $ git pull --rebase # Création d’une branche pour la correction $ git checkout -b amz # Recréation d’une plateforme de dev from scratch $ ansible-playbook -i inv/amz vm-reinit.yml # Lancement sur une plateforme de dev $ ansible-playbook -i inv/amz -l db-servers configure.yml --diff -vvv # Édition du test serverspec MySQL pour vérifier la nouvelle caractéristique attendue $ vim tests/spec/nodetypes/db/mysql_spec.rb # Vérification que le test est bien faux $ ENV=amz rake -f tests/Rakefile spec:mysql # Édition du template ansible de configuration de MySQL $ vim roles/mysql/templates/my.cnf.j2 # Édition du rôle Ansible MySQL $ vim roles/mysql/tasks/main.yml # Vérification de la syntaxe du rôle Ansible MySQL $ ansible-lint roles/mysql [ANSIBLE0012] Commands should not change things if nothing needs doing /home/amz/projets/trucs/infra-as-code/roles/mysql/tasks/main.yml:17 Task/Handler: Ch{mod,own} file # Oups, j’ai fait une coquille, ansible-lint l’a attrapé avant que je lance la commande $ vim roles/mysql/tasks/main.yml # Vérification de la syntaxe du rôle Ansible MySQL $ ansible-lint roles/mysql # Cette fois, c’est bon, lancement sur une plateforme de dev en dry-run $ ansible-playbook -i inv/amz -l db-servers configure.yml --check --diff # Lancement sur une plateforme de dev $ ansible-playbook -i inv/amz -l db-servers configure.yml --diff -vvv # Lancement des tests qui doivent passer au vert $ ENV=amz rake -f tests/Rakefile spec:mysql # Vérification des fichiers modifiés $ git status # Ajout des fichiers modifiés au prochain commit Git $ git add tests/spec/nodetypes/db/mysql_spec.rb roles/mysql/templates/my.cnf.j2 roles/mysql/tasks/main.yml # Commit git en référence au ticket $ git commit -m “#678 ajout de la gestion des key_buffer_size” # Pousse dans la branche pour faire une merge-request + pair review # La plateforme d’intégration continue se charge du reste $ git push origin amz # Purge de la plateforme temporaire de dev $ ansible-playbook -i inv/amz vm-destroy.yml
Dans cet exemple, l’écriture du code Ansible est étayée par un analyseur de bonnes pratiques de codage (ansible-lint) et des tests (en serverspec) qui sont écrits (si possible) avant l’implémentation. La capacité à disposer d’environnements jetables à la demande (via test-kitchen ou toute autre solution) permet de valider les changements sur un environnement anté-prod. La stratégie de branche et de code-review participe à la qualité et au partage du référentiel de code. C’est notamment l’occasion de faire relire le code et le paramétrage à un petit nouveau sur le projet ou un DBA qui vérifiera le paramétrage. Une plateforme d’intégration continue se charge de repasser tous les tests et un mécanisme de promotion (manuelle ou automatique) envoie les changements en production.
#### Quatrième âge : niveau de confort | |
#### Pourquoi ça marche<br><br>Il y a plusieurs niveaux de tests qui contribuent chacun à la qualité du code.<br><br>Je profite du versionning du SCM pour versionner toute mon infra. | #### Pourquoi ça ne marche pas<br><br>Non, stop, ça marche. |
L’outil de déploiement devient donc pour les sysadmins/devops une sorte de chien de berger. C’est finalement lui qui devient le nouvel animal de compagnie, celui dont vous avez besoin et dont vous prenez le plus grand soin. Celui dont chaque ligne de code est écrite avec amour, avec toute la qualité possible puisque c’est lui qui vous permet de manipuler un tel parcs de serveurs et d’applications.
La transformation du métier d’ops n’est finalement pas une remise en question des valeurs de ce métier. C’est plutôt un changement de l’objet de son attention. Au lieu de s’attacher aux machines, il s’agit de s’attacher à l’automate (et au code qui le pilote) qui les fait vivre, en conservant le même goût du travail bien fait, celui qui donne envie de se lever tous les matins.
Et demain ?
Vous êtes fiers de votre travail, pourtant déjà se présentent devant vous de nouveaux défis : cloud (IaaS, auto-scalling, PaaS), conteneurisation (Swarm, Kubernetes...), Clusters applicatifs (MongoDB, Cassandra, Kafka, Spark...)… La différence ? Des durée de vie des conteneurs encore plus courtes, un mécanisme de cluster qui participe à la vie du cheptel. Finalement, peu importe, vous avez mis en œuvre toutes les bonnes pratiques vous préparant aux changements (d’outils et de technologies).