it-swarm.com.de

Ansible: Alle IP-Adressen einer Gruppe abrufen

Stellen wir uns eine Inventardatei wie diese vor: 

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]

In meinem Playbook möchte ich nun einige Variablen erstellen, die die IP-Adressen der Gruppe mainnodes enthalten: 

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"

Das habe ich bisher bekommen:

vars:
  main_nodes_ips: "{{groups['mainnodes']|join(',')}}"
  main_nodes_ips_with_port: "{{groups['mainnodes']|join(':3000,')}}"

dies würde jedoch die Hostnamen anstelle der IP-Adressen verwenden. 

Irgendwelche Ideen, wie das gemacht werden könnte?

Update :

wenn ich mir die Dokumente für eine Weile anschaue, denke ich, dass ich dadurch alle IP-Adressen durchlaufen könnte:

{% for Host in groups['mainnodes'] %}
    {{hostvars[Host]['ansible_ssh_Host']}}
{% endfor %}

Aber ich kann einfach nicht herausfinden, wie man ein Array erstellt, das all diese IPs enthält. Damit kann ich den |join()-Befehl für sie verwenden.

Update2:
Ich dachte nur, ich hätte es herausgefunden ... aber es stellt sich heraus, dass Sie die {%%} -Syntax im Playbook nicht verwenden können ... oder kann ich? . : /

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,')}}"
26
Forivin

Ich habe es jetzt selbstständig gemacht. Ich bin nicht sehr glücklich über die Lösung, aber sie wird es tun: 

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,')}
1
Forivin

Ich finde den Zauber map extracthier .

main_nodes_ips: "{{ groups['mainnodes'] | map('extract', hostvars, ['ansible_Host']) | join(',') }}"
main_nodes_ips_with_port: "{{ groups['mainnodes'] | map('extract', hostvars, ['ansible_Host']) | join(':3000,') }}:3000"

Eine Alternative (Idee kommt von hier ):

main_nodes_ips: "{{ groups['mainnodes'] | map('extract', hostvars, ['ansible_eth0', 'ipv4', 'address']) | join(',') }}"

(Angenommen, die Schnittstelle ist eth0)

38
McKelvin

ich bin vor einiger Zeit auf dieses Problem gestoßen.

---
# 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

und die Vorlagendatei ist

ip:
{% for h in groups['webservers'] %}
 - {{ hostvars[h].ansible_ssh_Host }}
{% endfor %}
5
user2599522

Ich habe dies getan, indem ich die Ansible-Fakten in einem Playbook verwendet habe .. Dieses Playbook enthält eine Ansible_all_ipv4_addresses-Liste und einen Ansible_nodename (der eigentlich voll qualifizierte Domainname ist), durchläuft alle Hosts und speichert die Daten in der Datei localpath_to_save_ips auf Ihrem localhost. Sie können localpath_to_save_ips in den absoluten Pfad auf Ihrem localhost ändern.

---
- 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

1

Ich habe den "einzigen Weg" gefunden, auf die IPs anderer Gruppen zuzugreifen, wenn eine der folgenden Bedingungen zutrifft:

  • einige Mitglieder werden noch nicht von Ansible gebootet
  • seriell verwenden
  • gruppe ist nicht Teil des Spielbuchs

Ist wie folgt:

{% set ips=[] %}{% for Host in groups['othergroup'] %}{% if ips.append(lookup('Dig', Host)) %}{% endif %}{% endfor %}{{ ips }}

Benötigt dnspython auf dem Rechner, auf dem ansible läuft, Installation über

Sudo apt-get install python-dnspython

Wenn jemand einen besseren Weg unter den gegebenen Bedingungen kennt, würde ich gerne diesen Greuel loswerden.

1
Petroldrake
- 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 }}]"

als Ergebnis erhalten Sie die folgende Zeile in der Konfigurationsdatei:

hosts: ["192.168.126.38","192.168.126.39","192.168.126.40"]
0
ADV-IT