Skip to content

It can do Windows too – Running Ansible on Windows

Running Ansible playbooks against Linux systems is common. The Ansible core team and the community have developed all sorts of modules that grow day by day in functionality. But there is also a quite broad base on modules, which have a Windows couterpart. I thought, it must be hard to get the communication right between Ansible and a Windows system, but it’s easier than you might think. And because it’s more fun, let’s do it with OpenSSH instead of WinRM.

Since Ansible 2.8, Ansible supports a connection to a Windows system, using a SSH connection. It’s still beta, although we’re now up to Ansible 2.12. But I made the experience, that it’s one, quite easy to setup and two, worked for me reliable. You may want to check the official documentation on the current status of the OpenSSH support for Windows and Ansible here. There is one downside when it comes to Windows in general (regardless if you want to use WinRM or SSH to connect to it). You need to configure it cause no connection option is enabled and configured out of the box. This brings manual overhead or you need to be aware when provision the Windows host.

To setup Windows for OpenSSH is not hard to do. Download the latest release of OpenSSH for Windows for your architecture from here. Place the Archive on your Windows host and extract it to C:\Program Files\OpenSSH. Then, start an elevated Powershell and head to the directory you placed the Archive content in. Run the following command in the Powershell.

powershell.exe -ExecutionPolicy Bypass -File install-sshd.ps1

If you’ve enabled the Windows Firewall, you have to add an allow rule for SSH traffic. You can use the same Powershell and use the following command:

New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

Now head to the Service management and set the start type of the OpenSSH Server service to autostart and start the service then.

The next step is optional, you can select which shell OpenSSH should use. By default, this is good old cmd.exe. I prefer powershell.exe though, so I would also recommend you to change the default shell to Powershell. You can do so by running the following command within the same elevated Powershell than before.

 New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
 New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShellCommandOption -Value "/c" -PropertyType String -Force

What it basically does, it adds two registry entries which control the OpenSSH server behavior.

So now, you should already be able to connect to the Windows host using SSH. Let’s try it out:

❯ ssh administrator@vmwindows22
The authenticity of host 'vmwindows22 (xxx.xxx.xxx.xxx)' can't be established.
ED25519 key fingerprint is SHA256:+CPKNuFnjHIGUTa8m9+ieZvxn2NJULxv8nRv3CHkuV4.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'vmwindows22' (ED25519) to the list of known hosts.
administrator@vmwindows22's password:

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Users\Administrator>

What’s missing is the Ansible configuration in your inventory / host-file. I’ve added my newly build Windows server to a group called [windows] and added some group variables to it.

[windows]
vmwindows22 ansible_host=xxx.xxx.xxx.xxx

[windows:vars]
ansible_user=administrator
ansible_connection=ssh
ansible_shell_type=powershell

As you can see, I provided powershell as the value for ansible_shell_type. If you decided to stay with cmd.exe above, you need to specify cmd in your hosts file also. Also the ansible_user may vary in your case to another user. If you feel it, you can also write down the administrator password in the hosts file by using the ansible_password parameter. I would never recommend you to do so. But I have to mention a known issue regarding using SSH keys for authentication when using Ansible with SSH on Windows. At least at the time of writing this, there are situations, were you will experience problems in doing so. Check the documentation linked above for details.

Now I thought, let’s try to run the win_ping adhoc command of Ansible against the host, to see if it is working. I got the error message down below.

❯ ansible -m win_ping windows -i hosts
vmwindows22 | FAILED! => {
    "msg": "The module win_ping was redirected to ansible.windows.win_ping, which could not be loaded."
}
}

This may also differ from your experience, cause the solution is simply, to install the ansible.windows collection with this command: ansible-galaxy collection install ansible.windows.

The next error I stumbled over was when, that I missed to install sshpass on my Ansible control host. I did so by using the apt package manager and then finally, the adhoc command worked:

❯ ansible windows -m win_ping -i hosts -k
SSH password:
vmwindows22 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Good and done I would say. Time to write some awesome Ansible playbooks for Windows then!

Philip

Leave a Reply

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