hashicorp / vagrant

Vagrant is a tool for building and distributing development environments.
https://www.vagrantup.com
Other
26.16k stars 4.43k forks source link

Ansible provisioner is using SSH despite Vagrantfile configured to use WinRM #13193

Open Wenzel opened 1 year ago

Wenzel commented 1 year ago

Debug output

https://gist.github.com/Wenzel/4ba6ea863129f44bb3752edb2187b85b

Expected behavior

vagrant provision should have run the Ansible provisioner and the win_ping test should have completed

Actual behavior

Ansible attempts to use an SSH connection, despite our VM configured to use WinRM.

DEBUG winrmshell: initializing WinRMShell
 INFO winrmshell: Attempting to connect to WinRM...
 INFO winrmshell:   - Host: 192.168.121.184
 INFO winrmshell:   - Port: 5985
 INFO winrmshell:   - Username: vagrant
 INFO winrmshell:   - Transport: negotiate
DEBUG winrmshell: [WinRM] opening remote shell on http://192.168.121.184:5985/wsman
DEBUG winrmshell: [WinRM] remote shell created with shell_id: 45836555-DEAC-4154-B750-577C9597B34A
DEBUG winrmshell: [WinRM] Command created for hostname with id: 223D86AE-743B-458A-883A-C623A135DD87
DEBUG winrmshell: [WinRM] creating command_id: 223D86AE-743B-458A-883A-C623A135DD87 on shell_id 45836555-DEAC-4154-B750-577C9597B34A
DEBUG winrmshell: [WinRM] Waiting for output...
DEBUG winrmshell: [WinRM] Processing output
DEBUG winrmshell: [WinRM] cleaning up command_id: 223D86AE-743B-458A-883A-C623A135DD87 on shell_id 45836555-DEAC-4154-B750-577C9597B34A
DEBUG winrmshell: Output: #<WinRM::Output:0x00007f9f7fc7fb48 @data=[{:stdout=>"vagrant-10"}, {:stdout=>"\r\n"}], @exitcode=0>
 INFO winrm: WinRM is ready!
...
INFO interface: detail:     vagrant-kafl-windows: Running ansible-playbook...
    vagrant-kafl-windows: Running ansible-playbook...
 INFO interface: detail: PYTHONUNBUFFERED=1 ANSIBLE_NOCOLOR=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="vagrant-kafl-windows" --inventory-file=/home/wenzel/Projets/kafl.targets/common/windows_template/.vagrant/provisioners/ansible/inventory -v setup_target.yml
PYTHONUNBUFFERED=1 ANSIBLE_NOCOLOR=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="vagrant-kafl-windows" --inventory-file=/home/wenzel/Projets/kafl.targets/common/windows_template/.vagrant/provisioners/ansible/inventory -v setup_target.yml
 INFO subprocess: Starting process: ["/home/wenzel/Projets/kafl.targets/windows_x86_64-userspace/template/venv/bin/ansible-playbook", "--connection=ssh", "--timeout=30", "--limit=vagrant-kafl-windows", "--inventory-file=/home/wenzel/Projets/kafl.targets/common/windows_template/.vagrant/provisioners/ansible/inventory", "-v", "setup_target.yml"]
 INFO subprocess: Command not in installer, restoring original environment...
DEBUG subprocess: Selecting on IO
 INFO interface: detail: Using /home/wenzel/Projets/kafl.targets/common/windows_template/ansible.cfg as config file

Using /home/wenzel/Projets/kafl.targets/common/windows_template/ansible.cfg as config file
 INFO interface: detail: 
PLAY [Setup target] ************************************************************

PLAY [Setup target] ************************************************************
 INFO interface: detail: 
TASK [Gathering Facts] *********************************************************

TASK [Gathering Facts] *********************************************************
 INFO interface: detail: fatal: [vagrant-kafl-windows]: UNREACHABLE! => {
    "changed": false,
    "unreachable": true
}

MSG:

ssl: auth method ssl requires a username

fatal: [vagrant-kafl-windows]: UNREACHABLE! => {
    "changed": false,
    "unreachable": true
}

MSG:

ssl: auth method ssl requires a username
 INFO interface: detail: 
PLAY RECAP *********************************************************************
vagrant-kafl-windows       : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   

Reproduction information

Vagrant version

Vagrant 2.3.6

Host operating system

Ubuntu 23.04

Guest operating system

Windows 10

Steps to reproduce

  1. python3 -m venv venv && source venv/bin/activate && pip install ansible pywinrm 1.git clone https://github.com/Wenzel/kafl.targets -b vagrant_ansible_ssh_bug
  2. cd common/windows_template
  3. packer build -var-file win10.pkrvars.hcl windows.pkr.hcl
  4. vagrant box add packer_windows_libvirt.box --name kafl_windows
  5. vagrant up

Vagrantfile

https://github.com/Wenzel/kafl.targets/blob/vagrant_ansible_ssh_bug/common/windows_template/Vagrantfile

Vagrant.configure("2") do |config|
    # The Packer box we just added
    config.vm.box = "kafl_windows"
      # our box name in libvirt
    config.vm.define "vagrant-kafl-windows"

    config.vm.synced_folder "sharedir", '/vagrant', type: 'rsync', disabled: true
    config.vm.provider :libvirt do |libvirt|
        # send absolute mouse movments to QEMU VNC display using a tablet
        # otherwise the guest mouse pointer is always out of sync with the host pointer, very annoying
        libvirt.input :type => "tablet", :bus => "usb"
        libvirt.cpus = 4
        libvirt.memory = 4096
      end

    config.vm.provision "ansible" do |ansible|
      ansible.playbook = "setup_target.yml"
      ansible.verbose = true
    end
  end
chrisroberts commented 1 year ago

The ansible provisioner currently only supports ssh connections. Implementation updates will be required for winrm support so marking this as an enhancement.

Cheers

Wenzel commented 1 year ago

As a workaround I used the vagrant-host-shell plugin to run a local script that will get the guest's IP address via vagrant winrm-config dump and then provision the guest with ansible:

Vagrantfile

    ....
    # workaround https://github.com/hashicorp/vagrant/issues/13193
    config.vm.provision :host_shell do |host_shell|
        host_shell.inline = 'source ../venv/bin/activate && ./setup_target.sh'
    end

setup_target.sh

#!/bin/bash

ip_address=$(vagrant winrm-config | grep 'HostName' | head -1 | awk '{print $2}')

ansible-playbook -i "${ip_address}," \
    -e ansible_connection=winrm \
    -e ansible_port=5985 \
    -e ansible_winrm_transport=basic \
    -e ansible_winrm_scheme=http \
    -e ansible_shell_type=powershell \
    -e ansible_user=vagrant \
    -e ansible_password=vagrant \
    playbook.yml $*
Wenzel commented 8 months ago

Since vagrant-host-shell is unmaintained since 2014, and Vagrant 2.3.7+ breaks the plugin compatibility, I switched to another workaround based on Vagrant triggers:


    config.trigger.after :provision do |trigger|
        trigger.info = "Provisioning"
        trigger.run = {inline: "bash -c 'source ../venv/bin/activate && ./setup_target.sh -e target_harness=#{TARGET}'"}
    end
salderma commented 1 month ago

The ansible provisioner currently only supports ssh connections. Implementation updates will be required for winrm support so marking this as an enhancement.

Cheers

This issue seems to be unresolved and stale. I have been attempting to build ansible provisioning with Vagrant recently and have posted a discussion topic to attempt to resurrect this issue. It does appear some work has been done to include WinRM support with the ansible provisioning plugin, however it seems incomplete or bugged.

Hope this helps bring some discussion and resolution to this topic.