Ansible:将库存中的 IP 添加到所有节点的 /etc/hosts

Ansible:将库存中的 IP 添加到所有节点的 /etc/hosts

我正在部署一个小型的 3 节点集群,并且我想将我的清单中定义的公共 IP 地址添加到所有节点的 /etc/hosts 文件中。

我正在尝试使用以下命令,但它给出了一个错误:

- name: Add IP address of all hosts to all hosts
  lineinfile: 
    dest: /etc/hosts
    line: '{{ hostvars[item]["ansible_host"] }} {{ hostvars[item]["ansible_hostname"] }} {{ hostvars[item]["ansible_nodename"] }}'
    state: present
  with_items: groups['all']

错误是:

致命:[app1.domain.com]:失败! => {“失败”:true,“msg”:“字段“args”具有无效值,似乎包含未定义的变量。错误为:“ansible.vars.hostvars.HostVars 对象”没有属性 u“groups['all']”\n\n错误似乎出现在“/Users/k/Projects/Ansible/roles/common/tasks/main.yml”中:第 29 行,第 3 列,但可能\n位于文件的其他位置,具体取决于确切的语法问题。\n\n有问题的行似乎是:\n\n\n- 名称:将所有主机的 IP 地址添加到所有主机\n ^ 此处\n”}

对于我遗漏的内容有什么想法吗?

答案1

上面的答案根本不起作用,因为当主机的 IP 地址发生变化时,它会为同一主机添加新行,而不是修改现有行。

以下解决方案考虑了特定服务器的 IP 地址何时发生变化,并通过仅修改行而不是添加重复条目来很好地处理它。

---
- name: Add IP address of all hosts to all hosts
  lineinfile:
    dest: /etc/hosts
    regexp: '.*{{ item }}$'
    line: "{{ hostvars[item].ansible_host }} {{item}}"
    state: present
  when: hostvars[item].ansible_host is defined
  with_items: "{{ groups.all }}"

答案2

看起来你的语法有错误。你使用的 ansible 是哪个版本?变量名可能不同。2.2这个版本对我来说是有效的:

- name: Add IP address of all hosts to all hosts
  lineinfile:
    dest: /etc/hosts
    line: "{{ hostvars[item].ansible_host }} {{ hostvars[item].inventory_hostname }} {{ hostvars[item].inventory_hostname_short }}"
    state: present
  with_items: "{{ groups.all }}"

更新

Basil 考虑过 IP 发生变化的情况。在这种情况下,最好使用他建议的解决方案:

- name: Add IP address of all hosts to all hosts
  lineinfile:
    dest: /etc/hosts
    regexp: '.*{{ item }}$'
    line: "{{ hostvars[item].ansible_host }} {{item}}"
    state: present
  when: hostvars[item].ansible_host is defined
  with_items: "{{ groups.all }}"

答案3

我遇到了同样的问题,以下是我为任何感兴趣的人提供的解决方案。

主机/dev.ini

[controller]
controller1 ansible_ssh_host=10.11.11.10
controller2 ansible_ssh_host=10.11.11.11
controller3 ansible_ssh_host=10.11.11.12

[compute]
compute1 ansible_ssh_host=10.11.11.13
compute2 ansible_ssh_host=10.11.11.14
compute3 ansible_ssh_host=10.11.11.15

[block]
block1 ansible_ssh_host=10.11.11.16
block2 ansible_ssh_host=10.11.11.17

[haproxy]
haproxy1 ansible_ssh_host=10.11.11.18

[nginx]
nginx1 ansible_ssh_host=10.11.11.19

[deployment]
deployment ansible_ssh_host=10.11.11.20

[all:vars]
ansible_python_interpreter=/usr/bin/python3

任务/main.yml

---
- name: Update /etc/hosts
  become: true
  blockinfile:
      path: /etc/hosts
      create: yes
      block: |
        127.0.0.1 localhost

        # The following lines are desirable for IPv6 capable hosts
        ::1 ip6-localhost ip6-loopback
        fe00::0 ip6-localnet
        ff00::0 ip6-mcastprefix
        ff02::1 ip6-allnodes
        ff02::2 ip6-allrouters
        ff02::3 ip6-allhosts

        {% for item in ansible_play_batch %}
        {{ hostvars[item].ansible_ssh_host }}   {{ item }}    
        {% endfor %}

笔记:

  • Python 3.7.5 Ansible 2.9.0
  • 我决定使用 blockinfile 而不是使用模板,因为 hostvars 上下文未在模板内更新。而且我很着急 :-)。

答案4

在 Ansible2.5 中,这是一个可行的解决方案,我已经使用ansible_env.SSH_CONNECTION变量来获取远程服务器 IP,但未ansible_host在收集的事实中定义。

- name: Update the /etc/hosts file with node name
      tags: etchostsupdate
      become: yes
      become_user: root
      lineinfile:
        path: "/etc/hosts"
        regexp: "{{ hostvars[item]['ansible_env'].SSH_CONNECTION.split(' ')[2] }}\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}"
        line: "{{ hostvars[item]['ansible_env'].SSH_CONNECTION.split(' ')[2] }}\t{{ hostvars[item]['ansible_hostname']}}\t{{ hostvars[item]['ansible_hostname']}}"
        state: present
        backup: yes
      register: etchostsupdate
      when: ansible_hostname != "{{ item }}"
      with_items: "{{groups['app']}}"

相关内容