Using Ansible through Windows 10's Subsystem for Linux

Ever since I heard about the new 'Beta' Windows Subsystem for Linux, which basically installs an Ubuntu LTS release inside of Windows 10 (currently 14.04), I've been meaning to give it a spin, and see if it can be a worthy replacement for Cygwin, Git shell, Cmder, etc. And what I was most interested in was whether I could finally point people to a more stable and friendly way of using Ansible on a Windows workstation.

In the past, there was the option of running Ansible inside Cygwin (and this is still the best way to try getting Ansible working in an older Windows environment), but this always felt kludgy to me, and I hated having to recommend either that or forcing Windows users to do a full Linux VM installation just to run Ansible commands. I finally updated my PC laptop to the latest Windows 10 Anniversary Update, and installed the Windows Subsystem for Linux, and lo and behold, Ansible works!

Ansible running on Windows in the Ubuntu Bash shell

In this blog post, I'll show you how to install and use Ansible on Windows 10.

Installing Bash on Windows 10

For reference, here are the official instructions from Microsoft: Bash on Ubuntu on Windows - Installation Guide.

Before installing the Linux Subsystem, you have to have:

  • Windows 10 (Anniversary update or later version)
  • 64-bit installation (can't run on 32-bit systems)

Once you verify your system is 64-bit and up to date, you have to do a few manual steps to enable the 'Windows Subsystem for Linux':

  1. Open 'Settings' (the cog in the start menu)
  2. Click 'Update & Security', then click the 'For developers' option on the left.
  3. Toggle the 'Developer mode' option, and accept any warnings Windows pops up.

Wait a minute for Windows to install a few things in the background (it will eventually let you know a restart may be required for changes to take effect—ignore that for now). Next, to install the actual Linux Subsystem, you have to jump over to 'Control Panel' (why is this separate from 'Settings'?), and do the following:

  1. Click on 'Programs'
  2. Click on 'Turn Windows features on or off'
  3. Scroll down and check 'Windows Subsystem for Linux (Beta)', and then click OK.

The subsystem will be installed, then Windows will require a reboot. Reboot, then open up the start menu and enter 'bash' (to open up 'Bash' installation in a new command prompt). Fill out all the questions (it will have you create a separate user account for the Linux subsystem), and once that's all done (it takes a few minutes to install), you will finally have Ubuntu running on your Windows laptop, somewhat integrated with Windows.

Installing Ansible

To install Ansible, since we're basically in an Ubuntu environment, it's as simple as installing pip, then installing Ansible:

  1. Open a bash prompt (from start menu, type 'bash' and hit enter).
  2. Install Pip: sudo apt-get -y install python-pip python-dev libffi-dev libssl-dev
  3. Install Ansible: pip install ansible --user (--user installs packages local to the user account instead of globally to avoid permissions issues with Pip and the Linux Subsystem)
  4. Since the ansible* commands are installed under ~/.local/bin, we need to add that to the $PATH, so run the command: echo 'PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
  5. Either exit out of the bash prompt and start it again from the Windows menu, or run source .bashrc to update your $PATH to include Ansible.

Note the use of --user for the pip install command; due to some peculiarities of the way the Linux subsystem works, Pip can't easily install packages globally, so we install packages just for the user account we set up for bash.

Using Ansible

At this point, which ansible should show the path to Ansible, ansible --version should show you Ansible's version, and you should be able to use ansible and the rest of the command-line tools (e.g. ansible-playbook, ansible-galaxy, etc.) as you would on any common environment.

If you get the error message ImportError: No module named markupsafe, try installing markupsafe manually with pip install markupsafe --user. See this GitHub issue for more detail.

If you want to run a playbook that's stored in your Windows user account's Documents folder (e.g. C:\Users\jgeerling\Documents), you can do so by navigating to /mnt/c/Users/jgeerling/Documents (where jgeerling is your username). Windows drives are mounted in the Subsystem inside the /mnt directory. Let's create a test playbook and see if it works!

  1. Open a bash prompt, and cd into your Windows user's Documents directory: cd /mnt/c/Users/jgeerling/Documents.
  2. Create a new test playbook: touch test.yml
  3. User nano or some other editor to add the following contents:

      ---
      - hosts: localhost
        tasks:
          - debug: msg="Ansible is working!"
    
  4. Run the playbook with the command ansible-playbook test.yml --connection=local

Ansible should run the command and print out the debug message. Ansible might warn about no inventory file being present, but since you're using --connection=local, the localhost host should automatically work.

Ansible test playbook running on Windows in the Ubuntu Bash shell

Going further

Now that you have Ansible installed, you can start automating everything (even including the rest of the bash environment)! If you need to, you can generate an SSH key for use connecting to servers, use ssh to directly connect to servers, etc. It's basically a full Ubuntu LTS install running inside Windows!

Comments

I just got bogged down in the installation of subsystem, just got an error when I was trying to activate this windows feature.

Any particular reason for using pip rather than the Ansible PPA (e.g. PPAs don't work on WSfL)?

Hi,

When running "sudo apt-get -y install pip python-dev", I received an error
I changed this to "sudo apt-get install python-pip python-dev", and it resolved the issue

Also prior to this I was receiving an "unable to resolve host" error which was resolved with

sudo su
echo 127.0.0.1 your_pc_name >> /etc/hosts

Thanks for the tutorial and hope this can help!

Same thing here regarding pip and python-pip.

thank you very much for this - very helpful and saved me loads of time compared to other how-tos I found.

For some reason the pip package is named wrong or has been renamed to python-pip.

So use this command in step 2: sudo apt-get -y install python-pip python-dev

This sudo apt-get -y install python-pip python-dev should be sudo apt-get -y install python-pip python-dev libffi-dev libssl-dev. Otherwise the compilation of the crypto-extensions won't work.

There seems to be permission issue when trying to install a role from the ansible-galaxy after following this guide.

$ ansible-galaxy install geerlingguy.git
- downloading role 'git', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-git/archive/1.2.1.tar.gz
- extracting geerlingguy.git to /etc/ansible/roles/geerlingguy.git
[WARNING]: - geerlingguy.git was NOT installed successfully: Could not update files in
/etc/ansible/roles/geerlingguy.git: [Errno 13] Permission denied: '/etc/ansible'
ERROR! - you can use --ignore-errors to skip failed roles and finish processing the list.

By default, Ansible installs roles into /etc/ansible, which is a path owned by root. Thus, you'd need to use sudo with galaxy install—sudo ansible-galaxy install geerlingguy.git.

Otherwise, you can also set a roles_path in /etc/ansible/ansible.cfg and set a directory to which you have write access (e.g. ~/ansible/roles or something like that). Additionally, you can add an ansible.cfg file in your project root that sets a path for that specific project's roles.

Hi,

First of all, thank you very much for this great tutorial.
So far I managed to get the test.yml to work with no issue.
I am now trying to set a real life scenario and create an ansible hosts but when I go to /etc there isn't an ansible directory..
Do I need to makdir /etc/ansible and then touch /etc/ansible/hosts ?

Could you please assist

Thank you in advance
Fred

Yes, if that directory doesn't exist, run sudo mkdir /etc/ansible, then touch /etc/ansible/hosts.

Great work Jeff, appreciate your time invested in this post as it saved me the need from running an additional VM

Ansible-galaxy will throw an error unless you add markupsafe package:

sudo pip install markupsafe

Once installed you will be now able to init new boiler plate for ansible galaxy roles or retrieve galaxy roles.

We can also try to install ansible using package manager but it will fail and throw a lot of errors.

Any idea if this works around Ansible issue #9963 (https://github.com/ansible/ansible/issues/9963)?

I encountered this when I created a vault on Mac OS but Windows user using Ansible via Cygwin couldn't decrypt. Would be helpful to hear your experience while I schedule time with one of my colleagues with Windows 10 to try, too.

There's a good chance it will work correctly—if you do everything within WSL, and don't use any windows-based tools to touch the vault file (e.g. no Git Bash for Windows, no Cygwin, no Powershell...).

getting a syntax error... not very familiar with yaml... i just copy / pasted your test file. any ideas?

drew@DREWTOP:~/playbooks$ ansible-playbook test.yml --connection=local
[WARNING]: Host file not found: /etc/ansible/hosts
[WARNING]: provided hosts list is empty, only localhost is available
ERROR! Syntax Error while loading YAML.
The error appears to have been in '/home/drew/playbooks/test.yml': line 2, column 10, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
  ---
  - hosts: localhost
         ^ here

same error :/

here is the paste of the test.yml file:

---
  - hosts: localhost
    tasks:
      - debug: msg="Ansible is working!"

Another option is to create an inventory file at /etc/ansible/hosts (sudo nano /etc/ansible/hosts) then add a line localhost to that file. Or a one-liner: echo "localhost" | sudo tee -a /etc/ansible/hosts > /dev/null. If the ansible directory doesn't exist, create it with sudo mkdir /etc/ansible first.

I istalled Ansible on ubuntu machine and now trying to make connectivity with a windows 2012 server.
To automate the setup of WinRM, I am running ./ConfigureRemotingForAnsible.ps1 script on the remote machine in a PowerShell console as an administrator.It throws error.
copied upgrade_to_ps3.ps1 script onto the remote host and run a PowerShell console as an administrator. It also throws an error. Do you happen to know the fix or if you have steps for windows connectivity then do share the steps.

Best regards,
Shakti

Hey Jeff,
Any ideas about installing custom ansible modules with this setup? Trying to get win_dsc5 to work and while `ansible windows -m win_dsc5` returns correctly, attempting to call a playbook that leverages the same module fails to find the module. This occurs even with an ansible.cfg defined that calls out the library path...
Thanks

Hi Jeff!

Thanks for a detailed and well presented post. I managed to get ansible working on the Ubuntu subsystem no problem at all controlling remote machines as well as some basic things through the local connection.

I have run into an issue while trying to get ansible to 'become' / sudo on the local ubuntu subsystem. Have you had any issues here or worked around the problem?
I have:
- Tried adding become to tasks, although ansible seems to ignore this
- Tried running ansible-playbook with sudo, which of course doesn't work as the above post only installs it for the one user
- Tried specifying a default sudo user and pass in vars, but it seems to get ignored
- Tried specifying a user when running ansible-playbook and a password using -K

This seems to be the last blocker to being able to use ansible for managing my local system.

Thanks again.
Addshore

Thanks you Jeff for great info.
But I've met with some difficulties. I've installed Zookeeper server and zookeeperd.
But when I tried to monitor service with:
sudo service zookeeper status

I've got that error
Failed to connect to socket /com/ubuntu/upstart

Is any way to fix this problem?

I've not tried using Zookeeper under Ubuntu Bash, but I'm guessing that the zookeeper service is misconfigured in that case.

Interesting approach - thanks for posting it! Presumably(?) if you run commands on localhost using this setup, they run under the bash for windows environment? Is there a way to tell ansible to run a task on the "Windows side" of the machine (i.e. using winrm to treat the machine as a Windows host)?

Yes, all this would be run within Bash on Ubuntu—and if you have the Creators Update or later, you should be able to at least call out to windows executables... but there's not any deeper integration between the two at this time.

Hi Jeff. Thanks so much for this! Was fairly simple to setup and run a playbook to install and configure packages on a Vagrant Ubuntu machine from Windows!

---
- hosts: localhost
  tasks:
    - debug: msg="Ansible is working!"

use the above code to avoid syntax errors

Thank you! Appreciate this very much

Make sure to add to your apt-get line sshpass.

sudo apt-get -y install python-pip python-dev libffi-dev libssl-dev sshpass

Note that sshpass is only required if you need to log into servers using SSH password authentication (as opposed to key-based auth). This is not recommended, as it's slightly less secure, and has other deployment issues associated with it too. However, if you must use it, you can use it if you install sshpass.

On Windows 10 with ansible 2.1.0.0, when running the yaml example I get the following error:

(lvenv)vagrant@DESKTOP-T091QJO:$ ansible-playbook -vvv -i 'localhost,' /mnt/
c/Users/Admin/Documents/test.yml --connection=local
Using /mnt/c/code/custos-bots/custosbotscitests/ansible.cfg as config file
PLAYBOOK: test.yml *************************************************************
1 plays in /mnt/c/Users/Admin/Documents/test.yml
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: vagrant
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1498677017.51-150964564686249 `" && echo ansible-tmp-1498677017.51-150964564686249="` echo $HOME/.ansible/tmp/ansible-tmp-1498677017.51-150964564686249 `" ) && sleep 0'
<localhost> PUT /tmp/tmp6mFX1r TO /home/vagrant/.ansible/tmp/ansible-tmp-1498677017.51-150964564686249/setup
<localhost> EXEC /bin/sh -c 'LANG=en_ZA.UTF-8 LC_ALL=en_ZA.UTF-8 LC_MESSAGES=en_ZA.UTF-8 /usr/bin/python /home/vagrant/.ansible/tmp/ansible-tmp-1498677017.51-150964564686249/setup; rm -rf "/home/vagrant/.ansible/tmp/ansible-tmp-1498677017.51-150964564686249/" > /dev/null 2>&1 && sleep 0'
An exception occurred during task execution. The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_1neMDM/ansible_module_setup.py", line 127, in <module>
    main()
  File "/tmp/ansible_1neMDM/ansible_module_setup.py", line 119, in main
    data = get_all_facts(module)
  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 3177, in get_all_facts
  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 3123, in ansible_facts
  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 919, in populate
  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 107, in wrapper
  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 1142, in get_mount_facts
IndexError: list index out of range
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "invocation": {"module_name": "setup"}, "module_stderr": "Traceback (most recent call last):\n  File "/tmp/ansible_1neMDM/ansible_module_setup.py", line 127, in <module>\n    main()\n  File "/tmp/ansible_1neMDM/ansible_module_setup.py", line 119, in main\n    data = get_all_facts(module)\n  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 3177, in get_all_facts\n  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 3123, in ansible_facts\n  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 919, in populate\n  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 107, in wrapper\n  File "/tmp/ansible_1neMDM/ansible_modlib.zip/ansible/module_utils/facts.py", line 1142, in get_mount_facts\nIndexError: list index out of range\n", "module_stdout": "", "msg": "MODULE FAILURE", "parsed": false}
NO MORE HOSTS LEFT *************************************************************
        to retry, use: --limit @/mnt/c/Users/Admin/Documents/test.retry
PLAY RECAP *********************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1

Any ideas? I did add localhost to my `/bin/ansible/hosts` file

Hi,

I have installed the Ubuntu package under windows as per the instructions above and when i try and run the pip installation it fails with unable to resolve URL error messages. Have tried looking down this page for others who had the same problems and tried the fixes they suggested and it still fails. Is the archive URL still in place to download these packages?

All help gratefully received

Thanks

David

Are you on a network behind a corporate proxy? If so you would need to configure it in the Ubuntu bash environment.

Cheers for putting this tutorial together!

I was only half paying attention as I was reading and ended up just installing the Ansible package from the Ubuntu repositories via:

apt-get install ansible

I haven't gotten much farther than your debug step, but it looks good so far.

The package manager version is 2.0.0.2, which looks to date from January 2016 (https://releases.ansible.com/ansible/), so fairly out of date in comparison to 2.3.2.0 from July 2017, but we'll see how we go!

I wonder if there is a way for ansible to check if it is running under WSL, so that you could use it for conditionals.

Thanks for putting together this guide, it's great to be able to use Ansible from my laptop. And thanks for all the other Ansible and Drupal resources you have made available.

Have you come across this issue with trying to encrypt files into Ansible Vault?

*****@*****:/mnt/c/dev/ansible$ ansible-vault encrypt restric.yml -vvv
Using /mnt/c/dev/ansible/ansible.cfg as config file
New Vault password:
Confirm New Vault password:
ERROR! Unexpected Exception: /home/********/.local/lib/python2.7/site-packages/cryptography/hazmat/bindings/_openssl.so: cannot enable executable stack as shared object requires: Invalid argument
the full traceback was:

Traceback (most recent call last):
  File "/home/********/.local/bin/ansible-vault", line 109, in <module>
    exit_code = cli.run()
  File "/home/********/.local/lib/python2.7/site-packages/ansible/cli/vault.py", line 158, in run
    self.execute()
...
ImportError: /home/********/.local/lib/python2.7/site-packages/cryptography/hazmat/bindings/_openssl.so: cannot enable executable stack as shared object requires: Invalid argument

Sorry, I haven't seen that one before—I would imagine asking on the Ansible Project Google group might get some more opinions though! (Or maybe even the #ansible channel on Freenode IRC).

Thanks for looking.

I have since found that this seems to fix it:

sudo execstack -c /home/MY_USER_NAME/.local/lib/python2.7/site-packages/cryptography/hazmat/bindings/_openssl.so

Hi all,

i'm getting error in the initial steps. After enabled bash cmd. it asking 'type y to continue' to install ubuntu in windows. them pressing y, downloading start. cmd line window automatically closed after reached 100%. again hit bash cmd, show same error. anyone assist me

you're amazing. Its so easy and well written blog for ppl who wants to learn ansible in windows 10. I did so much research during my bash setup and i wish I could found this early then. !!!
Happy coding.

Hey thanks for this tutorial, I got everything working pretty smoothly until it came time to encrypt vault.yml (refer Jason Lengtstorf's YouTube tutorial). I get an error to do with Ubuntu seeing every file as executable.

$ ansible-vault encrypt group_vars/production/vault.yml

[WARNING]: Error in vault password file loading (default): Problem running vault password script
/mnt/d/Dev/learn-trellis/trellis/.vault-pass ([Errno 8] Exec format error). If this is not a
script, remove the executable bit from the file.

ERROR! Problem running vault password script /mnt/d/Dev/learn-trellis/trellis/.vault-pass ([Errno 8] Exec format error). If this is not a script, remove the executable bit from the file.

No worries, I think, those perms are messed up anyway let's have a clean up via chmod maybe some chown too. No such luck -- WSL doesn't support POSIX permissions. Bash registers the command fine, but no bits are changed on the files. Have you worked around this issue running Ansible on Ubuntu on Windows or know of anyone who has?

Thanks again!

Found a solution that works for me on StackOverflow. I can't post links without triggering the spam filter, but if anyone has this problem just search "cant use ansible inventory file because it is executable" and it should do the trick.

Thanks so much for this! As an FYI for anyone using this, check the $HOME/.local/bin direction post-install, before trying to manually add it. I had a suspicion, and it did turn out that that directory was automatically added to the PATH.

(Note this is from a fresh install, with update, of the Ubuntu version of the subsystem.)

If you get the following error "E: Unable to locate package python-pip" error try running "sudo apt-get update" first.

On one machine in the office here, this works great.
On three other machines, we're running into `SSLError: HTTPSConnectionPool(host='192...', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')",),))
fatal: [192...]: UNREACHABLE`

We asked on Stackoverflow too: https://stackoverflow.com/questions/49625721/eof-occurred-in-violation-…

Here's the full error:

TASK [Gathering Facts] **********************************************************************************************
task path: /mnt/c/ansible/test.yml:1
Using module file /home/.../python2.7/site-packages/ansible/modules/windows/setup.ps1
<192.168.6.1> ESTABLISH WINRM CONNECTION FOR USER: xxxx on PORT 5986 TO 192...
checking if winrm_host 192.168.6.1 is an IPv6 address
<192.168.6.1> WINRM CONNECT: transport=ssl endpoint=https://192...:5986/wsman
<192.168.6.1> WINRM CONNECTION ERROR: HTTPSConnectionPool(host='192...', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLEOFError(8, u'EOF occurred in violation of protocol (_ssl.c:590)'),))
Traceback (most recent call last):
  File "/home/.../python2.7/site-packages/ansible/plugins/connection/winrm.py", line 345, in _winrm_connect
    self.shell_id = protocol.open_shell(codepage=65001)  # UTF-8
  File "/home/.../python2.7/site-packages/winrm/protocol.py", line 157, in open_shell
    res = self.send_message(xmltodict.unparse(req))
  File "/home/.../python2.7/site-packages/winrm/protocol.py", line 234, in send_message
    resp = self.transport.send_message(message)
  File "/home/.../python2.7/site-packages/winrm/transport.py", line 256, in send_message
    response = self._send_message_request(prepared_request, message)
  File "/home/.../python2.7/site-packages/winrm/transport.py", line 261, in _send_message_request
    response = self.session.send(prepared_request, timeout=self.read_timeout_sec)
  File "/home/.../python2.7/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/home/.../python2.7/site-packages/requests/adapters.py", line 506, in send
    raise SSLError(e, request=request)
SSLError: HTTPSConnectionPool(host='192...', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLEOFError(8, u'EOF occurred in violation of protocol (_ssl.c:590)'),))

Is this something anyone else here as come across?

Hi, Thanks for such a wonderful article, everything went smooth so far on my windows 10, unfortunately i its not running the test
i have searched and tried to look for the answer, below is the same error after having created hosts entry, any help on this?

neo@xx-7A184VG-Home:~$ ansible-playbook testansi.yml --connection=local
ERROR! Syntax Error while loading YAML.
  expected <block end>, but found '<block sequence start>'
The error appears to have been in '/home/neo/testansi.yml': line 4, column 2, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
  tasks:
- debug: msg="Awesome ansible is working!!!"
^ here
$ cat /etc/ansible/hosts
localhost

It's probably a whitespace issue. Your playbook needs to have the proper amount of spaces to index the line with the debug task (so it's inside the 'tasks' list):

  tasks:
    - debug: msg="Awesome ansible is working!!!"

Also, make sure you're using spaces, not tabs.

Thank you , it worked but now ran into different problem ERROR! the field 'hosts' is required but was not set" I had added the host entry already...

I just bought the book and now I'm trying to get started with ansible. But I get stuck at chapter two when I try to do the provisioning. I am running this on Windows 10 WSL. This is what I get when I try to do the provisioning, at the end I list the versions on ansible and vagrant that I get. I also went to the suggested link for the problem, https://www.vagrantup.com/docs/provisioning/ansible_common.html#compatibility_mode But I'm not really sure how to add that to the vagrant file.

peter@BIGGUS:/mnt/c/dev/jgeerling/test01$ vagrant.exe provision
==> default: Running provisioner: ansible...
Windows is not officially supported for the Ansible Control Machine.
Please check https://docs.ansible.com/intro_installation.html#control-machine-requirements
Vagrant gathered an unknown Ansible version:


and falls back on the compatibility mode '1.8'.

Alternatively, the compatibility mode can be specified in your Vagrantfile:
https://www.vagrantup.com/docs/provisioning/ansible_common.html#compatibility_mode
    default: Running ansible-playbook...
The Ansible software could not be found! Please verify
that Ansible is correctly installed on your host system.

If you haven't installed Ansible yet, please install Ansible
on your host system. Vagrant can't do this for you in a safe and
automated way.
Please check https://docs.ansible.com for more information.
peter@BIGGUS:/mnt/c/dev/jgeerling/test01$ ansible --version
ansible 2.7.6
  config file = None
  configured module search path = [u'/home/peter/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/peter/.local/lib/python2.7/site-packages/ansible
  executable location = /home/peter/.local/bin/ansible
  python version = 2.7.15rc1 (default, Nov 12 2018, 14:31:15) [GCC 7.3.0]
peter@BIGGUS:/mnt/c/dev/jgeerling/test01$ vagrant --version
Vagrant 2.0.2
peter@BIGGUS:/mnt/c/dev/jgeerling/test01$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

Just a note that using Ansible under the WSL with Vagrant is tricky at best; I have still not found an easy way to do that. So I typically recommend either using ansible_local instead of ansible in the Vagrantfile for the provisioner (runs the playbook inside the VM), or doing it some other way. Unfortunately, it's not very easy to get things working well under WSL even if you try to integrate things with Vagrant/VirtualBox directly.

Yes, but can you run the win_* modules or would that need to be done from a different host?

Running under Ubuntu-WSL I got the same error as many people before me:

ansible-playbook -vvv -i 'localhost,'​ test.yml --connection=local
ansible-playbook 2.8.2
  config file = None
  configured module search path = [u'/home/bas/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/bas/.local/lib/python2.7/site-packages/ansible
  executable location = /home/bas/.local/bin/ansible-playbook
  python version = 2.7.15+ (default, Nov 27 2018, 23:36:35) [GCC 7.3.0]
No config file found; using defaults
Unable to parse address from hostname, leaving unchanged: Not a valid network hostname: ​
Parsed localhost,​ inventory source with host_list plugin
ERROR! Syntax Error while loading YAML.
  mapping values are not allowed here
The error appears to be in '/mnt/c/Users/bas/Documents/test.yml': line 2, column 10, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
---
  - hosts: localhost
         ^ here

Fixed. Syntax error says it all. But i was not the only one who overlooked this. I needed to begin with 3 dashes. The first on line one column 1.

Hi, thanks a lot for the guide. Still, it's 2019, and it's pretty painless now, just install WSL with Ubuntu 18.04, and "sudo apt install ansible" get you up & running :). Could you please update the blog accordingly?

Thank you for this, it worked great for me. One thing I'd like to mention is when I ran through this and I tried to run the playbook for the first time I received some errors, once I sudo the command it worked for me "sudo ansible-playbook".

Perhaps a step to add between 1 and 2 in Installing Ansible: run `sudo apt update`
That's necessary with a new install, otherwise you get "E: Unable to locate package python-pip"

The apt cache could/should be updated regularly, but if its out of date it would result in that issue. I wish apt itself would detect if it needs its cache to be updated... would result in a lot fewer weird moments.

Have followed all the instructions above, however sudo ansible-playbook test.yml --connection=local runs to success, but ansible-playbook test.yml --connection=local fails on gathering facts:

TASK [Gathering Facts] ***************************************************************************************************************
fatal: [localhost]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"setup": {"cmd": "/mnt/c/opscode/chefdk/bin/ohai", "failed": true, "invocation": {"module_args": {"fact_path": "/etc/ansible/facts.d", "filter": "*", "gather_subset": ["all"], "gather_timeout": 10}}, "msg": "[Errno 2] No such file or directory", "rc": 2}}, "msg": "The following modules failed to execute: setup\n"}

Should ansible-playbook work without sudo?

The clue was in the error message, the problem appears to have been with the Gathering Facts module. It couldn't find ohai (a program that returns the JSON inventory data).
Ran "apt install ohai" and issue is resolved.

Thank you, obvious but I didn't think about missing it because I also use an ancient chefdk, google indexed your answer, which helped me :)

starting us off with a spacing error. My test.yml would not work unless I put an extra carriage return between the hosts: and tasks:

  ---
  - hosts: localhost
    tasks:
      - debug: msg="Ansible is working!"

It should work as is in the post, assuming the entire file has the correct indentation:

---
- hosts: localhost
  tasks:
    - debug: msg="Ansible is working!"

Harkening back to Cygwin, you can also us MSYS2

#!/usr/bin/env bash
# Install MSYS2:
# @see https://www.msys2.org/

pacman -S base-devel msys2-devel gcc
pacman -S python3 python3-pip
pacman -S libffi libffi-devel libcrypt libcrypt-devel
pacman -S openssl openssl-devel

CFLAGS=-I/usr/lib/libffi-3.2.1/include python -m pip install ansible

Thanks man, this worked great. I already had wsl2 on my desktop, and I was thinking there might be a docker container with Ansible, and then I found this article. Now I am ready to lean Ansible.

These instructions worked for me(windows 10, build 2004 WSL2) after sight modification:

Change

sudo apt-get -y install python-pip python-dev libffi-dev libssl-dev

to

sudo apt-get -y install python3-pip python3-dev libffi-dev libssl-dev

Thanks Jeff!

Thank you very much for this blog Jeff. Really appreciate it!