Search code examples
ansiblejinja2

Ansible Use First Defined Variable


I'm in the process of updating a role that has to maintain backward compatibility. It supports two versions of the program (v1 and v2) and uses different variables that mean the same thing, but the name is prepended with the version (i.e. v1_my_val: True and v2_my_val: True).

I am creating two seperate vars files (one for v1 and one for v2) that gets loaded based on which version is being used. Common vars are put into each of the files (i.e. _my_val). So here is the part that is messing me up. I would like a single task that loads the first defined var in order if it is defined (i.e. v1_my_val, v2_my_val, _my_val).

Doing it with a single variable is easy enough (my_val: {{ v1_my_val | default _my_val }}) but not sure how to support the 2nd possibility.


Solution

  • Maybe you can get what you want using the ternary filter? Something like:

    - hosts: localhost
      gather_facts: false
      tasks:
        - debug:
            msg: "first available value: {{ var1 is defined | ternary(var1, var2) | default('val3') }}"
    

    If no variable is defined, running this produces:

    $ ansible-playbook playbook.yaml
    ...
    ok: [localhost] => {
        "msg": "first available value: val3"
    }
    

    If var1 is defined, we get the value of var1 (even if var2 is also defined):

    $ ansible-playbook playbook.yaml -e var1=val1 -e var2=val2
    ...
    ok: [localhost] => {
        "msg": "first available value: val1"
    }
    

    If var2 is defined (but not var1), we get the value of var2:

    $ ansible-playbook playbook.yaml -e var2=val2
    ...
    ok: [localhost] => {
        "msg": "first available value: val2"
    }