Build d'images en parralèle avec Ansible
Un pattern devops très souvent utilisé et qui complète la formation Ansible: l’utilisation de Docker.
Lors des builds d’applications, il m’arrive parfois d’utiliser docker pour lancer plusieurs compilations en parallèle. Mais à chaque fois, je cherche comment bien paramétrer le module docker_container pour qu’ils lancent bien les containers et qu’Ansible attendent la fin du traitement pour passer à la suite.
Quel est le besoin ?
J’ai besoin de pouvoir lancer la compilation d’une même application pour différents clients et différents environnements. Chacun de ses cas possèdent son propre paramétrage et sa propre version à compiler.
Dans mon explication je n’utiliserai pas de cas concret, mais je vous expose simplement la solution que j’ai retenue. Donc tout est fictif, mais je l’ai déjà mis en oeuvre à plusieurs reprises.
Solution retenue
Je vais utiliser Ansible pour embarquer les paramétrages client et des environnements dans les inventaires. L’image du container doit prendre en entrée des arguments et partager un volume pour y déposer les artefacts.
Construction du container de build Docker
Il faut que ce container accepte en entrée plusieurs qui seront utilisé pour la compilation du programme. Il suffit d’ajouter des ARG comme ceci :
Vous avez remarqué :
- je n’indique pas de CMD car je vais le définir dans le playbook Ansible.
- derrière le git clone j’utilise en paramètre —branch la version à compiler.
- la clé de déploiement est passé en argument car elle sera stocké dans une variable masquée du ci-cd gitlab.
- je crée le répertoire /artefact pour y déposer le résultat de la compilation. Ce répertoire sera monté via un volume
Construction de l’inventaire Ansible
Je reprends la structure que je vous ai expliquée dans un précédent billet.
- Dans le groupe de variables all, je stocke les paramètres communs comme CLONE_TOKEN.
- Dans les autres groupes les valeurs propres à chaque client par exemple :
- CLIENT: client1
- VERSION: v0.0.1
- PARAM1: toto
- Dans hosts j’indique les machines cibles d’installation. Pour le développement j’utilise Vagrant pour simuler mon environnement décrit ci-dessous.
Ecriture du playbook
Le playbook :
- J’utilise les modules Ansible
docker_image
etdocker_container
mis à disposition par la communauté Ansible ↗ - Pour lancer les commandes en local, j’utilise delegate_to. Docker étant installé sur mon node Ansible.
- L’étape Build utilise args pour injecter les paramètres pour récupérer le bon repository avec la bonne version.
- L’étape Launch utilise :
- image: build:{{ VERSION }} pour indiquer l’image avec la bonne version
- volumes: le point de montage pour y déposer les artefacts
- command: la commande de compilation avec la création de l’artefact dans le volume
- env: les paramètres de compilation
- register: pour des besoins de debug
- Les paramètres super important :
- recreate: yes on détruit une précédente exécution
- state: started on indique bien started et pas juste present sinon la commande n’est pas lancée.
- detach: no on indique à Ansible d’attendre la fin de l’exécution.
- privileged: yes on peut en avoir besoin dans certains cas.
Lancement du tout
Très simple une simple commande ansible-playbook et on compile n versions en peu
de temps. Attention cela peut être très consommateur de ressources et c’est pour
cela que j’ai serial
en paramètre du playbook pour limiter le nombre de
compilations en parallèle.
Remarquez l’utilisation de l’indication du user vagrant pour lancer la compilation de votre environnement virtualisé avec vagrant. Dans votre Ci Gitlab, vous pourrez l’enlever ou le mettre en paramètre.
Voila, il s’agit ici d’un cas simple, mais avec Ansible, on peut vite trouver une solution pour gagner du temps sur le déploiement d’une application.
La suite de la formation Ansible dans de prochains billets.