variables not defined when tasks are conditionally includes

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:

  • include: director.yml
    when: bacula_role == ‘director’

  • include: storage.yml
    when: bacula_role == ‘storage’

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.