Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow null or empty values in a variable using Ansible

I have this piece of code that checks if the variable "owner" matches with the following regex and accepts that it is undefined, that is, the playbook can work without that variable being passed.

varexample is undefined or varexample is match('^[a-zA-Z]+$')

What I would like to do is that this variable accepts empty or null values. What I tried is something like this

varexample is null or varexample is match('^[a-zA-Z]+$')

But I got this error:

The conditional check 'varexample is null or varexample is match('[a-zA-Z]+')' failed. The error was: template error while templating string: no test named 'null'. String: {% if varexample is null or varexample is match('[a-zA-Z]+') %} True {% else %} False {% endif %}

Can someone give me a hint or some help?

like image 663
Fede Berbara Avatar asked Apr 29 '26 12:04

Fede Berbara


1 Answers

Update:

Q: "Test the variable owner matches the following regex and accepts that it is undefined, empty or null value."

A: Use the filter default

owner | d('', true) is match('^[a-zA-Z]+$')

The 2nd argument true (default=false) is needed to convert null to an empty string (that doesn't match the regex). Quoting:

"If you want to use default with variables that evaluate to false you have to set the second parameter to true."

As a result:

  • Undefined owner converts to an empty string and match returns false
  • Defined no value owner: converts to an empty string and match returnes false
  • Defined value owner: value returns the match result

Details:

Q: "variable accepts null values"

A: It's a bug. Ansible shouldn't match null to '^[a-zA-Z]+$'

    - set_fact:
        varexample:
    - debug:
        var: varexample
    - debug:
        msg: "undefined: {{ varexample is undefined }}"
    - debug:
        msg: "match: {{ varexample is match('^[a-zA-Z]+$') }}"

gives

  varexample: null
  msg: 'undefined: False'
  msg: 'match: True'

As a result of this bug, your condition should be working as expected

  varexample is undefined or varexample is match('^[a-zA-Z]+$')

To be on the save side, for the case the bug will be fixed, you can additionally test None, e.g.

    - debug:
        msg: "Test passed. varexample: {{ item.varexample }}"
      when: item.varexample is undefined or
            item.varexample == None or
            item.varexample is match('^[a-zA-Z]+$')
      loop:
        - varexample: ABC
        - varexample: 123
        - varexample:

gives

ok: [localhost] => (item={'varexample': 'ABC'}) => 
  msg: 'Test passed. varexample: ABC'
skipping: [localhost] => (item={'varexample': 123}) 
ok: [localhost] => (item={'varexample': None}) => 
  msg: 'Test passed. varexample: '

Details

    - debug:
        msg: |
          Undefined: {{ item.varexample is undefined }}
          Is None: {{ item.varexample == None }}
          Match a-zA-Z: {{ item.varexample is match('^[a-zA-Z]+$') }}
      loop:
        - varexample: ABC
        - varexample: 123
        - varexample:
ok: [localhost] => (item={'varexample': 'ABC'}) => 
  msg: |-
    Undefined: False
    Is None: False
    Match a-zA-Z: True
ok: [localhost] => (item={'varexample': 123}) => 
  msg: |-
    Undefined: False
    Is None: False
    Match a-zA-Z: False
ok: [localhost] => (item={'varexample': None}) => 
  msg: |-
    Undefined: False
    Is None: True
    Match a-zA-Z: True
like image 167
Vladimir Botka Avatar answered May 01 '26 00:05

Vladimir Botka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!