Boolean values act strangely.

1,781 views
Skip to first unread message

C. Morgan Hamill

unread,
Apr 15, 2013, 11:38:27 AM4/15/13
to ansible-project
So, here's an example playbook:

- hosts: whatever
vars:
foo: yes
tasks:
- debug: msg={{ doit }}

This prints "True". Changing 'foo' to 'no', or '0', or 'false' causes
the above to print "False". This is as expected.

If I call the playbook and pass an extra var to it like so:

-e "foo=yes"

Then the above now prints "no" instead.

It seems that things passed in as extra vars do not get interpreted as
a booleans and replaced with True/False before being passed on to the
rest of the playbook.

This causes strange issues when trying to use extra vars in templates,
and also when using them in the new 1.2 "when" syntax.

Not sure what's going on --- was this always the case?
--
Morgan Hamill
<cha...@wesleyan.edu>

C. Morgan Hamill

unread,
Apr 15, 2013, 11:44:38 AM4/15/13
to ansible-project
Excerpts from C. Morgan Hamill's message of 2013-04-15 11:38:27 -0400:
> Then the above now prints "no" instead.

s/"no"/"yes"

Michael DeHaan

unread,
Apr 15, 2013, 4:13:33 PM4/15/13
to ansible...@googlegroups.com
You seem to be missing something in your copy/paste as the variable is named foo in one place and doit in the other.

Is there a conditional somewhere?

Note YAML interprets "foo: yes" as a Boolean, you would have to quote strings to keep them strings.





--
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.
For more options, visit https://groups.google.com/groups/opt_out.





--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

C. Morgan Hamill

unread,
Apr 15, 2013, 4:28:34 PM4/15/13
to ansible-project
Excerpts from Michael DeHaan's message of 2013-04-15 16:13:33 -0400:
> You seem to be missing something in your copy/paste as the variable is
> named foo in one place and doit in the other.S

Ahh, sorry about that; the variable was supposed to be the same in both
places.

> Note YAML interprets "foo: yes" as a Boolean, you would have to quote
> strings to keep them strings.

I'm aware of the yaml behavior, but the issue I'm having is instead
this:

If you specify a value in a playbook or vars file or whatnot, things
like "yes" and "no" become real booleans, as expected.

If you specify a value via -e, and use something like "yes" or "no" as
it's value, the value stays a string.

So:

- hosts: 127.0.0.1
vars:
foo: yes
tasks:
- debug: msg="{{ foo }}"

prints 'True', while:


- hosts: 127.0.0.1
tasks:
- debug: msg="{{ foo }}"

called with a -e "foo=yes" prints 'yes'.

The inconsistency there is what I'm wondering about.
--
Morgan Hamill
<cha...@wesleyan.edu>

Michael DeHaan

unread,
Apr 15, 2013, 4:56:21 PM4/15/13
to ansible...@googlegroups.com
You will probably have to use a Jinja2 filter to cast the type.





--
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.
For more options, visit https://groups.google.com/groups/opt_out.


Kahlil Hodgson

unread,
Apr 15, 2013, 6:47:01 PM4/15/13
to ansible...@googlegroups.com
If I am understanding this correctly,
 
1. Data from files is YAML data first, with the associated "magic" casting to boolean types.
2. YAML string values have their {{Jinja2}} fragments interpolated
3. The result is converted to internal ansible (python) data structures

But with the -e "foo=yes" we skip straight to internal ansible data and there is no "magic" boolean casting,
which makes sense because "foo=yes" is not YAML. Is this correct?

If --extra-vars took YAML syntax like 'foo: yes' or  'foo: "{{ yes }}"', we might expect something different.

Kal

--
Kahlil (Kal) Hodgson                       GPG: C9A02289
Head of Technology                         (m) +61 (0) 4 2573 0382
DealMax Pty Ltd                            (w) +61 (0) 3 9008 5281

Suite 1415
401 Docklands Drive
Docklands VIC 3008 Australia

"All parts should go together without forcing.  You must remember that
the parts you are reassembling were disassembled by you.  Therefore,
if you can't get them together again, there must be a reason.  By all
means, do not use a hammer."  -- IBM maintenance manual, 1925

Michael DeHaan

unread,
Apr 15, 2013, 6:59:07 PM4/15/13
to ansible...@googlegroups.com
It has nothing to do with foo=yes not being YAML.

It does have to do with the value of foo being a string when fed into the variable system and "--extra-vars" not knowing to booleanify things.

We could certaintly apply this but I'd be afraid of breaking existing content.

You can definitely check for "foo == 'yes'" in the conditional here if you don't want to cast it.


--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Kahlil Hodgson

unread,
Apr 15, 2013, 7:19:21 PM4/15/13
to ansible...@googlegroups.com

On Tue, Apr 16, 2013 at 8:59 AM, Michael DeHaan <mic...@ansibleworks.com> wrote:
It has nothing to do with foo=yes not being YAML.

Obviously not had enough coffee to express myself clearly. 

What I meant was 'foo=yes' on the command line does not _look_ like YAML, so we should not _expect_ it to behave like YAML.

I'm assuming 'foo: yes' in an ansible YAML file gets the boolean cast via some python library for importing YAML and not via ansible's variable system?

Michael DeHaan

unread,
Apr 15, 2013, 7:27:12 PM4/15/13
to ansible...@googlegroups.com
It's just fed to the variable system to be avialable in templating/other usage, well-post YAML parsing...


--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

C. Morgan Hamill

unread,
Apr 16, 2013, 10:33:52 AM4/16/13
to ansible-project
Excerpts from Michael DeHaan's message of 2013-04-15 18:59:07 -0400:
> We could certaintly apply this but I'd be afraid of breaking existing
> content.

Yeah, it's not a big deal; just wondering. The behavior is a bit
surprising, but so it goes.
--
Morgan Hamill
<cha...@wesleyan.edu>

Ikrom Hotamov

unread,
Nov 26, 2013, 9:10:32 PM11/26/13
to ansible...@googlegroups.com
Hi guys,

Not sure if this has been resolved, but I'm getting really strange behavior with my playbooks in version 1.4. This has nothing to do with --extra-vars, but a boolean variable defined in the "vars" section. Or am I defining it somewhat incorrectly?

Here is an example:

- hosts: 127.0.0.1
  vars:
    myvar: "{{ 'foo' == 'bar' }}"

  tasks:
    - name: print var value
      command: /bin/echo {{ myvar }}

    - name: this should run
      command: /bin/echo whatever
      when: not myvar

    - name: this should not run
      command: /bin/echo whatever
      when: myvar



This prints "False" for the first task and skips both the other tasks. However, if I change the "when" statements to myvar|bool, it works as expected.
So it seems myvar contains the string representation of the boolean expression returned from the statement.
Is there a way to have the variable of type boolean, or do I always have to explicitly pipe it to the Jinja bool filter?

Michael DeHaan

unread,
Nov 26, 2013, 10:30:17 PM11/26/13
to ansible...@googlegroups.com
So I'd request everyone please don't reply to ancient threads, things change and initial questions are seldom related to the old if you think they might be.

Saving a conditional in a variable should probably not involve a template statement, the need to do this in conditionals has been gone for some time.

We can dig and try to reproduce this later.
Reply all
Reply to author
Forward
0 new messages