Ansible – Using Ansible on Windows via Cygwin

Ansible – Using Ansible on Windows via Cygwin

As I continue down the Ansible journey to automate all things it is apparent that Windows is a second class citizen in some regards. I had a need to run Ansible from my Windows desktop and figured I would give this a shot. After some searching I found bits and pieces around the google results and pieced this all together and it works. And hopefully someone else will benefit from this.

First we need to install Cygwin from the following x64 (64-Bit) or x86 (32-Bit).

Install the following Cygwin components.

  • binutils
  • curl
  • gmp
  • libgmp-devel
  • make
  • python (2.7.x)
  • python-crypto
  • python-openssl
  • python-setuptools
  • git (2.5.x)
  • nano
  • openssh
  • openssl
  • openssl-devel

Once the Cygwin installer completes open the Cygwin desktop shortcut to open up the Cygwin BASH prompt.

There are two ways we can install the following.

The first way (more involved). See further down for the easy method.

Download the following packages to install.

curl -O https://pypi.python.org/packages/source/P/PyYAML/PyYAML-3.10.tar.gz
curl -O https://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.8.tar.gz

Now extract the packages downloaded above.

tar -zxvf Jinja2-2.8.tar.gz
tar -zxvf PyYAML-3.10.tar.gz

Now install the packages downloaded above.

cd Jinja2-2.8
python setup.py install
cd ..
cd PyYAML-3.10
python setup.py install

The second way (easy).

easy_install-2.7 pip
CFLAGS="-g -O2 -D_BSD_SOURCE" pip install -U pycrypto
pip install ansible

Now let’s pull down the Ansible code from GitHub. (More Involved way – see further down for the easy method)

git clone https://github.com/ansible/ansible /opt/ansible

Change to the latest stable branch of Ansible.

cd /opt/ansible
git checkout stable-1.9

Now we need to update some of the Ansible modules

cd /opt/ansible
git submodule update --init lib/ansible/modules/core
git submodule update --init lib/ansible/modules/extras

We now need to update our BASH profile to include the path to our Ansible folder.

cd ~
nano .bashrc

Paste the following at the bottom of the file and save.

# Ansible settings
ANSIBLE=/opt/ansible
export PATH=$PATH:$ANSIBLE/bin
export PYTHONPATH=$ANSIBLE/lib
export ANSIBLE_LIBRARY=$ANSIBLE/library

Now exit Cygwin

exit

And launch our Cygwin desktop shortcut once again to open up our Cygwin BASH prompt.
You should be able to launch ansible at this point to validate that our profile is correct in seeing the path to Ansible.

ansible
....
Usage: ansible  [options]

Options:
  -a MODULE_ARGS, --args=MODULE_ARGS
                        module arguments
  --ask-become-pass     ask for privilege escalation password
  -k, --ask-pass        ask for SSH password
  --ask-su-pass         ask for su password (deprecated, use become)
  -K, --ask-sudo-pass   ask for sudo password (deprecated, use become)
  --ask-vault-pass      ask for vault password
  -B SECONDS, --background=SECONDS
                        run asynchronously, failing after X seconds
                        (default=N/A)
  -b, --become          run operations with become (nopasswd implied)
  --become-method=BECOME_METHOD
                        privilege escalation method to use (default=sudo),
                        valid choices: [ sudo | su | pbrun | pfexec | runas ]
  --become-user=BECOME_USER
                        run operations as this user (default=None)
  -C, --check           don't make any changes; instead, try to predict some
                        of the changes that may occur
  -c CONNECTION, --connection=CONNECTION
                        connection type to use (default=smart)
  -e EXTRA_VARS, --extra-vars=EXTRA_VARS
                        set additional variables as key=value or YAML/JSON
  -f FORKS, --forks=FORKS
                        specify number of parallel processes to use
                        (default=5)
  -h, --help            show this help message and exit
  -i INVENTORY, --inventory-file=INVENTORY
                        specify inventory host file
                        (default=/etc/ansible/hosts)
  -l SUBSET, --limit=SUBSET
                        further limit selected hosts to an additional pattern
  --list-hosts          outputs a list of matching hosts; does not execute
                        anything else
  -m MODULE_NAME, --module-name=MODULE_NAME
                        module name to execute (default=command)
  -M MODULE_PATH, --module-path=MODULE_PATH
                        specify path(s) to module library
                        (default=/opt/ansible/library)
  -o, --one-line        condense output
  -P POLL_INTERVAL, --poll=POLL_INTERVAL
                        set the poll interval if using -B (default=15)
  --private-key=PRIVATE_KEY_FILE
                        use this file to authenticate the connection
  -S, --su              run operations with su (deprecated, use become)
  -R SU_USER, --su-user=SU_USER
                        run operations with su as this user (default=root)
                        (deprecated, use become)
  -s, --sudo            run operations with sudo (nopasswd) (deprecated, use
                        become)
  -U SUDO_USER, --sudo-user=SUDO_USER
                        desired sudo user (default=root) (deprecated, use
                        become)
  -T TIMEOUT, --timeout=TIMEOUT
                        override the SSH timeout in seconds (default=10)
  -t TREE, --tree=TREE  log output to this directory
  -u REMOTE_USER, --user=REMOTE_USER
                        connect as this user (default=larry.smith)
  --vault-password-file=VAULT_PASSWORD_FILE
                        vault password file
  -v, --verbose         verbose mode (-vvv for more, -vvvv to enable
                        connection debugging)
  --version             show program's version number and exit

BOOM!

Installing Ansible (Easy way)

easy_install-2.7 pip
pip install ansible

Now let’s do a test download of some Ansible Galaxy roles.

ansible-galaxy install mrlesmithjr.base
ansible-galaxy install mrlesmithjr.bootstrap

Now generate your SSH keys in order to execute ssh-passwordless logins.

ssh-keygen

One more thing that I ran into was when running an ansible-playbook was the following error.

ansible-playbook -i hosts gather_interfaces.yml
....
PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
fatal: [elk-pre-processor-1] => SSH Error: mux_client_request_session: send fds failed
    while connecting to 10.0.101.91:22
It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.

TASK: [grabbing interfaces] ***************************************************
FATAL: no hosts matched or all hosts have already failed -- aborting


PLAY RECAP ********************************************************************
           to retry, use: --limit @/home/larry.smith/gather_interfaces.retry

elk-pre-processor-1    : ok=0    changed=0    unreachable=1    failed=0

This error above is from using Cygwin and can easily be solved by creating an ansible.cfg file in your playbook folder with the following.

nano ansible.cfg
....
[ssh_connection]
ssh_args = -o ControlMaster=no

Now when running the playbook again success.

PLAY [all] ********************************************************************

GATHERING FACTS ***************************************************************
ok: [elk-pre-processor-1]

TASK: [grabbing interfaces] ***************************************************
changed: [elk-pre-processor-1]

TASK: [ensuring host_vars exists] *********************************************
ok: [elk-pre-processor-1 -> localhost]

TASK: [configuring host_vars] *************************************************
changed: [elk-pre-processor-1 -> localhost]

PLAY RECAP ********************************************************************
elk-pre-processor-1    : ok=4    changed=2    unreachable=0    failed=0

So there you have it! Now happy Ansibling! 🙂 And report back on any of your findings.

Enjoy!

About Larry Smith Jr.

vExpert 2013-2016 | Old-School coder coming back around to my roots #DevOPS and #automation | #Ansible junky!

15 thoughts on “Ansible – Using Ansible on Windows via Cygwin

  1. Hi, I want to thank you! It works, now I can use ansible from Windows machine when I’m not currenlty in Linux shell. Awesome.

  2. thank you so much for this article just wondering, how did the below configuration help

    “`cfg
    [ssh_connection]
    ssh_args = -o ControlMaster=no
    “`

    i tried ansible all -m ping, and it didn’t work until i added the ssh_connection configuration above to ansible.cfg

  3. Pingback: Scaling the Cliffs of Insanity (aka using Ansible from a Windows controller) – The rattled cough of Mike's imagination

  4. Easy install of ansible in cygwin

    Install cygwin with lynx

    lynx -source rawgit.com/transcode-open/apt-cyg/master/apt-cyg > apt-cyg
    install apt-cyg /bin
    apt-cyg install wget binutils curl gmp libgmp-devel make python python-devel \
    python-crypto python-openssl python-setuptools \
    git nano openssh openssl openssl-devel libffi-devel gcc-core gcc-g++
    wget http://peak.telecommunity.com/dist/ez_setup.py
    python ez_setup.py -U setuptools
    # previous line to avoid conflict with windows python install
    # restart terminal
    easy_install pip
    pip install ansible

  5. When I run command CFLAGS=”-g -O2 -D_BSD_SOURCE” pip install -U pycrypto I get error

    src/_fastmath.c:31:20: fatal error: Python.h: No such file or directory
    #include “Python.h”

    So I have to install python-devel Cygwin module

  6. On Cygwin I installed your list, and I also installed (via Cygwin package manager):
    “`
    openssl
    openssl-devel
    python
    python-crypto
    python-jinja2
    python-setuptools
    python2
    python2-cryptography
    python2-openssl
    python2-pip
    python2-setuptools
    python2-yaml
    “`

    Afterwards, i ran `pip2 install ansible` and it all downloaded and installed without any issues.

  7. Hello.
    I have installed Cygwin and Ansible in my Windows 10.
    Could you advice me why I cannot run “self configuration” when I run:
    $ ansible all -i ‘localhost,’ -c local -m win_ping
    localhost | FAILED! => {
    “changed”: false,
    “failed”: true,
    “module_stderr”: “/cygdrive/c/Users/username/.ansible/tmp/ansible-tmp-1498633802.04-14828277884701/win_ping.ps1 : The term \r\n’/cygdrive/c/Users/username/.ansible/tmp/ansible-tmp-1498633802.04-14828277884701/win_ping.ps1′ is not recognized \r\nas the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was \r\nincluded, verify that the path is correct and try again.\r\nAt line:1 char:1\r\n+ /cygdrive/c/Users/username/.ansible/tmp/ansible-tmp-1498633802.04 …\r\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n + CategoryInfo : ObjectNotFound: (/cygdrive/c/Use…01/win_ping.ps1:String) [], CommandNotFoundException\r\n + FullyQualifiedErrorId : CommandNotFoundException\r\n \r\n”,
    “module_stdout”: “”,
    “msg”: “MODULE FAILURE”,
    “rc”: 0
    }

    I have tried unix style of the command:
    $ ansible all -i ‘localhost,’ -c local -m ping
    localhost | SUCCESS => {
    “changed”: false,
    “ping”: “pong”
    }

    I guess my problem related to attempt to run PowerShell script from Cygwin environment. Could you recommend how to resolve it?

    Regards, Vlad.

  8. The setup worked for me as well. thanks very much.
    Ansible is running now without errors in cygwin.
    had to use ‘ssh_args = -o ControlMaster=no’ to be able to connect to machines.

    The only problem i have with it right now is: it is very, very, very slow.
    the ping-pong for 15 machines alone takes about 20 to 30 seconds.
    simple ssh connections would open in the blink of an eye on these machines.

    what is happening here in the background?

Leave a Reply

Your email address will not be published. Required fields are marked *

*