One of the most popular configuration management and infrastructure automation products on the market is Ansible. Ansible, along with Chef, Puppet, CFEngine and the like is in a class of software products that are considered to be DevOps tools. These tools help automate infrastructure provisioning, software deployments, and general configuration management.

Since the DevOps methodology was born in the Linux world, you'll find that Ansible is much more focused on that platform. 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 necessarily ever used it before, you'll soon see that it's relatively straightforward to get set up. Although Windows support requires a bit more configuration, it's not too bad once the initial setup is done.

With that being said, 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 . This isn't going to be an article on how to set up a Vagrant box, but I will give you the Vagrantfile 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| = "boxcutter/ubuntu1604"
        ctl.vm.hostname = "ansible" "private_network",ip: ""
        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.

Installing Ansible

Assuming you've got that test box set up, we'll now install Ansible. To do this, you’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, it's time to get used to the command line. Ansible provides some setup instructions, but from my experience, some things have been 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 you’re 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

Once this is complete, install Git. I'll be using Git to get the development branch of Ansible, because it contains useful Ansible modules for us Windows guys, such as win_command and win_shell.

Next, in order to prevent a trust warning about an SSL certificate, I recommend setting the GIT_SSL_NO_VERIFY environment variable.


Next, I'll clone the Ansible Git repository and all child repositories.

git clone git:// –recursive

Now I'll navigate to the Ansible directory that was created.

cd ./ansible

Ansible uses Python, so we'll now set up a Python environment using the source command.

source ./hacking/env-setup

Next, we'll install Pip. Pip is the Python package management application that I'll use to download and install a few other required packages.

sudo easy_install pip

We'll now need to 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

At this point, Ansible should be installed and ready to go. Now is the time we focus on the Windows-specific tasks that allow Ansible to manage Windows nodes. Since Ansible natively works over SSH and Windows doesn't have that luxury yet, 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"

That’s it for software installs! Now let's focus on the Windows-specific configuration that must be done. We'll need to tell Ansible not to use SSH and instead to 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 that 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 that 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.

touch ./group_vars/windows.yml

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 set up HTTPS.

ansible_user: administrator
ansible_password: <password>
ansible_port: 5985
ansible_connection: winrm
ansible_winrm_scheme: http
ansible_winrm_server_cert_validation: ignore

I'm using the local administrator account to connect to the Windows nodes. Active Directory support is available but is outside 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 has 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

Ansible to run the win ping module

If Ansible notices the Windows node 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!

  1. William 7 years ago

    Slight typo, should be. end (space) end

    # -*- mode: ruby -*-
    # vi: set ft=ruby :
    Vagrant.configure(2) do |config|
    config.vm.define “ansible” do |ctl| = “boxcutter/ubuntu1604”
    ctl.vm.hostname = “ansible” “private_network”,ip: “”
    ctl.vm.provider “virtualbox” do |vb|
    vb.memory = 2048

  2. Author
    Adam Bertram (Rank 3) 7 years ago

    Thanks. Got that updated.

  3. Shakti Rai 6 years ago

    touch ./group_vars/windows.yml
    Could you elaborate the use of this step. Can this entry be made under /etc/ansible/hosts file itself, as I do not see ./group_vars folder by default.
    Do we need to create that, in order to complete the connectivity?

  4. Shakti Rai (Rank 1) 6 years ago

    I have been working on Linux and everything worked fine until I started on windows. I have question on :

    touch ./group_vars/windows.yml – why are we doing this? I do not see the folder group_vars. do we need to create this folder and file windows.yml?

    I made an entry within /etc/ansible/hosts and executed command:

    ansible all -m win_ping and I am getting:

    Error! ERROR! /etc/ansible/hosts:22: Expected key=value host variable assignment, got administrator

  5. ruga 6 years ago

    Ansible does not work, unless WinRM is already enabled and secured on each client.

    Now consider enabling 1000 clients…

  6. Wei-Yen Tan 3 years ago

    @ruga, Those servers tend to run in Active Directory. So you get ansible to authenticate through AD

Leave a reply

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


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account