Testing for a defined but non empty string

Best to explain with an example

We have tasks setup like

  • name: do something
    shell: do task
    when: foo is defined

This works perfectly for most situations however we have a number of places where we need to unset the variable to stop the command on certain hosts. Neither of the following work when set in the group vars and result in the task working.

foo:
foo: “”

So my question is how would one normally unset a variable like this or correctly test for it. Jinja docs suggest its just an “if variable” [1], so “when: foo” but that doesn’t work whenever the variable has a value

fatal: [127.0.0.1] => error while evaluating conditional: foo

The closest I’ve gotten is
when: foo is defined and foo is string
but this feels wrong and there is no reference to using an “is string” check in the ansible docs.

[1] http://jinja.pocoo.org/docs/templates/#if

If setting it to an empty string when you don't want it to run is okay
for your use case, you could do:

when: foo|default("") != ""

That will compare against the value of foo when it's defined, and
otherwise compare against an empty string.

Thanks, that will work in the case of foo: “”. Before I go about switching all our templates, is there a way to also make it work in the case of foo: , i.e. without the empty string defined? Ansible detects these as None

Yes, if Ansible sees that as None, then you could use |default(None) like this:

when: foo|default(None) != None

foo is defined and foo !+ "" or "default-value"

I faced the same problem.

I tried Nick Groenen’s code and it doesn’t work when the params is like this:

foo:

in this case, foo is define and foo == none

And it doesn’t work when foo: ’ ’

This is what I came up with:

not((foo is undefined) or (foo is none) or (foo|trim == ‘’))

Not sure if there is any build-in function that implement similar logic.

Cheers

Leo Liang

在 2014年1月31日星期五 UTC+11下午10:58:17,Stephen Ryan写道:

@ Leo Thanks, this work for me as well

Why is this not in the documentation for conditionals? it should be basic stuff!!!

Tell me about it Leo, the documentation on this language is seriously lacking.

Is there really no better way to do it? While Leo’s method works it’s extremely ugly to look at nor easily reusable.

I think the iptables rule that I found on galaxy uses the following to
set a variable to empty:

foo: {}

Maybe this works in your case, too?

Johannes

Would this help you?

  • name: do something
    shell: do task
    when: ansible_local[foo] is defined

Instead of using ansible_local (which holds local facts), you could also use:

vars

hostvars

both of them are dictionaries with key/value pairs.

More info - http://docs.ansible.com/ansible/playbooks_variables.html