我坐在一个相当复杂的Ansible项目前面,我们用它来设置我们的本地开发环境(多个VM),并且有一个角色使用Ansible收集的事实来设置{{1}每个VM上的文件。不幸的是,当你只想为一个主机运行playbook时(使用-limit参数),其他主机的事实(显然)都会丢失。
有没有办法强制Ansible在所有主机上收集事实,即使你将剧本限制在一个特定的主机上?
我们尝试在剧本中添加一个剧本来收集所有主持人的事实,但当然这也限于-limit参数给出的一个主持人。如果有一种方法可以强制这个游戏在其他播放之前在所有主机上运行,那将是完美的。
我已经google了一下,发现了使用redis进行事实缓存的解决方案,但由于我们的Playbook是在本地使用的,所以我想避免使用其他软件。我知道,这不是什么大不了的事,但我只是在寻找一个“更清洁”,仅限Ansible的解决方案,并且想知道,如果存在的话。
答案 0 :(得分:11)
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
...
答案 1 :(得分:10)
一般来说,即使您不想在所有主机上运行任务,获取所有主机的事实的方法也是这样的:
- hosts: all
tasks: [ ]
但正如您所提到的, - limit参数将限制将应用于哪些主机。
我认为没有办法简单地告诉Ansible忽略任何游戏中的--limit参数。但是,在Ansible中可能还有另一种方法可以完全按照你想要的那样做。
我个人没有使用它,但是从Ansible 1.8 fact caching开始可用。简而言之,启用事实缓存Ansible将使用redis服务器来缓存它遇到的主机的所有事实,并且您将能够在后续的剧本中引用它们:
启用事实缓存后,一个组中的计算机可能会引用另一个组中的计算机的变量,尽管事实上它们尚未在当前执行的/ usr / bin / ansible-playbook中进行通信。
答案 2 :(得分:6)
这仍然是2016年没有干净解决方案的问题,但更新版本的Ansible提供了一个“jsonfile”事实缓存后端,这似乎是在本地安装Redis以满足这种需求的妥协。现在,我在使用ansible all -m setup
选项运行一个剧本之前启动--limit
。爵士乐足够好了!
http://docs.ansible.com/ansible/playbooks_variables.html#fact-caching
答案 3 :(得分:1)
您可以将您的剧本修改为:
...
- hosts: "{{ limit_hosts|default('default_group') }}"
tasks:
...
...
当您运行它时,如果未定义some_var
(正常状态),则它将在default_group
库存组上运行,但如果您将其运行为:
ansible-playbook --extra-vars "limit_hosts=myHost" myplaybook.yml
然后它只会在您的myHost
上运行,但您仍可以使用其他部分包含不同的hosts: ..
声明,事实收集或其他任何实际内容。