Сбор фактов на всех хостах
Я сижу перед довольно сложным проектом 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: ..
, для сбора фактов или всего остального.