At Azavea we use Ansible and custom ansible roles quite a bit.
We’ve also been using Vagrant for quite some time to create project-specific development environments. Adding Ansible as a provisioner makes setting up a development environment wonderfully smooth.
Unfortunately, Ansible is not officially supported with Windows as the control machine.
It is possible to get Ansible running in a Cygwin environment. With a bit of work, you can get it running from Vagrant too!
The first step to getting Ansible running is installing Cygwin. You can follow the normal installation instructions for Cygwin if you’d like to, or if you already have a Cygwin environment set up that’s great too!
We’re using babun instead of Cygwin’s normal installer for a simpler installation and package installation process. If you’re new to using Cygwin or having trouble with the standard installer I’d recommend this.
Setting up Ansible
Once you’ve got Cygwin installed, you’ll want to open up a terminal. You’ll need to use a Cygwin terminal, and not
cmd.exe, whenever you want to run
You’ll need to install
pip, to be able to install Ansible. You’ll also need some packages Ansible needs to run that can’t be installed by pip. If you’re using the standard Cygwin installer, run it again and make sure
openssh python-setuptools are all installed. We need
gcc-g++ to compile source code when installing
PyYAML from PyPi.
If you’re using babun, this is:
pact install python python-paramiko python-crypto gcc-g++ wget openssh python-setuptools
You might get the following error if you try to run python:
ImportError: No module named site.
If you see that error add the following to your
~/.zshrc (in your Cygwin home folder) and source it:
export PYTHONHOME=/usr export PYTHONPATH=/usr/lib/python2.7
Next lets get
pip installed, and install Ansible itself.
python /usr/lib/python2.7/site-packages/easy_install.py pip pip install ansible
Making Ansible Run From Vagrant
Once that is done, you should be able to run
ansible-playbook from bash or zsh.
However, that isn’t enough to use Ansible as a Vagrant provisioner. Even if you call
vagrant from bash or zsh,
vagrant won’t be able to find
ansible-playbook, because it isn’t on the Windows PATH. But even if we put
ansible-playbook on the Windows PATH, it won’t run, because it needs to use the Cygwin Python.
To ensure we’re using the Python in our Cygwin environment, we need a way to run
bash. The solution we came up with was to create a small Windows batch file and place it somewhere on the Windows PATH as
@echo off REM If you used the stand Cygwin installer this will be C:cygwin set CYGWIN=%USERPROFILE%.babuncygwin REM You can switch this to work with bash with %CYGWIN%binbash.exe set SH=%CYGWIN%binzsh.exe "%SH%" -c "/bin/ansible-playbook %*"
This is enough to let Vagrant find
ansible-playbook and run the Ansible provisioner.
You’ll likely run into the following error when you try and provision your first Vagrant VM:
GATHERING FACTS *************************************************************** fatal: [app] => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue
To get around this, we had to create a
~/.ansible.cfg in our Cygwin home directory (this can also go in your project directory as
ansible.cfg) changing what the ssh
ControlPath was set to:
[ssh_connection] control_path = /tmp
And with that you should be ready to provision using Ansible!
If you want to run other Cygwin programs from your Vagrantfile, such as
ansible-galaxy, you’ll have to make another batch file. For an example of how to easily make a bunch of wrapper batch files, checkout this gist.