【问题标题】:Force fact-gathering on all hosts强制对所有主机进行事实收集
【发布时间】:2015-07-13 12:23:14
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: ansible limit hosts ansible-facts


    【解决方案1】:

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

    - hosts: all
      tasks: [ ]  
    

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

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

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

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

    【讨论】:

    • 感谢您的回答。这也是我们的第一个解决方案,但目前看来,缓存是这个问题的唯一解决方案。如果有一些东西可以覆盖限制参数来收集事实,那就太好了。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

      【讨论】:

      • 这是组和 -l 参数的重复。 [db:children] something-DB 将你的东西分组并使用组。
      【解决方案4】:

      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
      
           ...
      

      【讨论】:

      • 您必须添加:标签:始终运行预任务,无论标签。但是干得好!!!!非常有用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多