Ansible:获取组的所有IP地址

问题描述 投票:36回答:6

让我们假设一个像这样的库存文件:

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()命令了。

UPDATE2: 我只是觉得我已经弄清楚了......但事实证明你不能在剧本中使用{%%}语法......或者我可以吗?在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,')}}"
ansible jinja2 ansible-playbook
6个回答
57
投票

我找到了神奇的map extract here

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"

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

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

(假设接口是eth0


7
投票

我曾经遇到过这个问题,这就是我提出的问题(不是最优的,但它有效)

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

和模板文件是

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

2
投票

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

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

当满足以下任何条件时,我找到了访问其他组的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

如果有人知道条件更好的方式,我很想摆脱这种憎恶。


1
投票

我通过在剧本中使用ansible事实来做到这一点。该playbook采用ansible_all_ipv4_addresses列表和ansible_nodename(实际上是完全限定的域名),遍历所有主机并将数据保存在localhost上的localpath_to_save_ips文件中。您可以将localpath_to_save_ips更改为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

0
投票
- 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"]
© www.soinside.com 2019 - 2024. All rights reserved.