[FRsAG] Pb de vars ansible

Daniel Caillibaud ml at lairdutemps.org
Ven 27 Nov 03:51:43 CET 2020


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…

-- 
Daniel

Ceux qui écrivent clairement ont des lecteurs ; ceux qui écrivent
obscurément ont des commentateurs.
Albert Camus 


Plus d'informations sur la liste de diffusion FRsAG