Назад | Перейти на главную страницу

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]: НЕ ПРОШЛО! => {"failed": true, "msg": "поле 'args' имеет недопустимое значение, которое, по-видимому, включает неопределенную переменную. Ошибка была: 'ansible.vars.hostvars.HostVars object' не имеет атрибут u \ "groups ['all'] \" \ n \ nОшибка, похоже, была в '/Users/k/Projects/Ansible/roles/common/tasks/main.yml': строка 29, столбец 3, но может \ n находиться где-нибудь в файле в зависимости от точной синтаксической проблемы. \ n \ nСтрока, вызывающая нарушение, выглядит так: \ n \ n \ n- name: Добавить IP-адреса всех хостов ко всем хостам \ n ^ здесь \ n "}

Я не уверен, что происходит. Я все еще новичок в Ansible и до сих пор был доволен своим прогрессом. Любые идеи о том, что мне не хватает?

Предыдущий ответ просто не работает, потому что он добавляет новую строку для того же хоста вместо изменения существующей строки при изменении 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 }}"

Похоже, у вас есть ошибки в синтаксисе. И какую версию 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 }}"

ОБНОВИТЬ

Василий задумывался о ситуациях, когда 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 }}"

У меня была такая же проблема, и вот мое решение для всех, кому это интересно.

хосты / 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 доступный 2.9.0
  • Я решил использовать blockinfile вместо использования шаблонов, потому что контекст hostvars не обновлялся внутри шаблона. Плюс я очень торопился :-).

В 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']}}"

Я объединил гболо решение и этот решение с добавлением локального имени хоста в / etc / hosts, а также убедитесь, что не ошиблись с именами хостов, такими как s1 и ss1 друг с другом

- name: add hostname to /etc/hosts
  vars:
    comment: '# added by ansible'
  lineinfile:
    dest: /etc/hosts
    regexp: "127[.]0[.]0[.]1.*"
    line: "127.0.0.1 localhost.localdomain localhost {{ ansible_hostname }} {{ comment }}"
    state: present
    backup: yes
- name: add IP address of all hosts to /etc/hosts
  vars:
    comment: '# added by ansible'
  lineinfile:
    dest: /etc/hosts
    regexp: ".* {{ item }} {{ comment }}"
    line: "{{ hostvars[item]['ansible_env'].SSH_CONNECTION.split(' ')[2] }} {{ item }} {{ comment }}"
    state: present
    backup: yes
  when: ansible_hostname != item
  loop: "{{ query('inventory_hostnames', 'all') }}"

В раствор от Василия А довольно гибкий, но он может оставлять избыточные записи, если вы измените имя хоста или удалите хосты из инвентаря. По этой причине я создал немного доработанную версию решение от Vipul HK, с помощью blockinfile вместо того lineinfile:

- name: Add Ansible inventory mappings to /etc/hosts
  become: true
  blockinfile:
    path: /etc/hosts
    block: |
      {% for host in groups['all'] %}
      {{ hostvars[host].ansible_host }} {{ host }}
      {% endfor %}

Это решение гарантирует, что сопоставления хостов в /etc/hosts всегда совпадает с теми, что указаны в файле инвентаря.