-
Notifications
You must be signed in to change notification settings - Fork 4.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vagrant 1.8, ansible_local extra_vars
being ignored
#6726
Comments
extra_vars
being ignoredextra_vars
being ignored
Hi @elsom25, thanks for your problem report. This looks strange, but likely to be an Ansible (usage) issue. Could you please log into the machine (
I'd expect you get the same result... |
Hey @gildegoma: as you suspect, it fails the same way. Looking through ansible docs for --extra-vars, I can't find anything that suggests there's support for a raw hash, but rather, it seems it expects quoted json. Testing this out by changing the command to:
Leads to the values being set correctly. |
@elsom25 thanks for checking. It's indeed a bug in Until it's fixed, you can store these extra variables in a YAML or JSON file, and use something like Note that the |
i was about to open a pull request... but since @gildegoma mentions it is not necessary for the since the ansible documentation uses single quotes around the
and then the ruby hash is properly passed on to ansible as a single quoted JSON string.
EDIT: that does not work when using more than one element in the hash. then bash interprets the the resulting
|
The weird doublequoting is necessary due to a vagrant bug: hashicorp/vagrant#6726
I've just stumbled upon the same issue and dared to open a PR that fixes it. @gildegoma looks like childprocess doesn't mind such quoting because I was able to provision my machine with both |
@kamazee thanks a lot for the PR, I'll check it asap (i.e. not right now 😉) |
Install REX-Ray into a CentOS 7 box using Ansible. To prevent users from having to have Ansible installed locally, use the ansible_local provisioner, which will run Ansible fromw within the guest. This requires Vagrant 1.8+, and at this time still doesn't quite work until hashicorp/vagrant#6726 is fixed.
+1 for this fix from me, I am trying to pass proxy settings through the ansible provisioner ansible.extra_vars = {
proxy_env: {
http_proxy: ENV['http_proxy'] || "",
https_proxy: ENV['http_proxy'] || ""
}
} but all what comes out in the command line arg is unquoted web: Running ansible-playbook...
PYTHONUNBUFFERED=1 \
ANSIBLE_FORCE_COLOR=true \
ANSIBLE_HOST_KEY_CHECKING=false \
ansible-playbook --connection=ssh --timeout=30 \
--extra-vars=ansible_ssh_user='vagrant' \
--limit='web.vagrant.dev' \
--inventory-file=./inventory \
--extra-vars={"proxy_env":{"http_proxy":"http://proxy:8888","https_proxy":"http://proxy:8888"}} \
--sudo site.yml whilst web: Running ansible-playbook...
PYTHONUNBUFFERED=1 \
ANSIBLE_FORCE_COLOR=true \
ANSIBLE_HOST_KEY_CHECKING=false \
ansible-playbook --connection=ssh --timeout=30 \
--extra-vars=ansible_ssh_user='vagrant' \
--limit='web.vagrant.dev' \
--inventory-file=./inventory \
--extra-vars='{"proxy_env":{"http_proxy":"http://proxy:8888","https_proxy":"http://proxy:8888"}}' \
--sudo site.yml |
@fdemmer I modified your approach slightly to also escape the quotes after the extra_vars hash is converted to JSON. Now it does work properly for me. def extra_vars_argument
if config.extra_vars.kind_of?(String) and config.extra_vars =~ /^@.+$/
# A JSON or YAML file is referenced.
config.extra_vars
else
# Expected to be a Hash after config validation.
"'#{config.extra_vars.to_json.gsub("\"", %q(\\\"))}'"
end
end |
I've worked around this issue by using raw arguments. This doesn't work: ansible.extra_vars = {
provider: "virtualbox"
} This does: ansible.raw_arguments = [
"--extra-vars",
"provider=virtualbox"
] I hope it can be fixed before 1.8.2. |
Is this issue holding up the 1.8.2 release? I noticed it's not in the 1.8.2 milestone, though one other ticket in that milestone mentioned this ticket as a dependency... |
@geerlingguy no, there is no hold up ;-) Of course, I hope this issue will also be fixed for the next Vagrant release 😃 @kamazee I actually started to review #6820 some days ago, and found some problems (which I don't remember right now). I'll comment directly onto the PR (but no commitment about the deadline, sorry). |
@gildegoma can you please double-check about those comments? i'd like to help, but don't see any comments in the code or conversation of pr #6820 besides the "needs-review" label and #6800 also only mentions "needs review", left the checkbox open, but still merged. |
@fdemmer #6820 will be reviewed (I haven't started yet, sorry). If you want to help, you chan also check it out and bring your feedbacks on the PR thread. That would be great :) For the records: I initially thought to address this issue via #6800. But I finally decided to merge this "growing beast" to get all these other fixes into master branch (I usually prefer to keep one PR focused on one Issue). I updated #6800 description, hoping to make things more clear... |
Let's flag it for Milestone 1.8.2... |
Without this change, the JSON string generated from the `extra_vars` Ruby hash is passed without enclosing quotes and is then not parseable by the ansible-playbook command when exectuted in a usual shell context. In this changeset, the ansible (remote) unit test coverage is improved to cover both usage of `extra_vars` (ansible_local unit tests are still missing). Additional Notes: - Double quotes are favored to single quotes in order to allow usage of any character for the variable values. For this reason additional escaping is appended to JSON-inner double quotes and backslashes. - This problem was not affecting the `ansible` remote provisioner (which is running the ansible-playbook command via the childprocess Ruby library). But with this change, the `verbose` output will also now be correct for a copy-paste reuse. - After this change, all the "--extra-vars" arguments (also a var file passed with the @-syntax or anything coming via the `raw_arguments` option) are "blindly" and systematically enclosed in double quoted and double-escaped. This is not optimal and can potentially break with peculiar values (e.g. a double quote character (") cannot be used in a json value when using `raw_arguments`). That said, I think that the current solution is a reasonable trade-off, since the official `extra_vars` option should now be able to cover a great majority of use cases. Fix #6726
My workaround (Vagrant 1.8.1, ansible_local 1.9.5):
|
fixed with #7103 imho. sorry, for being annoying, but is there an eta for 1.8.2? would help a fellow developer on windows a lot... |
With cb80286, the helper function stringify_ansible_playbook_command was also applied on the `raw_arguments` content, which is not wanted. Given that users have used the `raw_arguments` option as a workaround to avoid the bug GH-6726, this new change ensure that any `--extra-vars` option passed as a raw argument won't be additonally enquoted by the ansible_local provisioner. This change also improves the ansible remote provisioner verbose output, but has no impact on its behaviour, which was already correct. Note that this refactoring introduces some code duplications that are not very elegant (see ansible_playbook_command_for_shell_execution in host.rb and execute_ansible_playbook_from_host in base.rb). I hope we can find a better implementation later, but it is good enough for now since all these parts are covered by corresponding unit tests (the `ansible_local` stuff being tested via the verbose output of the ansible remote provisioner).
Below a simple test to verify the fix. Vagrant versionVagrant 1.8.1 Ansible version (also affects 1.9.x in exact same way)ansible-playbook 2.0.1.0 Host operating systemOSX 10.11.4 Guest operating systemCentos7 / any linux that can be targeted by ansible really Vagrantfile# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
if Vagrant.has_plugin?("vagrant-vbguest")
config.vbguest.auto_update = false
end
# provisioning ansible
config.vm.provision "ansible" do |ansible|
ansible.playbook = "play.yml"
ansible.verbose = "vvvv"
ansible.extra_vars = {
# send a string of generated keycloak servers to the haproxy
extra1: Array.new(3){ |n| "bla#{(1 + n).to_s.rjust(2,'0')}" },
extra2: true
}
end # ansible provisioning
end play.yml---
- hosts: all
# strategy: debug
gather_facts: no
tasks:
- debug: var=extra1
- fail: msg="extra1 arg not set"
when: extra1 is undefined Debug output$ vagrant provision
==> default: Running provisioner: ansible...
default: Running ansible-playbook...
PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true
ANSIBLE_HOST_KEY_CHECKING=false
ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s'
ansible-playbook --connection=ssh --timeout=30 --limit='default' \
--inventory-file=/Users/fred/workspaces/extraargs/.vagrant/provisioners/ansible/inventory \
--extra-vars='{"extra1":["bla01","bla02","bla03"],"extra2":true}'\
-vvvv play.yml
No config file found; using defaults
Loaded callback default of type stdout, v2.0
1 plays in play.yml
PLAY ***************************************************************************
TASK [debug] *******************************************************************
task path: /Users/fred/workspaces/extraargs/play.yml:6
ok: [default] => {
"extra1": "VARIABLE IS NOT DEFINED!"
}
PLAY RECAP *********************************************************************
default : ok=1 changed=0 unreachable=0 failed=1 Expected behaviorExtra args should be passed properly to the ansible playbook executable: PYTHONUNBUFFERED=1 \
ANSIBLE_FORCE_COLOR=true \
ANSIBLE_HOST_KEY_CHECKING=false \
ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' \
ansible-playbook --connection=ssh \
--timeout=30 \
--limit='default' \
--inventory-file=./.vagrant/provisioners/ansible/inventory \
--extra-vars='{"extra1":["bla01","bla02","bla03"],"extra2":true}' \
-vvvv play.yml
No config file found; using defaults
Loaded callback default of type stdout, v2.0
1 plays in play.yml
PLAY ***************************************************************************
TASK [debug] *******************************************************************
task path: /Users/fred/workspaces/extraargs/play.yml:6
ok: [default] => {
"extra1": [
"bla01",
"bla02",
"bla03"
]
}
PLAY RECAP *********************************************************************
default : ok=1 changed=0 unreachable=0 failed=0 Actual behaviorWhat actually happened?
Steps to reproduce
|
@bertramn thank you very much for your test case. I really appreciate to get more people involved in the "quality assurance" process 👍 😄 From your report, I think that you are testing it with a wrong fix (maybe #6820), as your output is single quoted, not double quoted. If you run it with with ==> machine1: Running provisioner: ansible...
machine1: Running ansible-playbook...
PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true \
ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' \
ansible-playbook --connection=ssh --timeout=30 --limit="machine1" \
--inventory-file=/.../.vagrant/provisioners/ansible/inventory \
--extra-vars="{\"extra1\":[\"bla01\",\"bla02\",\"bla03\"],\"extra2\":true}" \
-vvvv check.yml
PLAY [all] ********************************************************************
TASK: [debug var=extra1] ******************************************************
<127.0.0.1> ESTABLISH CONNECTION FOR USER: vagrant
ok: [machine1] => {
"var": {
"extra1": [
"bla01",
"bla02",
"bla03"
]
}
}
TASK: [fail msg="extra1 arg not set"] *****************************************
skipping: [machine1]
PLAY RECAP ********************************************************************
machine1 : ok=1 changed=0 unreachable=0 failed=0 with ==> machine1: Running provisioner: ansible_local...
machine1: Running ansible-playbook...
cd /vagrant && PYTHONUNBUFFERED=1 ANSIBLE_FORCE_COLOR=true ansible-playbook \
--limit="machine1" --inventory-file=/tmp/vagrant-ansible/inventory \
--extra-vars="{\"extra1\":[\"bla01\",\"bla02\",\"bla03\"],\"extra2\":true}" \
-vvvv check.yml
Using /vagrant/ansible.cfg as config file
Loaded callback default of type stdout, v2.0
PLAYBOOK: check.yml ************************************************************
1 plays in check.yml
PLAY [all] *********************************************************************
TASK [debug] *******************************************************************
task path: /vagrant/check.yml:5
ok: [machine1] => {
"extra1": [
"bla01",
"bla02",
"bla03"
]
}
TASK [fail] ********************************************************************
task path: /vagrant/check.yml:7
skipping: [machine1] => {"changed": false, "skip_reason": "Conditional check failed", "skipped": true}
PLAY RECAP *********************************************************************
machine1 : ok=1 changed=0 unreachable=0 failed=0 I also must stress out that I am very surprised that you have produce such an error when running the Can you please give it a try with git |
Hi @gildegoma, glad to help out. This test case was actually executed against vagrant 1.8.1 release. I did have problems with ansible extra-vars on both OSX and windows. The ansible documentation suggests to single quote As of Ansible 1.2, you can also pass in extra vars as quoted JSON, like so: I am not that familiar with ruby and have not been able to run the latest master (will have to setup a rbenv first before breaking my system ruby install ). However I did look through the ansible provisioner code while tracking the same problem on a windows machine and it looks like the "command" is properly constructed but the subprocess utility does mingle it up and constructs the os process incorrectly (as in stripping out characters required by ansible). Its all good until about here: |
CANDLEPIN_JENKINS_GITHUB_ORG when set will override what github org is used as the base for the jobs. This allows one to point the jobs at ones own repo, rather than at the central repos. Had to switch from ansible_local to ansible because of a [vagrant bug](hashicorp/vagrant#6726). The bug is fixed in 1.8.2, but f24 has 1.8.1, so I figure it's better to just switch for now at least, even though I prefer ansible_local for having less deps on the host machine.
CANDLEPIN_JENKINS_GITHUB_ORG when set will override what github org is used as the base for the jobs. This allows one to point the jobs at ones own repo, rather than at the central repos. Had to switch from ansible_local to ansible because of a [vagrant bug](hashicorp/vagrant#6726). The bug is fixed in 1.8.2, but f24 has 1.8.1, so I figure it's better to just switch for now at least, even though I prefer ansible_local for having less deps on the host machine.
CANDLEPIN_JENKINS_GITHUB_ORG when set will override what github org is used as the base for the jobs. This allows one to point the jobs at ones own repo, rather than at the central repos. Had to switch from ansible_local to ansible because of a [vagrant bug](hashicorp/vagrant#6726). The bug is fixed in 1.8.2, but f24 has 1.8.1, so I figure it's better to just switch for now at least, even though I prefer ansible_local for having less deps on the host machine.
Porting applications to use the lovely new
ansible_local
, and running into a few issues.In my Vagrantfile, I have:
Values have been scrubbed and simplified. Many of them actually inspect environment variables to determine there value, preventing me from moving them to my inventory group_var file.
default values defined in
group_vars/all
isis_vagrant=false
andshould_seed=false
which generates (what looks correctly):
But then I get (in a dummy task created to display variable output):
I can work around this temporarily, but something seems amiss.
The text was updated successfully, but these errors were encountered: