Vagrant: Boolean variables treated incorrectly in ansible host_vars

Created on 27 Apr 2018  ·  6Comments  ·  Source: hashicorp/vagrant

Vagrant version

Vagrant 2.0.4

Host operating system

Ubuntu 16.04

Guest operating system

Centos 7

Vagrantfile

Vagrant.configure(2) do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.define "centos-test"

  config.vm.provision :ansible do |ansible|
    ansible.playbook = '../ansible/testing-centos.yml'
    ansible.limit = 'all'
    ansible.tags = 'init'
    ansible.extra_vars = {
        proxy_host: false
    }
    ansible.groups = {
      "deploy" => ["centos-test"]
    }

    ansible.host_vars = {
      "centos-test" => {
        proxy_host: false,
        pretty_name: "Centos",
        client_name: "centos",
        mysql_host: "localhost",
        mysql_user: "test-centos",
        mysql_db_name: "test-centos",
        ldapauth: false,
        ldap: false
      }
    }

  end
end

Expected output

ok: [centos-test] => {
    "proxy_host": false
}

Actual output

ok: [centos-test] => {
    "proxy_host": "false"
}

Expected/Actual behavior

Add a debug var statement to ansible to see. Play around with the extra_vars in the Vagrantfile. I have found that when using the host_vars alone it treats the boolean variable as a string, when it is defined in extra_vars it correctly treats it as a boolean.

Steps to reproduce

Make use of a boolean variable in an ansible playbook, in this case, a debug statement is sufficient to see the results.

- debug:
    var: proxy_host

If you define proxy_host as a host variable it will treat it as a string, breaking playbooks. If you define it in the extra_vars hash it works, so there must be some difference in the way each section of vars is processed.

bug provisioneansible provisioneansible_local upstream

Most helpful comment

Hi Chris,

Can confirm the issue is present on Vagrant 2.0.4. Have updated the initial post so as not to confuse future readers!

All 6 comments

Hi there,

The Vagrant version you are currently using is extremely old and there have been many updates to the ansible provisioner since the 1.8.1 release. Would you please install the latest version of Vagrant and see if it resolves your issue.

Thanks!

Hi Chris,

Can confirm the issue is present on Vagrant 2.0.4. Have updated the initial post so as not to confuse future readers!

@bencromwell In fact, Ansible behaves differently depending on how/where the variables are set.

As explained in details below, I think that there is no (- at least: no reasonable/affordable) way for the Vagrant Ansible provisioners to give more support there, as these issues are present upstream, in Ansible itself.

For variables set in the Ansible inventory (either group or host vars):

From Ansible Documentation:

Values passed in the INI format using the key=value syntax are not interpreted as Python literal structure (strings, numbers, tuples, lists, dicts, booleans, None), but as a string. For example var=FALSE would create a string equal to ‘FALSE’. Do not rely on types set during definition, always make sure you specify type with a filter when needed when consuming the variable.

This explains why the boolean type is not considered, and the Vagrant provisioners can't provide any solution as the purpose of host_vars and groups options is to put the variables into the generated inventory (in INI format).

Possible approach: As Ansible documentation says, always filter the variable when consuming it: {{ proxy_host | bool }}

For variables passed on the command line (via --extra-vars argument):

From Ansible Documentation:

Values passed in using the key=value syntax are interpreted as strings. Use the JSON format if you need to pass in anything that shouldn’t be a string (Booleans, integers, floats, lists etc).

When the extra_vars option is a hash (like in your case), the Vagrant Ansible provisioner will pass a JSON-formatted extra-vars argument to Ansible. This explains why the boolean type is considered.

For variables defined in host_vars and group_vars YAML files

I personally prefer to specify most of my variables this way, having for instance some group(s) specific to the vagrant environment:

In group_vars/vagrant (or group_vars/deploy, or whatever you like):

---
proxy_host: no
pretty_name: Centos
# etc

References:

About my recommendation on using host_vars and group_vars construct, see also:

From Ansible Documentation:

The preferred practice in Ansible is to not store variables in the main inventory file.

Closing per above comments. Adding some notes or examples into the docs might help to reduce the confusion, although Ansible documentation is already quite clear.

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

StefanScherer picture StefanScherer  ·  3Comments

rrzaripov picture rrzaripov  ·  3Comments

barkingfoodog picture barkingfoodog  ·  3Comments

OtezVikentiy picture OtezVikentiy  ·  3Comments

dorinlazar picture dorinlazar  ·  3Comments