# accessing vars for hosts that are not in the play?

**URL:** <https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108>\
**Category:** Ansible Project\
**Tags:** aws\
**Created:** [September 16, 2022, 9:34am UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108 "2022-09-16T09:34:09Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [September 16, 2022, 9:34am UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/1 "2022-09-16T09:34:09Z")

</div>

Hi

I have a playbook that contains several plays. One play is performing API related tasks in AWS, so it’s using the local connection and localhost. The plays after that targets real hosts.  
Pseudo code:

- name: do API related work  
hosts: localhost  
connection: local  
become: false  
gather\_facts: false  
tags: api  
tasks:
- name: populate secret for use elsewhere

community.aws.aws\_secret:  
name: foopass  
secret: “{{ hostvars[groups[‘web’][0]].foopass }}”

- name: deploy web servers  
hosts: web  
tasks:
- name: save secret  
copy:  
dest: foopass.txt  
content: “{{ foopass }}”

This play works, but I don’t know how to selectively run the API play if there are no web servers in the play (as they might not exist yet).

If I try ‘-i localhost, --connection local’, then the API task doesn’t find any hostvars for a ‘web’ host:

TASK [populate secret for use elsewhere] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
fatal: [localhost]: FAILED! =\>  
msg: ‘{{ hostvars[groups[’‘web’‘][0]].foopass }}: ‘‘dict object’’ has no attribute ‘‘web’’’

This seems to make sense. But how would I go about accessing those vars?

Is it possible at all to access variables for hosts that are NOT in the current play?

FYI the variable is not gathered (again, because the web host is not yet there), it is defined in group\_vars/web/main.yml - so it is there on disk.

Thanks!

Dick Visser

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [September 16, 2022, 10:50am UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/2 "2022-09-16T10:50:22Z")

</div>

Can you add  
when: groups[‘web’] | length  
onto the “populate secret for use elsewhere” task?

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [September 16, 2022, 11:19am UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/3 "2022-09-16T11:19:01Z")

</div>

Better:  
groups[‘web’] | default() | length

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [September 16, 2022, 11:39am UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/4 "2022-09-16T11:39:16Z")

</div>

Hi

Thanks, but that seems to be making the play conditional on whether there are any ‘web’ hosts in the play.  
What I am looking for is a way to access those group\_vars regardless of whether there are any such hosts in the play.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [September 16, 2022, 1:07pm UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/5 "2022-09-16T13:07:19Z")

</div>

In that case, in the first play, do a “debug” and see what variables are available.

- name: groupvars anybody  
debug:  
msg: “{{ vars }}”  
From that you should be able to work out what the expression would be, if there is a way to do it.

---

<div class="post-metadata">

**Author:** ![Evan\_Hisey](https://avatars.discourse-cdn.com/v4/letter/e/ce73a5/32.png) [@Evan\_Hisey](https://forum.ansible.com/u/Evan_Hisey)\
**Post date:** [September 16, 2022, 1:16pm UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/6 "2022-09-16T13:16:44Z")

</div>

Honestly this sounds more like a need to revisit how you are handling variables. You are creating a scoping issue with the current approach. The all group is were things should live that might need to be accessed by multiple groups. Specific subgroups are for scope specific variables, so really should not be reaching across scopes for variables.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [September 16, 2022, 1:50pm UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/7 "2022-09-16T13:50:04Z")

</div>

This works in my little test. Worth a try, but this feels shaky.  
In your first play, at the same indent level as “tasks:”, add  
vars\_files:

- group\_vars/web/main.yml  
Then “{{ foopass }}” will be available to your task(s) in that first play.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [September 16, 2022, 2:23pm UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/8 "2022-09-16T14:23:32Z")

</div>

> vars\_files:  
> &nbsp;&nbsp;&nbsp;- group\_vars/web/main.yml

Do not load group\_vars/host\_vars directly, this is the job of the vars plugin,  
you create duplicate entries and mask the actual expected values from  
normal precedence resolution.

\> msg: '{{ hostvars[groups[''web''][0]].foopass }}: ''dict object''  
has no attribute ''web'''  
This is not because host is not in current play, it is because the  
host is not in inventory, which is a very different issue.

If you want to skip the tasks conditionally, check that the group is  
present and has at least one host:

&nbsp;&nbsp;&nbsp;when: "'web' in groups and groups['web'][0]"

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [September 16, 2022, 6:41pm UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/9 "2022-09-16T18:41:11Z")

</div>

Ok thanks for clearing this up.  
Just to be sure: it is not possible to access variables for hosts that are not in the inventory?

---

<div class="post-metadata">

**Author:** ![Evan\_Hisey](https://avatars.discourse-cdn.com/v4/letter/e/ce73a5/32.png) [@Evan\_Hisey](https://forum.ansible.com/u/Evan_Hisey)\
**Post date:** [September 16, 2022, 6:54pm UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/10 "2022-09-16T18:54:41Z")

</div>

If hosts are not in the inventory then they dont exist for Ansible. Group variables are different than host variables, by the way.

---

<div class="post-metadata">

**Author:** ![Kevin\_Shumaker](https://avatars.discourse-cdn.com/v4/letter/k/eb9ed0/32.png) [@Kevin\_Shumaker](https://forum.ansible.com/u/Kevin_Shumaker)\
**Post date:** [September 16, 2022, 6:57pm UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/11 "2022-09-16T18:57:49Z")

</div>

Is it possible to have multiple ‘inventories’? Like a touch list and do not touch list?

---

<div class="post-metadata">

**Author:** ![Evan\_Hisey](https://avatars.discourse-cdn.com/v4/letter/e/ce73a5/32.png) [@Evan\_Hisey](https://forum.ansible.com/u/Evan_Hisey)\
**Post date:** [September 16, 2022, 7:39pm UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/12 "2022-09-16T19:39:30Z")

</div>

Sure. That is the purpose of groups. You can but the entire network in a single inventory, solit it up by groups and groups of groups, then run play books only against the groups you want. You can also build them on the fly.

You can also mix that with logic loops in the playbooks to skip certain host with a switch varible.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [September 17, 2022, 12:59am UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/13 "2022-09-17T00:59:08Z")

</div>

The thing was my suggestion, and I heartily endorse Brian’s stance on this — i.e. to not to. “This works in my little test” and “this feels shaky” were too subtle. Just don’t. Reflecting further on the nature of the problem as you re-stated it: If you have a need to access these group variables’ values even when there are no host members in the relevant group(s) in your inventory, then I assert that these values are improperly scoped. By that I mean their “true root” should not be that group, but rather some other source that’s available to all the places that need it. For example With those two files in place, your initial play becomes

---

<div class="post-metadata">

**Author:** ![Evan\_Hisey](https://avatars.discourse-cdn.com/v4/letter/e/ce73a5/32.png) [@Evan\_Hisey](https://forum.ansible.com/u/Evan_Hisey)\
**Post date:** [September 17, 2022, 1:08am UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/14 "2022-09-17T01:08:00Z")

</div>

In a follow up to you line of thought, this really looks a variable (in the example) better handle by usin ansible vault than a variable file. It was designed for things like passwords.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [September 17, 2022, 1:23am UTC](https://forum.ansible.com/t/accessing-vars-for-hosts-that-are-not-in-the-play/37108/15 "2022-09-17T01:23:36Z")

</div>

Oh, for sure:
