Use variable for default value if imported role failed

Viewed 308

I have an ansible role that reads data from a DB. That data might not exist in which case it fails. I cannot change this role. Currently I'm using this role like:

- name: Import role and read values
  import_role:
      name: shared_role
  register: value

This works well when the data in the DB exists and the role doesn't fail. However when that data is missing it's causing more problems. So in case of an error I want to ignore that error and use a default value.

- import_role:
      name: shared_role
  register: value
  ignore_errors: true
- set_fact:
    value: "{{ value | default({{ default_var }}) }}"

where default_var is defined in group_vars. Now this doesn't work obviously and I'm kind of stuck. How could I use a variable as a default value foor another variable registered in a role that might have failed... if that makes sense.

3 Answers

default will by default (sorry for this redundancy but I don't know how to write it better) replace values for undefined variables only. A variable defined as None is defined.

Fortunately, there is a second parameter that can be used to replace also "empty" vars (i.e. None, or empty string). See Documentation for this

Moreover, you cannot use jinja2 expansion while inside a jinja2 expansion already. Check the jinja2 documentation to learn more.

So you should achieve your requirement with the following expression (if all you described about your data is correct):

- set_fact:
    value: "{{ value | default(default_var, true) }}"

You should not have problems with variable precedence here: set_fact and register are on the same level so the latest assignment should win. But for clarity and security, I would rename that var so you are sure you never get into trouble:

- import_role:
    name: shared_role
  register: role_value
  ignore_errors: true
- set_fact:
    value: "{{ role_value | default(default_var, true) }}"

This is a simple syntax error. You can not use the {{}} in a filter.
The correct syntax is

- set_fact:
    value: "{{ value | default(default_var) }}"

EDIT:
If your value is "None" and you want to replace that, you can use something like this:

- set_fact:
    value: "{%- if not value is defined or value == 'None' -%}{{ default_var }}{%- else -%}{{ value }}{%- endif -%}"

Take note of the use of {{}} here.

Here is my group_vars/all.yml file. I am using food that is defined here to set in my play. you can see the value 6 in output.

 logs: /var/log/messages
   foo: 6

and here is my play-book

   ---
   - name: assign a variable value in default state
     hosts: localhost
     tasks:
     - name: set fact and then print
       set_fact:
         new_var: "{{ doodle | default( foo ) }}"
     - name: debug
       debug: msg="{{ new_var }}"

and here is the output

PLAY [assign a variable value in default state] ********************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [set fact and then print] *************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
   

>  "msg": "6"

}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 




  
Related