Vagrant: Vagrant not quoting host_vars in Ansible inventory file

Created on 17 May 2017  ยท  5Comments  ยท  Source: hashicorp/vagrant

Vagrant version

1.9.5

Host operating system

OS X 10.12.4

Guest operating system

Debian 8

Expected behavior

Vagrant should quote Ansible host variables when generating an inventory file.

Actual behavior

It doesn't, and then pukes.

More Info

When generating the Ansible host file, I'm using "host_vars" like so...

  cfg.vm.provision :ansible do |a|
    a.host_vars = ansible_host_vars
  end

Problem is, it's not quoting strings that should be quoted...generating something like this:

cb-beta-app-1 ansible_ssh_host=173.255.247.7 ansible_ssh_port=22 hostname=cb-beta-app-1 vpn_hostname=vpn_app_1 vpn_ip=10.0.0.20 datacenter=fremont linode_plan=Linode 2048

The last variable there "linode_plan" should be quoted. The space inside throws off vagrant provision and causes the following errors with Ansible:

ERROR! Attempted to read "/Users/seth/Work/cashboard/app/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory" as YAML: 'AnsibleUnicode' object has no attribute 'keys'
Attempted to read "/Users/seth/Work/cashboard/app/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory" as ini file: /Users/seth/Work/cashboard/app/.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory:2: Expected key=value host variable assignment, got: 2048
Ansible failed to complete successfully. Any error output should be
visible above. Please fix these errors and try again.
bug provisioneansible

All 5 comments

FWIW, it looks like provisioners/ansible/provisioner/base.rb line 151. If you change...

s = vars.each.collect{ |k, v| "#{k}=#{v}" }.join(" ")

...to...

s = vars.each.collect{ |k, v| "#{k}=\"#{v}\"" }.join(" ")

I think it should be good.

@subimage This is actually a known issue (see #8158).

In this case, you need to explicitly apply quotes where necessary, for instance:

ansible.host_vars = {
  "cb-beta-app-1" => {
    "hostname" => "cb-beta-app-1",
              ...
    "linode_plan" => "'Linode 2048'",
  }
}

(See also https://www.vagrantup.com/docs/provisioning/ansible_common.html#host_vars)

I know it's confusing and not very "friendly", but I'm afraid if always putting these quotes could potentially break things in existing Vagrant configurations. I'm also unsure about try to add a "smarter" behaviour (automatically quote _only when necessary_, i.e. if this is an unquoted text that contains blank characters).

For all these reasons, I considered this issue as "low priority" and preferred to stick to this "basic" behaviour (KISS). But I'm open to accept the addition of the "smarter" behaviour described above, but not to always set the double quotes as proposed in #8158.

I'm closing, but feedbacks (or pull request) are welcome. Thanks!

A farily safe smarter behavior would be pretty trivial to code...example:

s = vars.each.collect do |k, v| 
  if v.include?(' ') && !v.match(/^('|").*('|")$/)
    v = %Q|"#{v}"|
  end
  "#{k}=#{v}" 
end
s.join(" ")

I understand your concern, but I believe it to be a bit overblown. Right now this is breaking configurations and causing confusion.

If you have to resort to a documentation explanation to "fix" this, I don't believe it's a solid approach. "Gotchas" are never beneficial in product design.

@subimage I agree, and your patch looks good.

Adding test coverage, and it will be all set to be merged. I reopen the issue to keep it on the radar. Pull request welcome, if someone is interested to accelerate the things...

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

lebogan picture lebogan  ยท  3Comments

hesco picture hesco  ยท  3Comments

RobertSwirsky picture RobertSwirsky  ยท  3Comments

rrzaripov picture rrzaripov  ยท  3Comments

Cbeck527 picture Cbeck527  ยท  3Comments