33

我正坐在一个相当复杂的 Ansible 项目前面,我们用它来设置我们的本地开发环境(多个 VM),并且有一个角色使用 Ansible 收集的事实/etc/hosts在每个 VM 上设置文件。不幸的是,当您只想为一台主机运行剧本时(使用 -limit 参数),来自其他主机的事实(显然)丢失了。

有没有办法强制 Ansible 在所有主机上收集事实,即使您将剧本限制在一个特定的主机上?

我们试图在剧本中添加一个剧本来收集来自所有主机的事实,但当然这也仅限于 -limit 参数给定的一个主机。如果有一种方法可以强制该播放在其他播放之前在所有主机上运行,​​那将是完美的。

我用谷歌搜索了一下,找到了使用 redis 进行事实缓存的解决方案,但由于我们的剧本是在本地使用的,我想避免需要额外的软件。我知道,这没什么大不了的,但我只是在寻找一个“更清洁”、仅限 Ansible 的解决方案,并且想知道这是否存在。

4

4 回答 4

34

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

     ...
于 2017-08-14T23:13:05.757 回答
11

通常,即使您不想在所有主机上运行任务,获取所有主机的事实的方法是执行以下操作:

- hosts: all
  tasks: [ ]  

但正如您所提到的, --limit 参数将限制这将应用于哪些主机。

我认为没有办法简单地告诉 Ansible 在任何播放中忽略 --limit 参数。但是,可能还有另一种方法可以完全在 Ansible 中完成您想要的操作。

我没有亲自使用过它,但从 Ansible 1.8 开始,事实缓存是可用的。简而言之,启用事实缓存后,Ansible 将使用 redis 服务器缓存它遇到的主机的所有事实,您将能够在后续的剧本中引用它们:

启用事实缓存后,一个组中的机器可以引用有关另一组中机器的变量,尽管在当前执行 /usr/bin/ansible-playbook 时它们没有被通信。

于 2015-05-04T11:24:19.330 回答
6

在 2016 年,如果没有一个干净的解决方案,这似乎仍然是一个问题,但新版本的 Ansible 提供了一个“jsonfile”事实缓存后端,这似乎是为了满足这一需求而在本地安装 Redis 的一个不错的折衷方案。现在我只是ansible all -m setup在运行带有该--limit选项的剧本之前启动一个。爵士乐就够了!

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

于 2016-06-30T23:14:38.130 回答
1

您可以将您的剧本修改为:

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

当您运行它时,如果some_var未定义(正常状态),那么它将在default_group库存组上运行,但如果您将其运行为:

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

然后它只会在您的 . 上运行myHost,但您仍然可以拥有具有不同hosts: ..声明的其他部分,用于事实收集或其他任何实际内容。

于 2016-08-01T20:08:42.377 回答