One of the most popular configuration management and infrastructure automation products on the market is Ansible. Ansible — along with Chef, Puppet, CFEngine — is part of a class of software for DevOps. These tools help automate infrastructure provisioning, software deployments and general configuration management.
Ansible is focused on Linux. However, with Microsoft's new stance on open source, their community contributions and their adoption of a more agile, DevOps-minded software development approach, Windows support is slowly catching up. If you've heard of Ansible but haven't really used it, it's relatively straightforward to get set up. Although Windows support requires a little bit more configuration, it's not too bad once the initial setup is done.
Let's dive into Ansible and get it deploying simple changes to a Windows node.
Setting up the Linux VM with Vagrant
Ansible runs on a control server. Unlike other configuration management products, it has no agent and sends commands to the nodes under its control. Unfortunately for us Windows guys, it has to be run on Linux. If you don't have a spare Linux box laying around, let's bring one up. I use Vagrant for all of my initial testings. It's the easiest way I've found to quickly get a VM of just about any flavor up and running quickly. This isn't going to be an article on how to set up a Vagrant box, but I will give you the Vagrant file I use to bring up my test box.
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.define "ansible" do |ctl|
ctl.vm.box = "boxcutter/ubuntu1604"
ctl.vm.hostname = "ansible"
ctl.vm.network "private_network",ip: "192.168.2.5"
ctl.vm.provider "virtualbox" do |vb|
vb.memory = 2048
This VagrantFile will download an Ubuntu box on VirtualBox, call it 'ansible,' assign a private IP and give it 2GB of RAM.
Assuming you've got that test box setup, we'll now install Ansible. To do this, I'll need to ssh into the Linux box. If using Vagrant, the VM can be connected to by typing 'vagrant ssh'. Otherwise, you'll probably need to download Putty or some other Windows SSH client. Once you're on the Linux server's console is when it's time to get used to the command line. Ansible provides some setup instructions, but from my experience, some things were missed. Let's cover the commands that I used to get Ansible up and running.
Note: All commands I'll be running will be on Ubuntu 16.04. If running any other version of Ubuntu or distribution, your commands may be slightly different.
First of all, it's safer to ensure all packages are up to date before starting. To do this, you'll use apt-get.
sudo apt-get update
Install Git to get the development branch of Ansible, because it contains useful Ansible modules for us Windows guys like win_command and win_shell.
Next, to prevent a trust warning about an SSL certificate, I recommend setting the GIT_SSL_NO_VERIFY environment variable.
Next, clone the Ansible Git repository and all child repositories.
git clone git://github.com/ansible/ansible.git –recursive
Navigate to the Ansible directory that was created.
Ansible uses Python, so we'll now set up a Python environment using the source command.
Install Pip. Pip is the Python package management application that I'll use to download and install a few other required packages with.
sudo easy_install pip
Download a few more required packages. The order is important here.
sudo pip install PyYAML Jinja2 httplib2 six
sudo apt-get install libssl-dev
sudo pip install paramiko
Setting up Ansible for Windows
Ansible should be installed and ready to go. Now focus on the Windows-specific tasks that allows Ansible to manage Windows nodes. Since Ansible natively works over SSH, Windows doesn't have that luxury yet so we'll need to give Ansible the ability to communicate with Windows nodes over WinRM. To do that, we'll need to install the Python pywinrm library.
sudo pip install "pywinrm>=0.1.1"
This is it for software installs. We'll need to tell Ansible not to use SSH and instead use WinRM for all communication. Due to Ansible's extensible nature, there are many ways to make this happen, but I've chosen to do this by creating a Windows inventory group inside of a file called 'hosts' in ./hosts.
Note: Ensure Ansible knows where to find your inventory file. I've chosen to set this in the ansible.cfg file located in the ansible folder I'm working in.
inventory = /home/vagrant/ansibletesting/hosts
Once I've ensured Ansible can find my inventory file, I'll add our windows group in there.
At this point, I need to tell Ansible to use WinRM rather than SSH. I can set Ansible variables for inventory groups by creating a file called windows.yml inside of the group_vars directory.
I'll now fill in the YAML file with the required variables. Note below that I'm just using WinRM over HTTP and not HTTPS. Although this is doable, it requires a little further configuration. Refer to this link if you'd like to setup HTTPS.
I'm using the local administrator account to connect to the Windows nodes. Active Directory support is available but is out of the scope of this article.
At this point, I can run the built-in Ansible module win_ping. This module will go out and create a WinRM session to ensure it's established successfully. You can see below that I'm telling Ansible to run the win_ping module for all nodes inside of the windows inventory group.
ansible windows -m win_ping
Ansible to run the win_ping module
If Ansible notices that the windows node that you've added to the windows group and returns a green SUCCESS, you're all done. Pat yourself on the back. You've installed and configured Ansible to work with your first Windows node.