<p dir="auto">I have a growing bootstrap tasklist that sets up a common environment across all of my hosts -- things like ssh_authorized_keys, switching users' shells to their preferred, and most recently setting up a base set of monitoring rules in my Nagios infrastructure.</p>
<p dir="auto">The last bit led me to exploring <code class="notranslate">delegate_to</code> to set up rules on the nagios host which reference the nrpe rules installed on each host. Simple stuff, really. nrpe has a configuration variable which is used to restrict who can connect to it, based on IP address: <code class="notranslate">allowed_hosts=127.0.0.1,{{ hostvars['monitor.rix.si']['ansible_default_ipv4']['address'] }}</code></p>
<p dir="auto">This fact doesn't exist because setup hasn't (necessarily) run on that host to populate hostvars, so let's grab it:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="- name: Pull facts for monitor since we need them in nrpe config
  action: setup
  delegate_to: monitor.rix.si"><pre class="notranslate"><code class="notranslate">- name: Pull facts for monitor since we need them in nrpe config
  action: setup
  delegate_to: monitor.rix.si
</code></pre></div>
<p dir="auto">Nope, this doesn't work, in fact:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="TASK: [debug] *****************************************************************
failed: [web1.rix.si] =&gt; {&quot;failed&quot;: true, &quot;item&quot;: &quot;&quot;}
msg: {'inventory_hostname': 'monitor.rix.si', 'inventory_hostname_short': 'monitor', 'machine_type': 'server', 'group_names': ['nagios']}"><pre class="notranslate"><code class="notranslate">TASK: [debug] *****************************************************************
failed: [web1.rix.si] =&gt; {"failed": true, "item": ""}
msg: {'inventory_hostname': 'monitor.rix.si', 'inventory_hostname_short': 'monitor', 'machine_type': 'server', 'group_names': ['nagios']}
</code></pre></div>
<p dir="auto">If I was working at a playbook-level scope I could just do this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="- hosts: monitor.rix.si
  - name: Pull facts for monitor since we need them in nrpe config
    action: setup"><pre class="notranslate"><code class="notranslate">- hosts: monitor.rix.si
  - name: Pull facts for monitor since we need them in nrpe config
    action: setup
</code></pre></div>
<p dir="auto">And that would work, but I don't think it's sane to have to add that to every playbook when I specifically have this bootstrap to not have to do that, and converting the bootstrap to a playbook with <code class="notranslate">hosts: all</code> sucks, since it would have to run for every host when I run a host-specific playbook.</p>
<p dir="auto">From my POV, delegate_to should set up hostvars, but I don't know much of the architecture of Ansible enough to dig in to the code and figure out how to make this stick.</p>
<p dir="auto">Is it possible that there is another way to tackle this?</p>
<p dir="auto">Consider a lookaside fact cache that can pull (and store) facts in a local sqlite3 database such that you do not have to always hit hosts to get their fact data each time</p>
<p dir="auto">This would prevent the "need to talk to hosts previously" case and save some communication time in other cases.</p>