# Variable state depending on existence of a file on host system - possible?

**URL:** <https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176>\
**Category:** Ansible Project\
**Created:** [January 5, 2022, 5:16pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176 "2022-01-05T17:16:28Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Neil\_Young](https://avatars.discourse-cdn.com/v4/letter/n/a3d4f5/32.png) [@Neil\_Young](https://forum.ansible.com/u/Neil_Young)\
**Post date:** [January 5, 2022, 5:16pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/1 "2022-01-05T17:16:28Z")

</div>

I’m currently having a var in my ./vars/default.yml, which is used at several points in my playbook for branching installation operations.

boolean\_var: true

Depending on this I’m performing (or not) install steps

…  
when: not boolean\_var

So far so good. I’m also using this var in some j2 templates like so:

{% if boolean\_var %}  
…

{% endif %}

My problem is, that I mostly forget to set this variable to a proper state, which reflects the real status on the host system, so I have to abort an update.  
I would rather like to derive it from a pre\_task, checking the existence of a particular file on the host before starting all operations.

Is there a way to define a variable with the same scope (playbook and templates) at runtime?

---

<div class="post-metadata">

**Author:** ![Wei-Yen\_Tan](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/wei-yen_tan/32/4111_2.png) [@Wei-Yen\_Tan](https://forum.ansible.com/u/Wei-Yen_Tan)\
**Post date:** [January 5, 2022, 5:18pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/2 "2022-01-05T17:18:22Z")

</div>

You could use the assert task to check that the variable exist before starting the run

---

<div class="post-metadata">

**Author:** ![Neil\_Young](https://avatars.discourse-cdn.com/v4/letter/n/a3d4f5/32.png) [@Neil\_Young](https://forum.ansible.com/u/Neil_Young)\
**Post date:** [January 5, 2022, 5:26pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/3 "2022-01-05T17:26:54Z")

</div>

It is not the problem of existence. The var exists all the time. It is about the wrong state

---

<div class="post-metadata">

**Author:** ![Wei-Yen\_Tan](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/wei-yen_tan/32/4111_2.png) [@Wei-Yen\_Tan](https://forum.ansible.com/u/Wei-Yen_Tan)\
**Post date:** [January 5, 2022, 5:34pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/4 "2022-01-05T17:34:27Z")

</div>

Use stat module to get your required facts. Bring it into assert or fail

[https://docs.ansible.com/ansible/latest/collections/ansible/builtin/stat\_module.html](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/stat_module.html)

---

<div class="post-metadata">

**Author:** ![decades\_software](https://avatars.discourse-cdn.com/v4/letter/d/8c91f0/32.png) [@decades\_software](https://forum.ansible.com/u/decades_software)\
**Post date:** [January 5, 2022, 6:06pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/5 "2022-01-05T18:06:59Z")

</div>

Well, yes. I know, how to stat a file. I don’t know how to create a variable from that with the same scope as a variable defined in default.yml.

I thought I was precise enough. Never mind. Disregard my question. Will find it out.

---

<div class="post-metadata">

**Author:** ![Wei-Yen\_Tan](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/wei-yen_tan/32/4111_2.png) [@Wei-Yen\_Tan](https://forum.ansible.com/u/Wei-Yen_Tan)\
**Post date:** [January 5, 2022, 6:08pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/6 "2022-01-05T18:08:29Z")

</div>

It is the example. Register

---

<div class="post-metadata">

**Author:** ![decades\_software](https://avatars.discourse-cdn.com/v4/letter/d/8c91f0/32.png) [@decades\_software](https://forum.ansible.com/u/decades_software)\
**Post date:** [January 5, 2022, 6:11pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/7 "2022-01-05T18:11:11Z")

</div>

Looks pretty verbose. I have some doubts to be able to use this in a .j2 file.

---

<div class="post-metadata">

**Author:** ![Wei-Yen\_Tan](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/wei-yen_tan/32/4111_2.png) [@Wei-Yen\_Tan](https://forum.ansible.com/u/Wei-Yen_Tan)\
**Post date:** [January 5, 2022, 6:13pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/8 "2022-01-05T18:13:31Z")

</div>

Why put in a jinja file? Run the assertion first in the role task /fail exit etc. Then run the template task

---

<div class="post-metadata">

**Author:** ![decades\_software](https://avatars.discourse-cdn.com/v4/letter/d/8c91f0/32.png) [@decades\_software](https://forum.ansible.com/u/decades_software)\
**Post date:** [January 5, 2022, 6:14pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/9 "2022-01-05T18:14:58Z")

</div>

It is a grown project, I can’t change everything just because of this.

Anyway, if it is not possible, then ok. I can live with the glitch

---

<div class="post-metadata">

**Author:** ![Wei-Yen\_Tan](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/wei-yen_tan/32/4111_2.png) [@Wei-Yen\_Tan](https://forum.ansible.com/u/Wei-Yen_Tan)\
**Post date:** [January 5, 2022, 6:21pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/10 "2022-01-05T18:21:24Z")

</div>

Can’t see why you can’t just run it before the template task. But your choice really.

---

<div class="post-metadata">

**Author:** ![decades\_software](https://avatars.discourse-cdn.com/v4/letter/d/8c91f0/32.png) [@decades\_software](https://forum.ansible.com/u/decades_software)\
**Post date:** [January 5, 2022, 6:22pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/11 "2022-01-05T18:22:29Z")

</div>

Exactly. Thanks

---

<div class="post-metadata">

**Author:** ![Neil\_Young](https://avatars.discourse-cdn.com/v4/letter/n/a3d4f5/32.png) [@Neil\_Young](https://forum.ansible.com/u/Neil_Young)\
**Post date:** [January 5, 2022, 6:43pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/12 "2022-01-05T18:43:16Z")

</div>

Well it is easier as I thought. Should have tried by myself before having asked here. Sharing the result. Still need to derive the var from the file stat, but hoping it is possible:

test.yml:

# ansible-playbook -l offline -i hosts.cfg test.yml

- hosts: all

vars:  
test: true

tasks:

- name: Copy config file, when test is defined  
tags: copy  
template:  
src: templates/test.j2  
dest: test.cfg  
when: test

- name: Copy config file, when test is not defined  
tags: copy  
template:  
src: templates/test.j2  
dest: test.cfg  
when: not test

templates/test.j2:

{% if test %}  
Test is defined  
{% else %}  
Test is not defined  
{% endif %}

A run with test=true skips the second copy task (as desired) and produces a file, which states “Test is defined” (as desired). The other way around with test=false

---

<div class="post-metadata">

**Author:** ![Neil\_Young](https://avatars.discourse-cdn.com/v4/letter/n/a3d4f5/32.png) [@Neil\_Young](https://forum.ansible.com/u/Neil_Young)\
**Post date:** [January 5, 2022, 7:08pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/13 "2022-01-05T19:08:45Z")

</div>

And this is all I wanted:

# ansible-playbook -l offline -i hosts.cfg test.yml

./test.yml:

- hosts: all

pre\_tasks:

# Test if there was a previous source installation of KMS

- name: Test if there was a KMS source installation running before  
stat:  
path: ~/.kms\_installed\_from\_source  
register: kms\_trace

vars:  
kms\_installed\_from\_source: ‘{{ true if (kms\_trace.stat.exists) else false }}’

tasks:

- name: Copy config file, when kms\_installed\_from\_source is defined  
tags: copy  
template:  
src: templates/test.j2  
dest: test.cfg  
when: kms\_installed\_from\_source

- name: Copy config file, when kms\_installed\_from\_source is not defined  
tags: copy  
template:  
src: templates/test.j2  
dest: test.cfg  
when: not kms\_installed\_from\_source

- name: Print  
debug:  
msg:

- ‘Status of “kms\_installed\_from\_source”: {{ kms\_installed\_from\_source}}’

./templates/test.j2:

{% if kms\_installed\_from\_source %}  
kms\_installed\_from\_source is defined  
{% else %}  
kms\_installed\_from\_source is not defined  
{% endif %}

Works

---

<div class="post-metadata">

**Author:** ![Wei-Yen\_Tan](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/wei-yen_tan/32/4111_2.png) [@Wei-Yen\_Tan](https://forum.ansible.com/u/Wei-Yen_Tan)\
**Post date:** [January 5, 2022, 7:11pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/14 "2022-01-05T19:11:03Z")

</div>

Which is if you look closely what I wrote. Similar to what I said 😊. Register the results from stat. Feed that into template. Thank you for taking my suggestion.

---

<div class="post-metadata">

**Author:** ![decades\_software](https://avatars.discourse-cdn.com/v4/letter/d/8c91f0/32.png) [@decades\_software](https://forum.ansible.com/u/decades_software)\
**Post date:** [January 5, 2022, 7:11pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/15 "2022-01-05T19:11:55Z")

</div>

Maybe I didn’t get it

---

<div class="post-metadata">

**Author:** ![Wei-Yen\_Tan](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/wei-yen_tan/32/4111_2.png) [@Wei-Yen\_Tan](https://forum.ansible.com/u/Wei-Yen_Tan)\
**Post date:** [January 5, 2022, 7:13pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/16 "2022-01-05T19:13:20Z")

</div>

Indeed. Glad that you got it sorted.

---

<div class="post-metadata">

**Author:** ![Dick\_Visser](https://avatars.discourse-cdn.com/v4/letter/d/d9b06d/32.png) [@Dick\_Visser](https://forum.ansible.com/u/Dick_Visser)\
**Post date:** [January 5, 2022, 7:41pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/17 "2022-01-05T19:41:27Z")

</div>

Hii

> And this is all I wanted:
> 
> # ansible-playbook -l offline -i hosts.cfg test.yml
> 
> ./test.yml:
> 
> - hosts: all
> 
> pre\_tasks:  
> # Test if there was a previous source installation of KMS  
> - name: Test if there was a KMS source installation running before  
> stat:  
> path: ~/.kms\_installed\_from\_source  
> register: kms\_trace
> 
> vars:  
> kms\_installed\_from\_source: '{{ true if (kms\_trace.stat.exists) else false }}'

You have the 'vars' section after 'pre\_tasks', giving the impression  
that this matters, while it doesn't.  
It can be anywhere.  
However, while it can be listed anywhere, it won't always work,  
because kms\_installed\_from\_source won't be available if used in tasks  
that are earlier than the 'stat' task.

Things will be less ambiguous if you use a set\_fact task, so it is  
clear where the variable is actually set.

Regarding 'pre\_tasks' (as well as post\_tasks), I find those somewhat  
confusing. I always have just 'tasks' and then the order of the tasks  
is as they appear in that list. I'm saying because I've seen  
post\_tasks being put at the beginning, and the other way around.

The "true if (kms\_trace.stat.exists) else false" is unnecessary as  
stat.exists is already a boolean.  
Concluding, if you must use a dedicated variale, then this task (as  
part of just 'tasks') should be sufficient:

- set\_fact:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;kms\_installed\_from\_source: '{{ kms\_trace.stat.exists }}'

Obviously the stat task needs to be executed before this. But if  
that's listed in that order, there is no ambiguity.

DIck

---

<div class="post-metadata">

**Author:** ![Neil\_Young](https://avatars.discourse-cdn.com/v4/letter/n/a3d4f5/32.png) [@Neil\_Young](https://forum.ansible.com/u/Neil_Young)\
**Post date:** [January 5, 2022, 7:44pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/18 "2022-01-05T19:44:37Z")

</div>

Hi Dick,  
Thanks for your elaborated answer.

The reason for having vars after stat is that I feared the “not defined” issue. I never tried to have vars before, but since I will try your set\_fact approach, this doesn’t matter either.

Thanks.

---

<div class="post-metadata">

**Author:** ![Neil\_Young](https://avatars.discourse-cdn.com/v4/letter/n/a3d4f5/32.png) [@Neil\_Young](https://forum.ansible.com/u/Neil_Young)\
**Post date:** [January 5, 2022, 7:48pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/19 "2022-01-05T19:48:18Z")

</div>

Yepp. Works. Many thanks. I also tried to simplify my true/false derivation before to no avail, but now it works.  
Thanks

---

<div class="post-metadata">

**Author:** ![Neil\_Young](https://avatars.discourse-cdn.com/v4/letter/n/a3d4f5/32.png) [@Neil\_Young](https://forum.ansible.com/u/Neil_Young)\
**Post date:** [January 5, 2022, 7:53pm UTC](https://forum.ansible.com/t/variable-state-depending-on-existence-of-a-file-on-host-system-possible/36176/20 "2022-01-05T19:53:45Z")

</div>

pre\_task btw is just to have a means to print out some installation variables for quick check in order to be able to react and abort the installation, if something is not as desired.

It is also quite handy, if you for instance use foreign roles (like geerlinguys node js installer). That needs an apt-cache update on bionic, before the role jumps in. So I sometimes find it helpful to have an early quick spot on something.
