Les workflows disponibles sur Ansible Tower (depuis la version 3.1)
permettent aux utilisateurs de créer des séquences à partir de plusieurs
ressources Ansible : playbooks, synchronisation de projet, autres
workflows, approbations, …
Préparation d’un workflow Ansible AWX
Il faut avant créer un projet contenant tout ce qu’il faut pour construire
notre infrastructure. Je vous fournis un exemple qui permet de provisionner
une machine sur un cluster libvirt, de l’enregistrer dans un inventaire
(donc dynamique), de la tester, pour finir par la détruire.
Clonons le projet :
Construction de l’environnement d’exécution
Je vais bien sûr créer mon image d’environnement
d’exécution intégrant
tous les modules et les modules python nécessaires. L’environnement se trouve
dans le répertoire EE/terraform. Il contient un fichier de déclaration
d’environnement permettant de spécifier comment sera construite l’image :
un fichier execution-environment.yml
J’ai ajouté l’installation de terraform et la commande mkisofs. mkisofs
permet de créer les isos lors de la construction de la machine dans le cluster
libvirt.
un fichier requirements.txt
Nécessaire au fonctionnement du module Ansible terraform
un fichier requirements.yml
Je vais utiliser le module awx pour créer l’inventaire dynamique. J’ai dû
recourir à ce fonctionnement, car j’aurais pu utiliser l’inventaire terraform
mais un bug du provider libvirt empêche de récupérer l’IP de la VM
provisionnée.
Pour construire l’image et la pousser dans votre registry docker (changer le tag
):
Ecriture du Code Terraform
Je créé une machine virtuelle en utilisant un cluster
libvirt distant. Dans la partie provider je
déclare donc un uri qemu+ssh://root@devbox.robert.local/system qui utilise une
connexion ssh.
La VM est construire à partir d’une image Ubuntu téléchargé à la volée.
J’ai créé aussi une ressource cloud-init qui se charge de configurer la machine,
mais surtout d’installer les packages python3 et qemu-guest-agent. C’est lui
qui va permettre de récupérer l’adresse IP de la machine :
Pour la partie réseau, j’ai modifié l’interface réseau pour qu’elle utilise un
pont. Cela permet à ma VM d’être accessible depuis les autres machines de mon
réseau. Du coup l’adresse IP est géré par mon serveur DHCP.
Avec ces trois fichiers, on peut déjà créé la VM avec :
Construction des playbooks Ansible
Maintenant que ma VM se créé je vais pouvoir écrire les playbooks qui seront
utilisés dans le workflow :
Le premier terraform-deploy.yml :
Vous remarquez que j’ai inclus des variables dont une que j’ai encrypté avec la
commande ansible-vault. Il s’agit de la clé publique SSH permettant de me
connecter à mon cluster libvirt.
Comme tout se passe dans l’environnement d’exécution je reconstruis le
répertoire .ssh dans le container qui contient la clé publique et le fichier
known_hosts (sinon le provider libvirt se plante).
Ensuite je fais appel au module ansible terraform qui lance les deux phases
init et apply. Je finis par stocker le state terraform, pour le restaurer
lors de la destruction de la VM.
Le second playbook create-inventory.yml :
Ce playbook récupère l’adresse IP de la VM en utilisant virsh en mode commande :
virsh qemu-agent-command test '{"execute":"guest-network-get-interfaces"}'
Cela retourne un json dont j’extrais l’IP. Si vous lisez attentivement j’ai
ajouté la relance de cette tache jusqu’à ce qu’elle s’exécute avec succès (max
15 fois). Et ou le provisionnement n’est pas instantané.
Ensuite je fais appel au module awx.awx pour détruire l’ancien inventaire, le
recréer avec le host dont j’ai récupéré l’IP et l’ajouter au modèle de job
test-vm (comme il est détruit et recréé il n’a plus le même ID).
Le troisième playbook test.yml est un simple ping.
Le dernier terraform-destroy :
Ce playbook est identique à celui du deploy sauf bien sur le status du module
terraform qui est à absent. Comme cela tourne dans un container, il faut tout
reconstruire et récupérer le state terraform.
Construction des ressources AWX
Nous avons tout le code. Maintenant créons ce qu’il faut dans AWX pour en faire
un workflow. Pour cette partie je vous renvoie au billet sur les premiers pas
avec AWX, car cela ferait trop de copies d’écran.
Il faut créer les :
un environnement d'exécution pointant sur l’image qui a été poussé dans la
registry docker.
une ressource de type projet qui pointe sur le projet donné en exemple.
une ressource de type informations d'identifications :
un de type Vault contenant le mot de passe du vault
un de type Machine pour se connecter au cluster libvirt
un autre de type Machine pour se connecter à la VM provisionné
Une ressource de type inventaire pointant sur le cluster libvirt.
Des ressources de type Modèle de Job pointant sur les playbooks :
deploy-vm avec inventaire cluster libvirt avec la clé SSH et le mdp vault
dans les informations d’identifications
create-inventory comme le précédent
test-vm avec comme inventaire Test
destroy-vm configuré comme le deploy.
Construction du Workflow AWX
Maintenant que nous avons tout ce qu’il nous faut créons le Worflow.
Dans [Ressources / Modèles] Ajouter un modèle de flux de Travail
nom : le nom que vous voulez
inventaire : celui du cluster libvirt
Pour finir Cliquez sur [Enregistrer].
Cliquez désormais sur [Visualiseur]. C’est ici que l’on va dessiner le WorkFlow
:
En déplaçant la souris sur [Démarrer] vous devriez voir apparaitre un [+].
Cliquez dessus. Dans [type de Noeud] prenez Sync Projet et sélectionnez votre
projet.
De la même façon déplacer la souris au-dessus de la première étape et cliquez
sur [+]. Et là vous voyez apparaître des choix sur les conditions d’exécution de
ce job. Prenez [En cas de succès] puis [Suivant]. On va prendre un Type de Noeud
[Modèle de job] et le premier job est [deploy-vm].
Répétez l’opération jusqu’à obtenir ce workflow. Il est possible d’ajouter des
relations en cliquant sur les deux petits anneaux et en pointant sur le noeud
destinataire. Vous pourrez alors choisir le type de condition : [En cas d’échec]
(rouge) et [Toujours] (bleu).
Pour lancer le workflow il suffit de cliquer sur la petite fusée en haut à
droite de la partie visualizer.
Je dois encore corriger la partie ajout dans l’inventaire. Mais cela permet de
valider qu’en cas d’échec de ce playbook la vm est détruite. Cool
Conclusion
Les gros avantages que j’ai trouvés :
Cela permet de ne pas avoir besoin d’écrire de gros playbooks monolithiques.
Au lieu d’enchainer les rôles les uns derrières les autres on découpe en
tâches plus unitaires.
Prise en charge de l’état en échec à la sortie d’un job
Possiblité de mettre des approbations.
Cet exemple n’est pas parfait, mais j’espère que cela vous aura permis de voir
tout le potentiel de cet outil qu’est Ansible AWX. J’ai encore pas mal de
travail de découvertes à faire dessus.
Je me souviens des premières versions où je n’avais vu aucun bénéfice à son
utilisation. Ce n’est plus le cas désormais !!!