Checking for undefined, empty or null variables

17,511 views
Skip to first unread message

jn.b...@gmail.com

unread,
Feb 14, 2018, 5:03:25 AM2/14/18
to Ansible Project

This is my example playbook:
---
 - name: play1
   hosts: app1
   vars_files:
   - "vars/app1.yml"

  tasks:
  - include_role:
      name: role1
    vars:
      applicationname: "{{ APPLICATIONNAME }}"
      description: "{{ DESCRIPTION }}"

Now in the role, I want to make sure applicationname is not undefined, empty or null.

It works when I use assert in the role:


/roles/defaults/main.yml
---
applicationname: ""
description: ""


/roles/tasks/main.yml

---
- assert:
    that:
      - (applicationname != "") and (
applicationname is not none) and (applicationname is defined)
    msg: "Variable '
applicationname' is null, empty or undefined"


But this is ugly when I have lots of variables in a role.



I tried the following approach:

/roles/defaults/main.yml
---
applicationname: ""
description: ""


required_vars:
 - applicationname


/roles/tasks/main.yml
---

- assert:
    that:
      - item != ""
      - item is not none
    msg: "A Variable is null, empty or undefined. But we don't know which one"
  with_items: "{{ required_vars }}"


This workes, but we don't know which variable is affected, this is also ugly.



Another approach:

- name: check required vars
  fail: msg="Variable '{{ item }}' is not defined"
  when: item not in vars
  with_items: "{{required_vars}}"


Workes, but you cannot check the value of the variable, just if it is not undefined.



How do I make sure that a lot of variables are not undefined, empty or null when passed to a role in a simple way?


Thanks for your help.

Regards
jn







Kai Stian Olstad

unread,
Feb 14, 2018, 5:49:58 AM2/14/18
to ansible...@googlegroups.com
On 14.02.2018 11:03, jn.b...@gmail.com wrote:
> Another approach:
>
> - name: check required vars
> fail: msg="Variable '{{ item }}' is not defined"
> when: item not in vars
> with_items: "{{required_vars}}"
>
> Workes, but you cannot check the value of the variable, just if it is
> not
> undefined.

This should work

when: vars[item] is not defined or vars[item] == ""

--
Kai Stian Olstad
Message has been deleted

jn.b...@gmail.com

unread,
Feb 14, 2018, 7:01:57 AM2/14/18
to Ansible Project
I was too fast with my answer.


/roles/defaults/main.yml
---
applicationname: ""
description: ""

required_vars:
 - applicationname





This workes:

- name: check required vars empty
  fail: msg="Variable '{{ item }}' is empty"
  when: vars[item] == ""
  with_items: "{{ required_vars }}"



This too:
- name: check required vars null
  fail: msg="Variable '{{ item }}' is null"
  when: vars[item] is none
  with_items: "{{ required_vars }}"




But this doesn't work:
- name: check required vars undefined
  fail: msg="Variable '{{ item }}' is null"

  when: vars[item] is not defined
  with_items: "{{ required_vars }}"



TASK [role1 : check required undefined] **********************************************
skipping: [server1] => (item=applicationname)  => {"changed": false, "item": "applicationname", "skip_reason": "Conditional result was False"}




I think

vars[item] is not defined
does not work because the variable "applicationname" in fact does have a value: "{{ APPLICATIONNAME }}"



TASK [role1 : debug] *******************************************************
ok: [server1] => {
    "vars": {
       "applicationname": "{{ APPLICATIONNAME }}"
    }
}

TASK [role1 : debug] *****************************************************************************************************************************************************************************************
ok: [server1] => {
    "applicationname": "VARIABLE IS NOT DEFINED!"
}


Any suggestions?




Kai Stian Olstad

unread,
Feb 14, 2018, 7:35:51 AM2/14/18
to ansible...@googlegroups.com
On 14.02.2018 13:01, jn.b...@gmail.com wrote:
> I was too fast with my answer.
>
> /roles/defaults/main.yml
> ---
> applicationname: ""
> description: ""
>
> required_vars:
> - applicationname
>

<snip />

> But this doesn't work:
> - name: check required vars undefined
> fail: msg="Variable '{{ item }}' is null"
> when: vars[item] is not defined
> with_items: "{{ required_vars }}"

It does, when I do a test

---
- hosts: localhost
gather_facts: false
vars:
required_vars:
- applicationname
tasks:

- name: check required vars when applicationname is not defined
debug: msg="Variable '{{ item }}' is not defined"
when: vars[item] is not defined
with_items: "{{ required_vars }}"

- set_fact:
applicationname: ''

- name: check required vars when applicationname is defined
debug: msg="Variable '{{ item }}' is not defined"
when: vars[item] is not defined
with_items: "{{ required_vars }}"

The output

TASK [check required vars when applicationname is not defined]
************************
ok: [localhost] => (item=applicationname) => {
"item": "applicationname"
}

MSG:

Variable 'applicationname' is not defined


TASK [set_fact]
***********************************************************************
ok: [localhost]

TASK [check required vars when applicationname is defined]
****************************
skipping: [localhost] => (item=applicationname)



> TASK [role1 : check required undefined]
> **********************************************
> skipping: [server1] => (item=applicationname) => {"changed": false,
> "item": "applicationname", "skip_reason": "Conditional result was
> False"}
>
>
>
> I think
> vars[item] is not defined
> does not work because the variable "applicationname" in fact does have
> a
> value: "{{ APPLICATIONNAME }}"

I don't understand where "{{ APPLICATIONNAME }}" comes from, you have
nothing like that in you code.

--
Kai Stian Olstad

jn.b...@gmail.com

unread,
Feb 14, 2018, 9:57:03 AM2/14/18
to Ansible Project
Hi Kai

You used the variable in a playbook, maybe that works. But I want to make sure that the role is not being executed when someone forgets to set the variable.
So the trick here is: "{{ APPLICATIONNAME }}" is not set.
Normaly this is a variable in vars/app1.yml
Here is the full code:


/vars/app1.yml
---
#APPLICATIONNAME: "app1"
#normally this var is set, but we want to provoke an error




playbook.yml

---
 - name: play1
   hosts: app1
   vars_files:
   - "vars/app1.yml"

  tasks:
  - include_role:
      name: role1
    vars:
      applicationname: "{{ APPLICATIONNAME }}"
      description: "{{ DESCRIPTION }}"






/roles/defaults/main.yml
---
required_vars:
 - applicationname

applicationname: ""
description: ""







/role/tasks/main.yml
---
- debug:
    var: vars

- debug:
    var: applicationname


- name: check required vars when applicationname is not defined
  debug: msg="Variable '{{ item }}' is not defined"
  when: vars[item] is not defined
  with_items: "{{ required_vars }}"





Execution:


TASK [role1 : debug] ***********************************************

ok: [server1] => {
    "vars": {

        "applicationname": "{{ APPLICATIONNAME }}"
    }
}

TASK [role1 : debug] ********************************************************
ok: [SERVER1] => {

    "applicationname": "VARIABLE IS NOT DEFINED!"
}

TASK [role1 : check required vars when applicationname is not defined] *******************************

skipping: [server1] => (item=applicationname)  => {"changed": false, "item": "applicationname", "skip_reason": "Conditional result was False"}





Or is my approach completely wrong?





Kai Stian Olstad

unread,
Feb 14, 2018, 1:06:57 PM2/14/18
to ansible...@googlegroups.com
On Wednesday, 14 February 2018 15.57.02 CET jn.b...@gmail.com wrote:
> Hi Kai
>
> You used the variable in a playbook, maybe that works. But I want to make
> sure that the role is not being executed when someone forgets to set the
> variable.
> So the trick here is: "{{ APPLICATIONNAME }}" is not set.
> Normaly this is a variable in vars/app1.yml
> Here is the full code:

The full code make is clear whats happening.


> /vars/app1.yml
> ---
> #APPLICATIONNAME: "app1"
> #normally this var is set, but we want to provoke an error
>
>
>
> playbook.yml
> ---
> - name: play1
> hosts: app1
> vars_files:
> - "vars/app1.yml"
>
> tasks:
> - include_role:
> name: role1
> vars:
> applicationname: "{{ APPLICATIONNAME }}"
> description: "{{ DESCRIPTION }}"
>
>
> /roles/defaults/main.yml
> ---
> required_vars:
> - applicationname
>
> applicationname: ""
> description: ""

role default will always set applicationname to "" and therefor always be defined.
So checking if that variable "is not defined" has no purpose since it will be defined.


--
Kai Stian Olstad

jn.b...@gmail.com

unread,
Feb 15, 2018, 2:51:46 AM2/15/18
to Ansible Project
I don't fully agree with you.
Because I set "applicationname" to "{{ APPLICATIONNAME }}" when I call the role in the playbook:



- include_role:
    name: role1
  vars:
    applicationname: "{{ APPLICATIONNAME }}"
    description: "{{ DESCRIPTION }}"


Problem is, that "{{ APPLICATIONNAME }}" at this point is undefined.

And again, I think the problem with
- name: check required vars when applicationname is not defined
  debug: msg="Variable '{{ item }}' is not defined"
  when: vars[item] is not defined
  with_items: "{{ required_vars }}"


is, that vars[item] is not undefined.
Why? Because "applicationname" seems to have a value:


TASK [role1 : debug] ***********************************************

ok: [server1] => {
    "vars": {

        "applicationname": "{{ APPLICATIONNAME }}"
    }
}

Maybe it is misinterpreted as a string "{{ APPLICATIONNAME }}"
Therefore,
when: vars[item] is not defined does not work as expected

Hope you can follow me.







Reply all
Reply to author
Forward
0 new messages