Hello folks,
I’m a bit confuse with conditional includes.
First, let me explained what I’m trying to do :
I want to install bacula as agent on all servers, but few servers have another bacula roles (like director and storage), so my first idea was the following one:
Create a roles/backup/tasks/main.yml which install the agent, create two files {director,storage}.yml in tasks director, and include them with the following code:
In director.yml I have something like:
- name: Check something by a script
shell: something.sh
register: something
- name: Do another thing if something is not ok
shell: blah.sh
when: something.rc > 0
but when I run the playbook on a node which have bacula_role == ‘agent’, ansible failed on evaluate something.rc > 0 (since something is not defined).
So my question are:
- why when conditions are evaluated when the task is skipped?
- why tasks in director.yml are parsed, why not just ignore this file when the when: condition doesn’t return true?
I have another related question, the bacula director role needs a SQL server, it is a good practice to have - { role: mysql-server, when: “bacula_role == ‘director’” } in meta/main.yml for example?
Thanks you
The files are always parsed because the when: statement may depend on a variable that is defined later in the execution, such as a host variable or fact. As for the first issue, I’m not quite sure why that would be happening because the task should not be run nor evaluated. I’m wondering if you have some other clause that is causing that to be included anyway?
No, I don’t have other include clauses.
Is that a bug, or I need to refactor my roles?
Yes go ahead and open an issue for that, and please include a quick sample to help reproduce that if you can.
Thanks!
- name: Check something by a script
shell: something.sh
register: something
- name: Do another thing if something is not ok
shell: blah.sh
when: something.rc > 0
While that that first task is skipped, the register option does make it
register something, which is, If I'm not mistaken:
something['skipped''] = true
Which makes something['rc'] not defined, yeilding an error.
Change that conditional to:
when: something.skipped is not defined and something.rc > 0
Always take into account a registered task might get skipped.
Serge
Ok, but why the when is evaluated while the task is skipped?
How can it know when to skip without evaluating the condition?
Remember, both conditions are appended, and evaluated; seems the
something.rc is evaluated first.
I vaguely recall an issue / discussion about that ordering, not sure what
it was or if something was changed about it.
Serge
Because these tasks are in a file which is include as following:
- include: file.yaml
when: condition that returned False
Because these tasks are in a file which is include as following:
- include: file.yaml
when: condition that returned False
again: both conditions are appended, and evaluated
Ok my bad.
Any chance to have a different behavior (with another keyword than include maybe) to include a file that will not even parsed when the when condition return false?
After all, maybe the way I think roles doesn’t match ansible roles.
It’s just an example, but for me, an ansible role “backup” should care of all backup configuration, server, client, etc.
Maybe I miss something, but at this moment I don’t understand how to have a separate tasks file for each backup role.