Running Ansible on a Windows System

On my last conference talk (it was about Ansible and Docker at DevOpsCon in Berlin), I was asked what is the best way to run Ansible on a Windows system. Ansible itself requires a Linux-based system as the control machine. When I have to develop on a Windows machine, I install a Linux-based virtual machine to run the Ansible's playbooks inside the virtual machine. I set up the virtual machine with Virtualbox and Vagrant. This tools allow me to share the playbooks easily between host and the virtual machine. so I can develop the playbook on the windows system and the virtual machine can have a headless setup. The next section shows you how to set up this tool chain.

 Tool Chain Setup

 At first, install VirtualBox and Vagrant on your machine. I additionally use Babun, a windows shell based on Cygwin and oh-my-zsh, for a better shell experience on Windows, but this isn't necessary. Then, go to the directory (let's called it ansible-workspace), where your Ansible's playbooks are located. Create there a Vagrant configuration file with the command vagrant init:

 1ansible-workspace
 2├── inventories
 3│   ├── production
 4│   └── test
 5├── README.md
 6├── roles
 7│   ├── deploy-on-tomcat
 8│   │   ├── defaults
 9│   │   │   └── main.yml
10│   │   └── tasks
11│   │       ├── cleanup-webapp.yml
12│   │       ├── deploy-webapp.yml
13│   │       ├── main.yml
14│   │       ├── start-tomcat.yml
15│   │       └── stop-tomcat.yml
16│   ├── jdk
17│   │   └── tasks
18│   │       └── main.yml
19│   └── tomcat8
20│       ├── defaults
21│       │   └── main.yml
22│       ├── files
23│       │   └── init.d
24│       │       └── tomcat
25│       ├── tasks
26│       │   └── main.yml
27│       └── templates
28│           └── setenv.sh.j2
29├── demo-app-ansible-deploy-1.0-SNAPSHOT.war
30├── deploy-demo.yml
31├── inventories
32│   ├── production
33│   └── test
34├── roles
35│   ├── deploy-on-tomcat
36│   │   ├── defaults
37│   │   │   └── main.yml
38│   │   └── tasks
39│   │       ├── cleanup-webapp.yml
40│   │       ├── deploy-webapp.yml
41│   │       ├── main.yml
42│   │       ├── start-tomcat.yml
43│   │       └── stop-tomcat.yml
44│   ├── jdk
45│   │   └── tasks
46│   │       └── main.yml
47│   └── tomcat8
48│       ├── defaults
49│       │   └── main.yml
50│       ├── files
51│       │   └── init.d
52│       │       └── tomcat
53│       ├── tasks
54│       │   └── main.yml
55│       └── templates
56│           └── setenv.sh.j2
57├── setup-app-roles.yml
58├── setup-app.yml
59└── Vagrantfile
60
61├── setup-app-roles.yml
62├── setup-app.yml
63└── Vagrantfile

Now, we have to choose a so-called Vagrant Box on Vagrant Cloud. A box is the package format for a Vagrant environment. It depends on the provider and the operation system that you choose to use. In our case, it is a Virtualbox VM image based on a minimal Ubuntu 18.04 system (box name is bento/ubuntu-18.04 ). This box will be configured in our Vagrantfile:

1Vagrant.configure("2") do |config|
2  config.vm.box = "bento/ubuntu-18.04"
3end

The next step is to ensure that Ansible will be installed in the box. Thus, we use the shell provisioner of Vagrant. The Vagranfile will be extended by the provisioning code:

 1Vagrant.configure("2") do |config|
 2  # ... other Vagrant configuration
 3  config.vm.provision "shell", inline: <<-SHELL
 4    sudo apt-get update -y
 5    sudo apt-get install -y software-properties-common
 6    sudo apt-add-repository ppa:ansible/ansible
 7    sudo apt-get update -y
 8    sudo apt-get install -y ansible
 9    # ... other Vagrant provision steps
10  SHELL
11end

The last step is to copy the SSH credential into the Vagrant box. Thus, we mark the SSH credential folder of the host system as a Shared folder, so that we can copy them to the SSH config folder inside the box.

 1Vagrant.configure("2") do |config|
 2
 3  # ... other Vagrant configuration
 4  config.vm.synced_folder ".", "/vagrant"
 5  config.vm.synced_folder "path to your ssh config", "/home/vagrant/ssh-host"
 6  # ... other Vagrant configuration
 7
 8  config.vm.provision "shell", inline: <<-SHELL
 9    # ... other Vagrant provision steps
10    cp /home/vagrant/ssh-host/* /home/vagrant/.ssh/.
11  SHELL
12end

On Github's Gist you can found the whole Vagrantfile.

Workflow

After setting up the tool chain let's have a look how to work with it. I write my Ansible playbook on the Windows system and run them from the Linux guest system against the remote hosts. For running the Ansible playbooks we have to start the Vagrant box.

1cd ansible-workspace > vagrant up

When the Vagrant box is ready to use, we can jump into the box with:

1vagrant ssh

You can find the Ansible playbooks inside the box in the folder /vagrant. In this folder run Ansible:

1cd /vagrant
2ansible-playbook -i inventories/test -u tekkie setup-db.yml

Outlook

Maybe on Windows 10 it's possible to use Ansible natively, because of the Linux subsystem. But I don't try it out. Some Docker fans would prefer a container instead of a virtual machine. But remember, before Windows 10 Docker runs on Windows in a virtual machine, so therefore, I don't see a benefit for using Docker instead of a virtual machine. But of course with Windows 10 native container support a setup with Docker is a good alternative if Ansible doesn't run on the Linux subsystem.

Do you another idea or approach? Let me know and write a comment.

  1. VirtualBox
  2. Vagrant
  3. Whole Vagrantfile on Github.