Ansible: récupère toutes les adresses IP d'un groupe
Imaginons un fichier d'inventaire comme ceci:
node-01 ansible_ssh_host=192.168.100.101
node-02 ansible_ssh_host=192.168.100.102
node-03 ansible_ssh_host=192.168.100.103
node-04 ansible_ssh_host=192.168.100.104
node-05 ansible_ssh_host=192.168.100.105
[mainnodes]
node-[01:04]
Dans mon playbook, je veux maintenant créer des variables contenant les adresses IP du groupe mainnodes
:
vars:
main_nodes_ips: "192.168.100.101,192.168.100.102,192.168.100.103,192.168.100.104"
main_nodes_ips_with_port: "192.168.100.101:3000,192.168.100.102:3000,192.168.100.103:3000,192.168.100.104:3000"
C'est ce que j'ai eu jusqu'à présent:
vars:
main_nodes_ips: "{{groups['mainnodes']|join(',')}}"
main_nodes_ips_with_port: "{{groups['mainnodes']|join(':3000,')}}"
Mais cela utiliserait les noms d'hôte au lieu des adresses IP.
Des idées comment cela pourrait être fait?
Mise à Jour:
En regardant les documents pendant un moment, je pense que cela me permettrait de parcourir toutes les adresses ip adresses:
{% for host in groups['mainnodes'] %}
{{hostvars[host]['ansible_ssh_host']}}
{% endfor %}
Mais je n'arrive tout simplement pas à comprendre comment créer un tableau contenant toutes ces adresses IP. Pour que je puisse utiliser la commande |join()
sur eux.
Update2:
J'ai juste pensé que j'avais compris... mais il s'avère que vous ne pouvez pas utiliser la syntaxe {% %} dans le playbook... ou puis-je?
Eh bien, dans la section vars, ce n'est pas le cas.: /
vars:
{% set main_nodes_ip_arr=[] %}
{% for host in groups['mesos-slave'] %}
{% if main_nodes_ip_arr.insert(loop.index,hostvars[host]['ansible_ssh_host']) %} {% endif %}
{% endfor %}
main_nodes_ips: "{{main_nodes_ip_arr|join(',')}}"
main_nodes_ips_with_port: "{{main_nodes_ip_arr|join(':3000,')}}"
5 réponses
Je trouve la magie map extract
ici.
main_nodes_ips: "{{ groups['mainnodes'] | map('extract', hostvars, ['ansible_ssh_host']) | join(',') }}"
main_nodes_ips_with_port: "{{ groups['mainnodes'] | map('extract', hostvars, ['ansible_ssh_host']) | join(':3000,') }}:3000"
Une alternative(l'idée vient de ici):
main_nodes_ips: "{{ groups['mainnodes'] | map('extract', hostvars, ['ansible_eth0', 'ipv4', 'address']) | join(',') }}"
Je suis tombé sur ce problème un temps, et c'est ce que j'ai trouvé (pas optimal, mais ça fonctionne)
---
# playbook.yml
- hosts: localhost
connection: local
tasks:
- name: create deploy template
template:
src: iplist.txt
dest: /tmp/iplist.txt
- include_vars: /tmp/iplist.txt
- debug: var=ip
Et le fichier modèle est
ip:
{% for h in groups['webservers'] %}
- {{ hostvars[h].ansible_ssh_host }}
{% endfor %}
Je l'ai fait travailler tout seul maintenant. Je ne suis pas trop heureux de la solution, mais cela fera l'affaire:
main_nodes_ips: "{% set IP_ARR=[] %}{% for host in groups['mainnodes'] %}{% if IP_ARR.insert(loop.index,hostvars[host]['ansible_ssh_host']) %}{% endif %}{% endfor %}{{IP_ARR|join(',')}}"
main_nodes_ips_with_port: "{% set IP_ARR=[] %}{% for host in groups['mainnodes'] %}{% if IP_ARR.insert(loop.index,hostvars[host]['ansible_ssh_host']) %}{% endif %}{% endfor %}{{IP_ARR|join(':3000,')}
J'ai trouvé le "seul moyen" d'accéder aux adresses ip d'autres groupes, lorsque l'un des éléments suivants est vrai:
- certains membres ne sont pas encore bootstrappés par ansible
- utilisant la série
- Le groupe ne fait pas partie du playbook
Est comme suit:
{% set ips=[] %}{% for host in groups['othergroup'] %}{% if ips.append(lookup('dig', host)) %}{% endif %}{% endfor %}{{ ips }}
Nécessite dnspython sur la machine exécutant ansible, installer via
sudo apt-get install python-dnspython
Si quelqu'un connaît un meilleur moyen compte tenu des conditions, j'aimerais me débarrasser de cette abomination.
Je l'ai fait en utilisant des faits ansible dans un playbook. Ce playbook prend la liste ansible_all_ipv4_addresses et ansible_nodename (qui est en fait un nom de domaine complet), parcourt tous les hôtes et enregistre les données dans le fichier localpath_to_save_ips sur votre localhost. Vous pouvez changer localpath_to_save_ips en chemin absolu sur votre localhost.
---
- hosts: all
become: yes
gather_facts: yes
tasks:
- name: get ip
local_action: shell echo {{ ansible_all_ipv4_addresses }} {{ ansible_nodename }} >> localpath_to_save_ips