Weird set_fact boolean problem

440 views
Skip to first unread message

Michael Peters

unread,
Aug 13, 2014, 11:11:18 AM8/13/14
to ansible...@googlegroups.com
Before I file a ticket, I just want to make sure I'm not doing
anything wrong. BTW, this is a simplified example to reproduce the
problem, not what I was actually trying to do. I have this simple
playbook test.yml:

---
- hosts: 127.0.0.1
connection: local
tasks:
- set_fact: foo=false

- command: ls /
when: not foo

Executed like this:

ansible-playbook -i '127.0.0.1,' test.yml


Which results in the following output:
PLAY [127.0.0.1] **************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [set_fact foo=false] ****************************************************
ok: [127.0.0.1]

TASK: [command ls /] **********************************************************
skipping: [127.0.0.1]

Notice the last task is skipped. So for some reason it's not following
the logic of the when clause like I'd expect. But the really weird
thing is that if I change the task to say "when: foo" (reverse the
logic) I get the same output:

---
- hosts: 127.0.0.1
connection: local
tasks:
- set_fact: foo=false

- command: ls /
when: foo

Executed like this: ansible-playbook -i '127.0.0.1,' test.yml

PLAY [127.0.0.1] **************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [set_fact foo=false] ****************************************************
ok: [127.0.0.1]

TASK: [command ls /] **********************************************************
skipping: [127.0.0.1]

Same output. So even if something with my logic was wrong (for
instance set_fact didn't like the literal "false") you would still
think that taking out the "not" would result in the task being
executed.

ansible 1.8 (devel 9edf3a749a) last updated 2014/08/13 14:03:10 (GMT +000)

Am I doing something wrong? Or should I file a bug report?

Matt Martz

unread,
Aug 13, 2014, 11:19:25 AM8/13/14
to ansible...@googlegroups.com
What is happening is that you are effectively setting foo to the string "false"

What you likely want to do is:

    when: not foo|bool
--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/CAJQqANdAt%3D3PB30cEDMqknJHY%2BAr3VwpxePrgN4J-dvfeZUWGQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


--
Matt Martz
ma...@sivel.net
http://sivel.net/

Michael Peters

unread,
Aug 13, 2014, 11:31:26 AM8/13/14
to ansible...@googlegroups.com
Is there a way to use set_fact to force it to use a real boolean
instead of the string? In the real playbook other tasks and includes
further down don't care where the var came from and I'd rather not
have to alter every boolean to run things through the bool filter just
in case the var came from set_fact.

I tried

- set_fact: foo={{ false }}
and
- set_fact: foo={{ false | bool }}

But neither of those work.
> https://groups.google.com/d/msgid/ansible-project/CAD8N0v_XppVmJ_%3DzxCn7NrbbyAOjLueX%2BqJz%2Ba23nQq62vTJBA%40mail.gmail.com.

Matt Martz

unread,
Aug 13, 2014, 12:26:37 PM8/13/14
to ansible...@googlegroups.com
If you use the pure YAML complex args way of invoking a module, you can make it an actual boolean:

- set_fact:
    foo: False

But due to the fact that you cannot do that with jinja2 variable expansion and such, I'd recommend just sticking to using the |bool filter at evaluation time.  It's more reliable and safer that way.



For more options, visit https://groups.google.com/d/optout.

Michael DeHaan

unread,
Aug 13, 2014, 12:46:01 PM8/13/14
to ansible...@googlegroups.com
"But due to the fact that you cannot do that with jinja2 variable expansion and such,"

- set_fact:
     foo: "{{ x }}"

The system will preserve complex dict/list types, I haven't tried it with boolean types recently.


Michael Peters

unread,
Aug 13, 2014, 1:42:25 PM8/13/14
to ansible...@googlegroups.com
Thanks, this works.

I was under the impression that the 2 syntax variants (yaml vs
key-value) worked the same. Is this something that should be fixed or
just documented as a difference?

On Wed, Aug 13, 2014 at 12:25 PM, Matt Martz <ma...@sivel.net> wrote:
> https://groups.google.com/d/msgid/ansible-project/CAD8N0v8UM%3DiKL2%2B0N-voLv7a42gn5Ay5dEB9-%2B0SEaKgHiFouA%40mail.gmail.com.

Michael Peters

unread,
Aug 13, 2014, 1:43:38 PM8/13/14
to ansible...@googlegroups.com
Also, isn't it weird the with the variable foo set to string "false"
both "when: foo" and "when: not foo" evaluate to false?

Michael DeHaan

unread,
Aug 14, 2014, 7:46:33 AM8/14/14
to ansible...@googlegroups.com
"Is this something that should be fixed or
just documented as a difference?"

Nope.  It's fine, because the system has no hint to decide you asked for anything other than a string.




Michael DeHaan

unread,
Aug 14, 2014, 7:47:58 AM8/14/14
to ansible...@googlegroups.com
"Also, isn't it weird the with the variable foo set to string "false"
both "when: foo" and "when: not foo" evaluate to false?"

This is a programming language concept.

No, as the string 'false' in Python or any prograis not the same as False.

there is a difference between these two:

vars:
    x: "false"
    x: false

The above quoted one is a string whose value is the word "false" and it's important the word doesn't get auto-converted into a boolean.




Michael Peters

unread,
Aug 14, 2014, 9:08:57 AM8/14/14
to ansible...@googlegroups.com
Yes, I realize the difference between a string and a boolean. But I've
never seen a system where "foo" and "not foo" evaluate to the same
thing.
> https://groups.google.com/d/msgid/ansible-project/CA%2BnsWgyWXrt-aZz-marw61BSRsXQpMWnw2CN_0r%3Da-MQ0NuDsA%40mail.gmail.com.

Michael DeHaan

unread,
Aug 14, 2014, 9:25:50 AM8/14/14
to ansible...@googlegroups.com
"both "when: foo" and "when: not foo" evaluate to false?"

Don't recall it ever working that way.

Can you share a playbook that reproduces this?



Michael Peters

unread,
Aug 14, 2014, 9:42:08 AM8/14/14
to ansible...@googlegroups.com
Sure: test.yml

---
- hosts: 127.0.0.1
connection: local
tasks:
- set_fact: foo=false

- command: ls /
when: foo

- command: ls /
when: not foo

Executed like "ansible-playbook -i '127.0.0.1,' test.yml"

Results in both tasks being skipped:

PLAY [127.0.0.1] **************************************************************

GATHERING FACTS ***************************************************************
ok: [127.0.0.1]

TASK: [set_fact foo=false] ****************************************************
ok: [127.0.0.1]

TASK: [command ls /] **********************************************************
skipping: [127.0.0.1]

TASK: [command ls /] **********************************************************
skipping: [127.0.0.1]

> https://groups.google.com/d/msgid/ansible-project/CA%2BnsWgzxAFA3NqY7UTiAMdWXrUxR63ksfFHu3ANv%3Du6BXpzLvA%40mail.gmail.com.

Michael DeHaan

unread,
Aug 14, 2014, 1:24:13 PM8/14/14
to ansible...@googlegroups.com
The inconsistent booleanification is definitely not something I'd want to see here.

Can you please file a bug on github for this one?




Michael Peters

unread,
Aug 14, 2014, 2:04:32 PM8/14/14
to ansible...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages