linuxautomationansibleyaml

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?


Solution

  • 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