0

I'd like to use an if else condition with include in my ansible playbooks. I have the following, which does not perform the check.

 - include: do-something.yml if {{version}} >= 1.14 else do-something-else.yml

version is set to 1.13.5 so do-something-else.yml should be run.

The following works but I'd prefer not to have multiple plays run and skipped as it makes the output and logs very busy.

- include: do-something.yml
  when: version >= "1.14"
- include: do-something-else.yml
  when: version < "1.14"

Here is an example mick.yml, which shows my desired include statement.

---
- include: do-something.yml if {{version}} >= 1.14 else do-something-else.yml

If I run mick.yml I'd expect it to check the version and run do-something-else.yml as version is set to 1.13.5. It does not do so but fails as follows.

ansible-playbook mick.yml
ERROR! Invalid variable name in vars specified for PlaybookInclude: '>' is not a valid variable name
mickt
  • 47
  • 1
  • 8

1 Answers1

1

Yes either you can do it in two tasks with two different when clause, just like you explained or, you can do it with the jinja2 if/else. But to doing so you have to place the tags {{ and }} surrounding the entire if/else clause, and encapsulated inside " that are required by YAML syntax.

So it should looks like this:

"{{ 'do-something.yml' if version >= 1.14 else 'do-something-else.yml' }}"

The version compare could be improved by using the appropriate jinja2 filter version_compare (related StackOverflow answer):

"{{ 'do-something.yml' if  version is version_compare('1.14', '>=') else 'do-something-else.yml' }}"

Nevertheless it seems there is an issue calling inline if/else with a real condition in an include:. We may open an Ansible issue.

So, what I propose is to keep this inline if/else, but store the results in a variable, and then call the include with that var.

---
- name: Test the jinja2 if/else to feed include
  hosts: localhost
  gather_facts: no

  vars:
    version: 1.12.7
    task_todo: "{{ 'do-something' if  version is version_compare('1.14', '>=') else 'do-something-else' }}.yml"

  tasks:
    - name: Print Task ToDo
      debug:
        var: task_todo

    - name: Include Something or SomethingElse
      include: "{{ task_todo }}"

Which was really close to what you tried! ;-)

xenlo
  • 761
  • 1
  • 7
  • 21
  • Thanks for the reply. I tried but It throws the following, ERROR! 'version' is undefined but version: 1.12.7 is defined in ansible/group_vars/all.yml. – mickt Sep 12 '19 at 14:14
  • If I throw braces around version it throws the following: ERROR! template error while templating string: expected token ':', got '}'. String: {{ 'do-something.yml' if {{version}} >= 1.14 else 'do-something-else.yml' }} – mickt Sep 12 '19 at 14:30
  • Indeed, you are right, it seems that the inline if/else generate some issue when processed in a `include`… I will updated my answer accordingly. BTW, I also propose an improvement to compare the version. – xenlo Sep 13 '19 at 10:52
  • Doesn't seem to work. ------- "reason": "no action detected in task. This often indicates a misspelled module name, or incorrect module path.\n\nThe error appears to have been in '/home/michthom/infrastructure-setup-new/do-something.yml': line 2, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n---\n- name: Ping VM\n ^ here\n\n\n ------- I will have multiple includes so unsure that this method will provide what I need. Shame the include check doesn't work as expected – mickt Sep 18 '19 at 12:31
  • Well, the sample in my answer was a copy/past of a working playbook… Are you sure that the content of the YAML file that you call is correct? I admit, in my I only had a simple `debug` tasks which printed the `task_todo` var. – xenlo Sep 18 '19 at 13:10
  • The existing files have been used many times directly and with include though without a check. I'm busy on something else at the moment so I'll park and revisit when time allows. Thanks for your help. – mickt Sep 19 '19 at 12:25