Le 26/11/20 à 19h28, Jean-Yves LENHOF jean-yves@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…