Vagrant: Ansible provisioner does not set ansible_winrm_scheme in generated inventory file, resulting in connection errors

Created on 30 Mar 2019  路  4Comments  路  Source: hashicorp/vagrant

Vagrant version

Vagrant 2.2.4

Host operating system

Linux

Guest operating system

Windows 10

Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.box = "senglin/win-10-enterprise-vs2015community"
  config.vm.box_version = "1.0.0"

  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
  end
end
# playbook.yml
- hosts: "*"
  # uncomment this for a workaround
  # vars:
  #   ansible_winrm_scheme: http
  tasks:
  - win_command: whoami

Debug output

(not provided for privacy reasons)

Expected behavior

vagrant provision should succeed.

Actual behavior

vagrant provision fails with:

fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "ssl: HTTPSConnectionPool(host='127.0.0.1', port=2202): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, u'[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:726)'),))", "unreachable": true}

Running

$ cat .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory 
# Generated by Vagrant

default ansible_connection=winrm ansible_host=127.0.0.1 ansible_port=2202 ansible_user='vagrant' ansible_password='vagrant'

reveals that the generated inventory file uses the HTTP port for winrm without setting ansible_winrm_scheme=http. Ansible defaults to https and the connection fails with an SSL error.

It is possible to work around this by modifying playbook.yaml (see comment above).

I'm not aware of a way to work around this in the Vagrantfile, but if it is possible I would be eager to learn how.

Steps to reproduce

  1. Create the given Vagrantfile and playbook.yaml
  2. Run vagrant up and/or vagrant provision
gueswindows provisioneansible question

Most helpful comment

I believe I can reproduce this issue, also with Vagrant 2.2.4 on Linux and a Windows guest. Unless I am misunderstanding something, which is totally possible. Anyway I hope this info might help, and thank you because the work-around provided helped me!

Vagrantfile:

Vagrant.configure("2") do |config|

  config.vm.box = "test-box"

  config.vm.provision "ansible" do |ansible|

    ansible.playbook = "site.yml"

    # Uncomment the below for work-around
    #ansible.host_vars = {
    #  "default" => { "ansible_winrm_scheme" => "http" }
    #}

  end

end

site.yml:

- hosts: all
  tasks:
    - win_ping:

Without the work-around, vagrant provision fails with:

fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "ssl: HTTPSConnectionPool(host='127.0.0.1', port=55985): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, u'[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:727)'),))", "unreachable": true}

Generated inventory:

# Generated by Vagrant

default ansible_connection=winrm ansible_host=127.0.0.1 ansible_port=55985 ansible_user='vagrant' ansible_password='vagrant'

Uncommenting the work-around in the Vagrantfile results in adding the variable ansible_winrm_scheme=http to the generated inventory, and with that, vagrant provision succeeds.

All 4 comments

@sol thank you for reporting this issue here (鉂わ笍for taking time to fill the template and add Vagrantfile + playbook.yml files 馃憤).

I'm not aware of a way to work around this in the Vagrantfile, but if it is possible I would be eager to learn how.

You actually have "tons" of ways to pass/override ansible variables from Vagrantfile settings (keeping your Playbook and Roles defaults clean ;-). Here is a list of options to define ansible_winrm_scheme as you wish/need:

  • The groups or host_vars options
  • The extra_vars option (to pass the variable as an ansible-playbook command line argument)
  • The raw_arguments option (to pass the variable as an ansible-playbook command line argument)

reveals that the generated inventory file uses the HTTP port for winrm without setting ansible_winrm_scheme=http. Ansible defaults to https and the connection fails with an SSL error.

At first glance, the generated inventory surprises me because we get

  • ansible_connection=winrm (Recent Vagrant versions seems to auto-detect the WinRM capabilty of the base box, this is new to my knowledge ;-)
  • ansible_port=2202 (I am not sure whether this connection port is really correct, as this corresponds to a position in the SSH range used by vagrant)

I haven't use Vagrant+Ansible+WindowsServers for many time now, but in the past at least, I think it was necessary to explicitly switch from SSH communication to WinRM protocol with this Vagrantfile setting:

config.vm.communicator = "winrm"

Or, is really your Windows WinRM service open/forwarded on your host's localhost:2202 ?

Once ansible_connection is set to winrm, I don't think that Vagrant has to specify other Ansible winrm options as the defaults looks good to me according to Ansible Documentation:

ansible_winrm_scheme: Specify the connection scheme (http or https) to use for the WinRM connection. Ansible uses https by default unless ansible_port is 5985

Basic authentication is not enabled by default on a Windows host but can be enabled by running the following in PowerShell [...]

But of course, it may depends how is your Server configured (and maybe the version of Ansible in use).

Please give it a try and let me know about your new results (e.g. generated inventory, log output).


PS: On my side, I'll try to do a test by myself as well (out of curiousity)

@sol your experience feedbacks are more than welcome into #10766 馃挀.

The generated inventory lines for a winrm machine should more look like this (but on a wrapped single line):

ansible_connection=winrm 
ansible_host=127.0.0.1
ansible_port=55985
ansible_user='vagrant'
ansible_password='vagrant'
ansible_winrm_server_cert_validation=ignore

although this kind of configuration is probably outdated with successive evolutions of WinRM. See #10444 discussion for more details, but recent working configuration looks for instance like this:

ansible_user: vagrant
ansible_password: vagrant
ansible_connection: psrp
ansible_port: 55986
ansible_psrp_transport: basic
ansible_psrp_cert_validation: ignore

Hope it helps...

I believe I can reproduce this issue, also with Vagrant 2.2.4 on Linux and a Windows guest. Unless I am misunderstanding something, which is totally possible. Anyway I hope this info might help, and thank you because the work-around provided helped me!

Vagrantfile:

Vagrant.configure("2") do |config|

  config.vm.box = "test-box"

  config.vm.provision "ansible" do |ansible|

    ansible.playbook = "site.yml"

    # Uncomment the below for work-around
    #ansible.host_vars = {
    #  "default" => { "ansible_winrm_scheme" => "http" }
    #}

  end

end

site.yml:

- hosts: all
  tasks:
    - win_ping:

Without the work-around, vagrant provision fails with:

fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "ssl: HTTPSConnectionPool(host='127.0.0.1', port=55985): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, u'[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:727)'),))", "unreachable": true}

Generated inventory:

# Generated by Vagrant

default ansible_connection=winrm ansible_host=127.0.0.1 ansible_port=55985 ansible_user='vagrant' ansible_password='vagrant'

Uncommenting the work-around in the Vagrantfile results in adding the variable ansible_winrm_scheme=http to the generated inventory, and with that, vagrant provision succeeds.

Was this page helpful?
0 / 5 - 0 ratings