[FRsAG] Pb de vars ansible

Faustin Lammler faustin at fala.red
Ven 27 Nov 12:16:10 CET 2020


Bonjour,
ça fait un moment que je travaille avec des outils de gestion de
déploiement et de gestion de configuration (puppet, saltstack et
maintenant ansible).

Mon expérience est que quand ça devient trop compliqué, l'approche est
souvent mauvaise (c'est d'ailleurs souvent vrai pour d'autres aspects de
l'informatique).

Voici quelques recommandations que j'essaie de garder en tête au moment
de développer des nouveaux rôles/tasks, peut-être qu'elles pourront te
servir :
- éviter au maximum de mettre de l'intelligence dans des rôles (sinon ça
  devient rapidement plus portable et c'est le début de la complexité
  inutile).
- privilégier le plus possible une approche descriptive de l'infra (dans
  group_vars/host_vars), cela simplifie énormément les développements et
  la lisibilité des rôles. Pourquoi vouloir détecter des IP qui ne
  changent pas ?
- utiliser le plus possible des variables raw, ça permet de simplifier
  drastiquement les templates ;
- essayer d'éviter les `| default("")` et passer par `defaults/main.yml`
  pour documenter la valeur par défaut des variables (et documenter le
  rôle finalement).

En ce qui concerne Ansible, son problème principal selon moi c'est sa
première qualité. C'est extrêmement facile à utiliser (notamment, car il
est agentless et n'a besoin que d'une connexion SSH). Du coup on se
lance tête baissée dans des déploiements/développements sans commencer
par structurer les choses proprement.

En ce qui concerne l'utilisation du `--check`, c'est évidemment très bien
mais je t'invite à regarder le projet molecule qui permet de tester
rapidement et proprement les rôles, ça fait gagner un temps fou pendant
la phase de développement (même si le setup est un peu plus long).

Si tu lis l'anglais, je te conseille ce livre (et les productions
en général de son auteur) : https://www.ansiblefordevops.com/

Finalement, voici un rôle que j'ai développé qui illustre ce qui me
semble être des bonnes pratiques pour ansible (il n'est surement pas
parfait mais je crois qu'il est assez simple à lire). Ce rôle contient
également les mécanismes de tests molecule dont je parle plus haut.
https://github.com/fauust/ansible-role-mariadb

Mes 2 centimes.

Faustin

PS : pour ceux qui trouvent ansible un peu long (et quand on vient de
saltstack, on pleure), je vous recommande d'essayer mitogen
(https://mitogen.networkgenomics.com/ansible_detailed.html), le gain en
performance est assez bluffant.

Daniel Caillibaud <ml at lairdutemps.org>,
27/11/2020 – 03:51:43 (+0100):

> Le 26/11/20 à 19h28, Jean-Yves LENHOF <jean-yves at lenhof.eu.org> a écrit :
> 
> > Hello,
> > 
> > Tu mets du code (petit certes, mais du code) dans des champs qui ne 
> > contiennent que des variables.... moi j'éviterais, je ne le fais 
> > qu'uniquement lorsque je veux positionner deux variables avec la même 
> > valeur avec une sorte de variable bidon technique.
> 
> Ok, tu veux dire que je devrais pas mettre de logique dans mon
> group_vars/all.yaml ?
> 
> > Pour moi tu présuppose que ta variable ansible_all_ipv4_addresses 
> > contient au moins une ip publique et du coup prendre la première même 
> > s'il n'y en a pas
> 
> Ben, en fait en mettant dans group_vars/all.yaml
>   ipv4_private: "{{ ansible_all_ipv4_addresses | ipaddr('private') | first | mandatory }}"
>   ipv4_public: "{{ ansible_all_ipv4_addresses | ipaddr('public') | first }}"
> 
> Je voulais
> - que ça plante si y'a pas d'ip privée (car ça devrait jamais arriver, 
>   pas la peine d'aller plus loin dans ce cas)
> - que ipv4_public soit initialisé avec la 1re ip publique si y'en a une, 
>   et undefined sinon
> pour n'importe quel playbook qui pourrait être lancé.
> 
> > J'essayerais avec le module set_fact
> 
> Ok, mais lui je dois le mettre dans une task, ce qui m'intéressait c'était 
> d'initialiser mes variables avant la 1re task, quel que soit le playbook
> 
> Comment je pourrais utiliser un set_fact avant toute tâche ?
> 
> 
> En tout cas tu as raison, c'est le |first sur un truc inexistant qui lui plaît
> pas, mais pas au moment de l'évaluer, juste lorsqu'il traite ce résultat.
> J'avais pas compris ça dans le message d'erreur, car le message sort après le
> print ok de l'ip privée, je pensais donc que mes définitions avaient déjà été
> évaluées et ne lui avait pas posé pb.
> 
> Si je remplace dans mes vars mon
>   ipv4_public: "{{ ansible_all_ipv4_addresses | ipaddr('public') | first }}"
> par
>   ipv4_public: "{{ ansible_all_ipv4_addresses | ipaddr('public') | default([]) | first | default('') }}"
> ou même
>   ipv4_public: "{{ ansible_all_ipv4_addresses | ipaddr('public') | first | default('') }}"
> 
> et ensuite dans les tasks le
>   when: ipv4_public is defined
> par
>   when: ipv4_public is defined and ipv4_public | bool
> ou
>   when: ipv4_public | bool
> 
> ça semble fonctionner comme je voulais.
> 
> Le "is defined" est superflu, car maintenant c'est toujours defined
> (éventuellement vide), j'hésite à le laisser au cas où la définition des 
> variables changerait, c'est probablement idiot (pas la peine de laisser 
> le choix, autant planter tout de suite si la variable est pas définie 
> puisqu'elle est toujours sensée l'être avec cette nouvelle définition).
> 
> 
> > Avec qq du genre , pas testé hein:
> > 
> >      - name: set ipv4 public address variable if at least one
> >        set_fact:
> >          ipv4_public: ansible_all_ipv4_addresses | ipaddr('public') |
> > first when: ansible_all_iansible_all_ipv4_addresses | ipaddr('public') |
> > length > 0
> > 
> >       - name: show ipv4 public adress
> >        debug:
> >          msg: "On a trouvé l'ip publique {{ ipv4_public }}"
> >        when: ipv4_public is defined
> 
> Je vois bien l'idée, merci pour avoir pointé le pb au bon endroit.
> 
> Ce que j'ai pas pigé c'est ce que renvoie
>   ipaddr('public')
> quand y'en a pas (c'est pas un tableau vide), et ce que renvoie
>   | first
> quand on lui file la sortie du précédent (c'est pas undefined)
> 
> Faudrait probablement que je me mette à python pour comprendre…
> 
-- 
Faustin Lammler
---------------------
FALARED S.A.S.U
27, rue Montorgueil
75001 PARIS - FRANCE
+33 (0) 6 09 14 46 57
GPG: F652 BCD1 1AA8 8975 F010 48A5 390A 2F27 832A 5C79
-------------- section suivante --------------
Une pièce jointe autre que texte a été nettoyée...
Nom: signature.asc
Type: application/pgp-signature
Taille: 833 octets
Desc: non disponible
URL: <http://www.frsag.org/pipermail/frsag/attachments/20201127/0bc932a2/attachment.sig>


Plus d'informations sur la liste de diffusion FRsAG