最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

hostvars failing with 'ansible.vars.hostvars.HostVarsVars object has no element' - Stack Overflow

programmeradmin2浏览0评论

I have a playbook that's running on two hosts, pulling data from host1 in a registered variable and then using those data in a loop on host2 using hostvars but it's failing with ansible.vars.hostvars.HostVarsVars object has no element.

I'm specifying the hosts at run time using -l "host1,host2" then using when to specify which task to run on which host. (There may well be a better way of doing this).

- command: /some/command
  loop: "{{ hostvars['host1.example'][registered_var][stdout_lines] }}"
  when: "'host2' in inventory_hostname"
  register: output

- debug: var=output.results

Here's the first task that runs on host1:

- command: /some/command
  when: "'host1' in inventory_hostname"
  register: results

- debug: var=results.stdout_lines 

and here's the error

skipping: [host1.example]
fatal: [host2.example]: FAILED! => {}

MSG:

ansible.vars.hostvars.HostVarsVars object has no element {'skip_reason': u'Conditional result was False', 'skipped': True, 'changed': False}

I have a playbook that's running on two hosts, pulling data from host1 in a registered variable and then using those data in a loop on host2 using hostvars but it's failing with ansible.vars.hostvars.HostVarsVars object has no element.

I'm specifying the hosts at run time using -l "host1,host2" then using when to specify which task to run on which host. (There may well be a better way of doing this).

- command: /some/command
  loop: "{{ hostvars['host1.example'][registered_var][stdout_lines] }}"
  when: "'host2' in inventory_hostname"
  register: output

- debug: var=output.results

Here's the first task that runs on host1:

- command: /some/command
  when: "'host1' in inventory_hostname"
  register: results

- debug: var=results.stdout_lines 

and here's the error

skipping: [host1.example]
fatal: [host2.example]: FAILED! => {}

MSG:

ansible.vars.hostvars.HostVarsVars object has no element {'skip_reason': u'Conditional result was False', 'skipped': True, 'changed': False}
Share Improve this question edited Mar 31 at 17:54 β.εηοιτ.βε 39.5k14 gold badges79 silver badges99 bronze badges asked Mar 31 at 12:23 blackcountryladblackcountrylad 11 bronze badge New contributor blackcountrylad is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 3
  • "I have a playbook that's running on two hosts, pulling data from host1 in a registered var and then using that data in a loop on host2 using hostvars", is that single tasks the whole playbook? What kind of data you are pulling? Maybe you can provide a reproducible example? – U880D Commented Mar 31 at 13:34
  • It's a playbook that's in the process of being created. Just two tasks right now, the first one pulls a list of IP's from host1 and registers that to a var. – blackcountrylad Commented Mar 31 at 13:53
  • 1 Please provide a minimal reproducible example. – Squashman Commented Mar 31 at 16:59
Add a comment  | 

2 Answers 2

Reset to default 0

For me it is absolute not clear what you try to achieve, additionally the currently given information and approach looks more like an anti-pattern which I would avoid in any case.


For debugging purpose, to get familiar with Controlling where tasks run, Registering variables, Execution, magic variables, Common Return Values, a minimal example playbook

---
- hosts: test
  become: false
  gather_facts: false

  tasks:

  - name: On A only
    command: echo A
    register: result
    when: inventory_hostname_short is search('a')

  - name: On B only
    command: echo {{ hostvars[(ansible_play_hosts | first)]['result']['stdout'] }}
    register: result
    when: inventory_hostname_short is search('b')

  - name: Show both
    debug:
      msg: "{{ result }}"

will result into an output of

PLAY [test] **********************************

TASK [On A only] *****************************
changed: [hosta.example]

TASK [On B only] *****************************
changed: [hostb.example]

TASK [Show both] *****************************
ok: [hosta.example] =>
  msg:
    changed: false
    skip_reason: Conditional result was False
    skipped: true
ok: [hostb.example] =>
  msg:
    changed: true
    cmd:
    - echo
    - A
    delta: '0:00:00.004406'
    end: '2025-03-31 19:30:00.170367'
    failed: false
    msg: ''
    rc: 0
    start: '2025-03-31 19:30:00.165961'
    stderr: ''
    stderr_lines: []
    stdout: A
    stdout_lines:
    - A

PLAY RECAP ************************************
hosta.example : ok=2    changed=1
hostb.example : ok=2    changed=1

Further Reading

  • No wizardry needed to use Ansible's magic variable hostvars

If you do want a fact to be propagated from one host to all the selected hosts of your play — factually from the same batch, but you don't mention using batch, here — you can use the couple delegate_to / run_once:

run_once
Boolean that will bypass the host loop, forcing the task to attempt to execute on the first host available and afterward apply any results and facts to all active hosts in the same batch.

From the "Playbook Keywords" documentation.

A playbook applying this would looks something like:

- command: hostname
  delegate_to: host1.example
  run_once: true
  register: results

- command: echo '"{{ item }}"'
  loop: "{{ results.stdout_lines }}"
  delegate_to: host2.example
  run_once: true
  register: output

- debug:
    var: output.results
发布评论

评论列表(0)

  1. 暂无评论