Ansible:获取组的所有IP地址

Ansible:获取组的所有IP地址,ansible,jinja2,ansible-playbook,Ansible,Jinja2,Ansible Playbook,让我们设想这样一个清单文件: 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] 在我的

让我们设想这样一个清单文件:

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]
在我的剧本中,我现在想创建一些包含组
mainnodes
IP地址的变量:

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"
到目前为止,我得到的是:

vars:
  main_nodes_ips: "{{groups['mainnodes']|join(',')}}"
  main_nodes_ips_with_port: "{{groups['mainnodes']|join(':3000,')}}"
但这将使用主机名而不是IP地址

你知道怎么做吗

更新

查看文档一段时间后,我认为这将允许我遍历所有ip地址:

{% for host in groups['mainnodes'] %}
    {{hostvars[host]['ansible_ssh_host']}}
{% endfor %}
但我就是不知道如何创建一个包含所有这些IP的阵列。这样我就可以对它们使用
|join()
命令

更新2:
我只是觉得我已经明白了。。。但事实证明,您不能在剧本中使用{%%}语法。。。或者我可以吗? 在vars部分,它没有:/

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

我现在可以自己工作了。我对解决方案不太满意,但它可以:

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

不久前我遇到了这个问题,这就是我想到的(不是最优的,但它是有效的)

模板文件是

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

我找到了神奇的
地图提取

另一种选择(想法来自):

(假设接口是
eth0

我找到了访问其他组的ip的“唯一方法”,当以下任何一项为真时:

  • 一些成员还没有被ansible引导
  • 使用串行
  • 小组不是剧本的一部分
详情如下:

{% set ips=[] %}{% for host in groups['othergroup'] %}{% if ips.append(lookup('dig', host)) %}{% endif %}{% endfor %}{{ ips }}
在运行ansible的机器上需要dnspython,通过安装

sudo apt-get install python-dnspython

如果有人知道在这种情况下更好的方法,我很想摆脱这种可憎的东西。

我在剧本中使用了可靠的事实。 此剧本采用ansible_all_ipv4_addresses列表和ansible_nodename(实际上是完全限定的域名),遍历所有主机并将数据保存在本地主机上的localpath_to_save_ips文件中。您可以将localpath_更改为将IP保存为本地主机上的绝对路径

---
-主持人:全部
变成:是的
收集事实:是的
任务:
-名称:获取ip
本地\u操作:shell echo{{ansible\u all\u ipv4\u addresses}{{ansible\u nodename}>>本地路径\u保存\u ips
结果,您将在配置文件中有以下行:

hosts: ["192.168.126.38","192.168.126.39","192.168.126.40"]

我这样做是为了不被依赖于
eth0
(感谢ADV-IT的回答):


这对我有好处。不依赖于接口名称

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

为它创建任务似乎有点过火。对于任何使用2.0+
ansible\u ssh\u主机的人来说,都不推荐使用它。此解决方案仍然有效,但您需要将其替换为您编写的
ansible\u host
您对自己的anser不太满意。您已经非常接近最佳实践。现在请将McKelvins设置为已接受的。谢谢。@McKelvin的答案应该是公认的解决方案,因为它远远优于此答案,并且是Ansible官方文档推荐的解决方法。对RedHat来说,这是破坏Ansible支持门户的一个极大的中伤。第二个链接已断开。请注意,只有当所有服务器的所有主界面都设置为eth0时,替代方法才有效,并且请注意,
ansible\u ssh\u host
自ansible 2.0Thanks@wedi以来已重命名为
ansible\u host
。更新。对于第二部分,
ansible\u default\u ipv4
可能更可靠,因为接口名称变得不可预测……虽然此代码片段可以解决问题,但有助于提高响应质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。
sudo apt-get install python-dnspython
- 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 }}]"
hosts: ["192.168.126.38","192.168.126.39","192.168.126.40"]
- name: gathering facts
  hosts: mainnodes
  gather_facts: true

- hosts: mainnodes
  tasks:
    - name: Create List of nodes
      set_fact: nodelist={%for host in groups['mainnodes']%}"{{hostvars[host]['ansible_env'].SSH_CONNECTION.split(' ')[2]}}"{% if not loop.last %},{% endif %}{% endfor %}

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