commands - Ansible: obtener todas las direcciones IP de un grupo
ansible documentation (6)
Encontré la "única forma" de acceder a las direcciones IP de otros grupos, cuando se cumple alguna de las siguientes condiciones:
- Algunos miembros aún no han sido arrancados por ansible.
- usando serial
- el grupo no es parte del libro de jugadas
Es como sigue:
{% set ips=[] %}{% for host in groups[''othergroup''] %}{% if ips.append(lookup(''dig'', host)) %}{% endif %}{% endfor %}{{ ips }}
Requiere dnspython en la máquina que se ejecuta ansible, instalar a través de
sudo apt-get install python-dnspython
Si alguien sabe una mejor manera dadas las condiciones, me encantaría deshacerme de esta abominación.
Imaginemos un archivo de inventario como este:
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]
En mi libro de jugadas ahora quiero crear algunas variables que contengan las direcciones IP de los mainnodes
grupo:
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"
Esto es lo que tengo hasta ahora:
vars:
main_nodes_ips: "{{groups[''mainnodes'']|join('','')}}"
main_nodes_ips_with_port: "{{groups[''mainnodes'']|join('':3000,'')}}"
pero eso usaría los nombres de host en lugar de las direcciones IP.
¿Alguna idea de cómo se podría hacer esto?
Actualización :
Mirando los documentos por un tiempo, creo que esto me permitiría recorrer todas las direcciones IP:
{% for host in groups[''mainnodes''] %}
{{hostvars[host][''ansible_ssh_host'']}}
{% endfor %}
Pero simplemente no puedo descubrir cómo crear una matriz que contenga todas estas IP. Para que pueda usar el comando |join()
en ellos.
Actualización2:
Pensé que lo había descubierto ... pero resulta que no puedes usar la sintaxis {%%} en el libro de jugadas ... ¿o puedo? Bueno, en la sección de vars no fue así. : /
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,'')}}"
Encuentro el map extract
mágico here .
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"
Una alternativa (la idea viene de here ):
main_nodes_ips: "{{ groups[''mainnodes''] | map(''extract'', hostvars, [''ansible_eth0'', ''ipv4'', ''address'']) | join('','') }}"
He hecho esto usando datos ansibles en un libro de jugadas. Este libro de jugadas toma la lista ansible_all_ipv4_addresses y ansible_nodename (que en realidad es el nombre de dominio completo), itera a través de todos los hosts y guarda los datos en el archivo localpath_to_save_ips en su host local. Puede cambiar localpath_to_save_ips a la ruta absoluta en su 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
Lo tengo para trabajar por mi cuenta ahora. No estoy muy contento con la solución, pero lo hará:
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,'')}
Me encontré con este problema hace un tiempo y esto es lo que se me ocurrió (no es óptimo, pero funciona)
---
# 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
y el archivo de plantilla es
ip:
{% for h in groups[''webservers''] %}
- {{ hostvars[h].ansible_ssh_host }}
{% endfor %}
- name: Create List of nodes to be added into Cluster
set_fact: nodelist={%for host in groups[''mygroup'']%}"{{hostvars[host].ansible_eth0.ipv4.address}}"{% if not loop.last %},{% endif %}{% endfor %}
- debug: msg=[{{nodelist}}]
- name: Set Cluster node list in config file
lineinfile:
path: "/etc/myfonfig.cfg"
line: "hosts: [{{ nodelist }}]"
Como resultados tendrás la siguiente línea en el archivo de configuración:
hosts: ["192.168.126.38","192.168.126.39","192.168.126.40"]