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

67 views
Skip to first unread message

Neil Young

unread,
Jan 5, 2022, 12:16:28 PM1/5/22
to Ansible Project
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?

Wei-Yen Tan

unread,
Jan 5, 2022, 12:18:37 PM1/5/22
to ansible...@googlegroups.com
You could use the assert task to check that the variable exist before starting the run 

From: 'Neil Young' via Ansible Project <ansible...@googlegroups.com>
Sent: Thursday, January 6, 2022 6:16:28 AM
To: Ansible Project <ansible...@googlegroups.com>
Subject: [ansible-project] Variable state depending on existence of a file on host system - possible?
 
--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/5da6e38e-ae18-4b28-98f9-4341465c2cbfn%40googlegroups.com.

Neil Young

unread,
Jan 5, 2022, 12:27:09 PM1/5/22
to ansible...@googlegroups.com
It is not the problem of existence. The var exists all the time. It is about the wrong state

Von meinem iPad gesendet

Am 05.01.2022 um 18:18 schrieb Wei-Yen Tan <weiye...@gmail.com>:


You received this message because you are subscribed to a topic in the Google Groups "Ansible Project" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ansible-project/MWKwiX9ICR8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ansible-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/SYBP282MB35259E19C8AA647EF3B46381AD4B9%40SYBP282MB3525.AUSP282.PROD.OUTLOOK.COM.

Wei-Yen Tan

unread,
Jan 5, 2022, 12:34:47 PM1/5/22
to ansible...@googlegroups.com
Use stat module to get your required facts. Bring it into assert or fail 


From: 'Neil Young' via Ansible Project <ansible...@googlegroups.com>
Sent: Thursday, January 6, 2022 6:26:54 AM
To: ansible...@googlegroups.com <ansible...@googlegroups.com>
Subject: Re: [ansible-project] Variable state depending on existence of a file on host system - possible?
 

decades software

unread,
Jan 5, 2022, 1:07:16 PM1/5/22
to ansible...@googlegroups.com
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.


Wei-Yen Tan

unread,
Jan 5, 2022, 1:08:49 PM1/5/22
to ansible...@googlegroups.com
It is the example. Register 

From: ansible...@googlegroups.com <ansible...@googlegroups.com> on behalf of decades software <decades-...@freenet.de>
Sent: Thursday, January 6, 2022 7:06:59 AM

decades software

unread,
Jan 5, 2022, 1:11:24 PM1/5/22
to ansible...@googlegroups.com
Looks pretty verbose. I have some doubts to be able to use this in a .j2 file.

Wei-Yen Tan

unread,
Jan 5, 2022, 1:13:50 PM1/5/22
to ansible...@googlegroups.com
Why put in a jinja file? Run the assertion  first in the role task /fail exit etc. Then run the template task 

Sent: Thursday, January 6, 2022 7:11:11 AM

decades software

unread,
Jan 5, 2022, 1:15:13 PM1/5/22
to ansible...@googlegroups.com
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


Wei-Yen Tan

unread,
Jan 5, 2022, 1:21:43 PM1/5/22
to ansible...@googlegroups.com
Can't see  why you can't just run it before the template task. But your choice really. 

Sent: Thursday, January 6, 2022 7:14:58 AM

decades software

unread,
Jan 5, 2022, 1:22:43 PM1/5/22
to ansible...@googlegroups.com

Neil Young

unread,
Jan 5, 2022, 1:43:17 PM1/5/22
to Ansible Project
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




Neil Young

unread,
Jan 5, 2022, 2:08:46 PM1/5/22
to Ansible Project
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

Wei-Yen Tan

unread,
Jan 5, 2022, 2:11:19 PM1/5/22
to ansible...@googlegroups.com
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. 

From: 'Neil Young' via Ansible Project <ansible...@googlegroups.com>
Sent: Thursday, January 6, 2022 8:08:45 AM
To: Ansible Project <ansible...@googlegroups.com>

decades software

unread,
Jan 5, 2022, 2:12:11 PM1/5/22
to ansible...@googlegroups.com

Wei-Yen Tan

unread,
Jan 5, 2022, 2:13:34 PM1/5/22
to ansible...@googlegroups.com
Indeed. Glad that you got it sorted. 

From: 'Neil Young' via Ansible Project <ansible...@googlegroups.com>
Sent: Thursday, January 6, 2022 8:08:45 AM
To: Ansible Project <ansible...@googlegroups.com>

Dick Visser

unread,
Jan 5, 2022, 2:41:53 PM1/5/22
to ansible...@googlegroups.com
Hii


On Wed, 5 Jan 2022 at 20:09, 'Neil Young' via Ansible Project
<ansible...@googlegroups.com> wrote:
>
> 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:
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

Neil Young

unread,
Jan 5, 2022, 2:44:37 PM1/5/22
to Ansible Project
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.

Neil Young

unread,
Jan 5, 2022, 2:48:18 PM1/5/22
to Ansible Project
Yepp. Works. Many thanks. I also tried to simplify my true/false derivation  before to no avail, but now it works.
Thanks

Neil Young

unread,
Jan 5, 2022, 2:53:46 PM1/5/22
to Ansible Project
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.
Reply all
Reply to author
Forward
0 new messages