Сбор фактов на всех хостах

Я сижу перед довольно сложным проектом Ansible, который мы используем для настройки наших локальных сред разработки (несколько виртуальных машин), и там есть одна роль, которая использует факты, собранные Ansible для настройки файла /etc/hosts на каждой виртуальной машине. К сожалению, если вы хотите запустить playbook только для одного хоста (используя параметр -limit), факты с других хостов (очевидно) отсутствуют.

Есть ли способ заставить Ansible собирать факты на всех хостах, даже если вы ограничиваете Playbook одним конкретным хостом?

Мы попытались добавить игру в учебник для сбора фактов со всех хостов, но, конечно, это также ограничивается одним хостом, заданным параметром -limit. Если бы был способ заставить эту игру работать на всех хостах до того, как будет играть другая, это будет идеально.

Я немного искал Google и нашел решение с кэшированием фактов с помощью redis, но так как наша playbook используется локально, я хотел избежать необходимости в дополнительном программном обеспечении. Я знаю, это неважно, но я просто искал "более чистого", единственного решения и интересовался, если бы это существовало.

Ответы

Ответ 1

В общем, способ получить факты для всех хостов, даже если вы не хотите запускать задачи на всех хостах, - это сделать что-то вроде этого:

- hosts: all
  tasks: [ ]  

Но, как вы уже упоминали, параметр -limit ограничивает, на каких хостах это будет применяться.

Я не думаю, что есть способ просто сказать Ansible игнорировать параметр -limit для любых игр. Однако может быть другой способ сделать то, что вы хотите полностью в Ansible.

Я не использовал его лично, но из Ansible 1.8 кэширование фактов доступно. В двух словах, с кэшированием фактов, включенный Ansible будет использовать redis-сервер для кэширования всех фактов о встречах с узлами, с которыми он сталкивается, и вы сможете ссылаться на них в последующих книжках:

При включенном кэшировании фактов, в одной группе можно ссылаться на переменные об машинах в другой группе, несмотря на то, что они не были связаны с текущим исполнением /usr/bin/ansible -playbook.

Ответ 2

В Ansible версии 2 появился чистый официальный способ сделать это с помощью делегированных фактов (см. Http://docs.ansible.com/ansible/latest/playbooks_delegation.html#delegated-facts).

when: hostvars[item]['ansible_default_ipv4'] is not defined, это проверка, чтобы убедиться, что вы не проверяете факты на хосте, о котором вы уже знаете факты

---
# This play will still work as intended if called with --limit "<host>" or --tags "some_tag"

- name: Hostfile generation
  hosts: all
  become: true

  pre_tasks:
    - name: Gather facts from ALL hosts (regardless of limit or tags)
      setup:
      delegate_to: "{{ item }}"
      delegate_facts: True
      when: hostvars[item]['ansible_default_ipv4'] is not defined
      with_items: "{{ groups['all'] }}"

  tasks:
    - template:
        src: "templates/hosts.j2"
        dest: "/etc/hosts"
      tags:
        - hostfile

     ...

Ответ 3

Это все еще кажется проблемой без чистого решения здесь в 2016 году, но более новые версии Ansible предлагают "jsonfile" -факту для кэширования фактов, что, по-видимому, является достойным компромиссом для локализации Redis для решения этой проблемы. Теперь я просто запускаю ansible all -m setup перед запуском playbook с опцией --limit. Хорошо для джаза!

http://docs.ansible.com/ansible/playbooks_variables.html#fact-caching

Ответ 4

Вы можете изменить свою книгу для воспроизведения:

...
- hosts: "{{ limit_hosts|default('default_group') }}"
  tasks:
    ...
...

И когда вы запустите его, если some_var не определено (нормальное состояние), то он будет выполняться в группе инвентаризации default_group, НО если вы запустите его как:

ansible-playbook --extra-vars "limit_hosts=myHost" myplaybook.yml

Затем он будет работать только на вашем myHost, но вы все равно можете иметь другие разделы с различными объявлениями hosts: .., для сбора фактов или всего остального.