Vagrant: Ansible provisioner not working via winrm

Created on 25 Nov 2018  ·  11Comments  ·  Source: hashicorp/vagrant

Hi Guys,

When running vagrant up, using an ansible provisioner against a windows machine, i get the following error:

fatal: [dc]: UNREACHABLE! => {"changed": false, "msg": "ssl: HTTPSConnectionPool(host='127.0.0.1', port=55985): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(\"bad handshake: Error([('SSL routines', 'SSL23_GET_SERVER_HELLO', 'unknown protocol')])\")))", "unreachable": true}

  • Host OS: macOS Mojave 10.14
  • vagrant 2.2.0
  • ansible 2.7.1
  • pywinrm 0.3.0 (i upgraded from 0.2.2 as part of troubleshooting this issue).
  • Guest OS: Windows Server 2016 Standard
  • Port 5985 is open in the firewall
  • I can run the playbook successfully using ansible outside of vagrant.
  • I've tried adding {"ansible_winrm_server_cert_validation" => "ignore"} to the Vagrantfile

Standalone ansible group vars look like this:

ansible_user: vagrant
ansible_password: vagrant
ansible_connection: winrm
ansible_winrm_server_cert_validation: ignore
ansible_port: 5985

.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory looks like this:

<hostname> ansible_connection=winrm ansible_host=127.0.0.1 ansible_port=55985 ansible_user='vagrant' ansible_password='vagrant' ansible_winrm_server_cert_validation=ignore
Thanks in advance,
Dan

gueswindows provisioneansible

Most helpful comment

It is, this is an issue with the latest release of pywinrm where it will ignore the server_cert_validation kwarg if REQUESTS_CA_BUNDLE or CURL_CA_BUNDLE environment variables are set. It has been fixed in the master branch but a release hasn't been made with the changes. Details on the original issue are here https://github.com/diyan/pywinrm/issues/201.

To get around this, you have 5 options

  • Install pywinrm from the master branch directly
  • Use the 0.2.2 version of pywinrm which didn't have this issue (you loose out on message encryption :( )
  • Use pypsrp instead. Need to install with pip install pypsrp and set the following vars in your inventory (Note: this requires Ansible 2.7)
ansible_user: vagrant
ansible_password: vagrant
ansible_connection: psrp
ansible_port: 55986
ansible_psrp_transport: basic # I personally would leave this out and use Negotiate/NTLM instead
ansible_psrp_cert_validation: ignore
  • Don't use SSL with winrm
  • Find out where in Vagrant that these env vars are being set and see if they can be unset

All 11 comments

Hello! Thanks for opening an issue. When opening a new issue on the Vagrant project, we ask that everyone provide a gist containing the behavior you're seeing with the --debug flag included. This helps us figure out what's actually going on. Thanks!

@dtrac thank you for the debug log. From line 2792, it seems vagrant is not (or no longer) configured to use the generated ansible inventory (.vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory), but a local inventory.yml file.

Could you also please share the content of your Vagrantfile and the static ansible inventory (inventory.yml). Thanks!

@dtrac see also the ansible-playbook notice at L2826:

[...]/inventory.yml did not meet script requirements, check plugin documentation if this is unexpected

Hey Gilles - thanks for taking the time to look at this. I've tried with both the auto-generated inventory, which looked like:

'# Generated by Vagrant

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

...and my own inventory.yml:

all:
  hosts:
    dc:
      ansible_host: 127.0.0.1
  vars:
    ansible_user: vagrant
    ansible_password: vagrant
    ansible_connection: winrm
    ansible_port: 55985 (...and tried 55986 - both 5985 and 5986 are up...)
    ansible_winrm_transport: basic
    ansible_winrm_server_cert_validation: ignore

Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

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

  config.vm.define "dc"
  config.vm.box = "StefanScherer/windows_2016"
  config.vm.hostname = "dc"
  config.vm.network "private_network", ip: "10.42.0.100", :name => 'vboxnet3'
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "test-playbook.yml"
    #ansible.inventory_path = "inventory.yml"
    #ansible.limit = "all"
    ansible.verbose = "-vv"
    ansible.host_vars = {
      "dc" => {"ansible_winrm_server_cert_validation" => "ignore"}
    }
  end

  config.vm.provider "virtualbox" do |v|
    v.name = "dc"
    v.gui = true
    v.linked_clone = true

  end
end

Dan

Update - despite the "/inventory.yml did not meet script requirements..." message, if I point standalone ansible at that inventory file - i can execute the playbook.

Interestingly, if i add:"ansible_port" => "55986"
...to my Vagrantfile, this gets added to the end of my autogenerated inventory file (along with "ansible_port=55985" earlier in the line!), and the error message changes to:

fatal: [dc]: UNREACHABLE! => {
    "changed": false,
    "msg": "ssl: HTTPSConnectionPool(host='127.0.0.1', port=55986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(\"bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')])\")))",
    "unreachable": true
}

...so it's almost like the "ansible_winrm_server_cert_validation=ignore" is being ignored...

Dan

It is, this is an issue with the latest release of pywinrm where it will ignore the server_cert_validation kwarg if REQUESTS_CA_BUNDLE or CURL_CA_BUNDLE environment variables are set. It has been fixed in the master branch but a release hasn't been made with the changes. Details on the original issue are here https://github.com/diyan/pywinrm/issues/201.

To get around this, you have 5 options

  • Install pywinrm from the master branch directly
  • Use the 0.2.2 version of pywinrm which didn't have this issue (you loose out on message encryption :( )
  • Use pypsrp instead. Need to install with pip install pypsrp and set the following vars in your inventory (Note: this requires Ansible 2.7)
ansible_user: vagrant
ansible_password: vagrant
ansible_connection: psrp
ansible_port: 55986
ansible_psrp_transport: basic # I personally would leave this out and use Negotiate/NTLM instead
ansible_psrp_cert_validation: ignore
  • Don't use SSL with winrm
  • Find out where in Vagrant that these env vars are being set and see if they can be unset

@jborean93

Thanks for your help with this. The solution for me was to use pypsrp with basic auth and SSL (it's just a development setup so that is a perfectly fine option for me just now). The Windows guest was configured as per the WinRM Setup section of the documentation.

With pywinrm, no matter what version I tried, it couldn't verify the certificate properly:

TASK [Gathering Facts] *********************************************************
 [WARNING]: ansible_winrm_cert_validation unsupported by pywinrm (is an up-to-
date version of pywinrm installed?)

Tried installing pywinrm 0.3.1 from github with no success. Tried pypsrp but get an error about the dependencies. Trying other 3 of 5 options now...

Closing this one now. I invite all Vagrant/Ansible/WindowsServer users to watch and feed the analysis that will take place at #10766. Many thanks in advance 💓.

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

rhencke picture rhencke  ·  3Comments

RobertSwirsky picture RobertSwirsky  ·  3Comments

Cbeck527 picture Cbeck527  ·  3Comments

hesco picture hesco  ·  3Comments