从“--limit”选项之外的主机获取数据

PPC*_*PCM 5 ansible

我有以下剧本 ( playbook.yaml)

- hosts: myfirsthost[0]
  tasks:
    - name: Get a token
      slurp:
        src: /var/mytoken
      register: tokenFile

- hosts: myotherhosts
  vars:
    fileToken: "{{ hostvars[groups['myfirsthost'][0]]['tokenFile']['content'] | b64decode | replace('\n', '') }}"
  tasks:
    - debug:
    msg: The token {{fileToken}}
Run Code Online (Sandbox Code Playgroud)

当我为所有主机运行它时,它工作正常。

但是当我针对组中包含的单个主机myotherhosts(不在 group 中myfirsthosts)运行它时

ansible playbook.yaml --limit thesinglehost 
Run Code Online (Sandbox Code Playgroud)

它不执行第一个任务,然后变量无法初始化,这是预期的。

您是否知道我如何强制所有主机执行“获取令牌”任务,即使它们不在myfirsthost

Zei*_*tor 2

问题

--limit当您在命令中使用时ansible-playbook,您将无法在超出此限制的主机上执行任何任务。这包括收集事实(即自动或显式地播放setup模块)和set_fact(即为主机手动创建/更新事实)。使用ansible默认设置(内存事实缓存),您将无法查询hostvars剧本中这些主机上的任何内容,因为该字典中没有它们的键inventory_hostname

事实缓存来救援

解决方案是启用非临时事实缓存ansible.cfg。默认缓存会进入内存并在剧本结束时终止。

启用缓存

首先,您可以使用以下设置启用缓存并将其存储在磁盘上的 json 文件中ansible.cfg

[defaults]
fact_caching = jsonfile
fact_caching_connection = /path/to/cache/folder
Run Code Online (Sandbox Code Playgroud)

有关此功能以及所有可能的缓存后端的更多信息,您可以查看默认ansible.cfg文件中相关参数的注释并检查缓存插件文档

填充缓存

一旦您拥有非临时缓存,您就可以收集set_fact所有相关主机的事实。如果您只需要从主机查询事实,则可以使用临时命令轻松完成此操作:

ansible -i your/inventory my_hosts -m setup
Run Code Online (Sandbox Code Playgroud)

就您而言,情况有点复杂,因为您想要将任务结果推送到缓存。您将需要创建第一个 playbook,并将在稍后需要使用的所有主机上运行。我将其称为init_facts_and_tokens.yml

[defaults]
fact_caching = jsonfile
fact_caching_connection = /path/to/cache/folder
Run Code Online (Sandbox Code Playgroud)

然后你在所有主机上运行它

ansible-playbook -i your/inventory init_facts_and_tokens.yml
Run Code Online (Sandbox Code Playgroud)

使用缓存

现在缓存已填充,您可以播放其他剧本(无论是否有限制),然后调用hostvars播放/限制之外的主机。如果他们的事实已正确缓存,您将获得上次事实收集期间查询的值或set_fact

在这种情况下,您可能可以禁用所有剧本的事实收集,以节省最终剧本的执行时间。如果出于任何原因(例如更改网络接口、添加 lvm 卷......)您需要在播放过程中刷新事实,您只需运行该setup模块即可。对于未从您的主机查询的任何其他事实,set_fact对给定变量的任何使用都将创建/刷新其值

ansible -i your/inventory my_hosts -m setup
Run Code Online (Sandbox Code Playgroud)

您现在可以在有限制的情况下启动第二个剧本。即使在游戏之外,它仍然能够读取任何主机的事实(查询或用户设置)

# run on all hosts
ansible-playbook -i your/inventory final_playbook.yml

# run only on third host of my_hosts group
ansible-playbook -i your/inventory --limit my_host[2] final_playbook.yml
Run Code Online (Sandbox Code Playgroud)