Once all the system requirements have been met, as detailed previously, the task that remains is to enable the WinRM listener. With this achieved, we can actually run Ansible tasks against the Windows host itself! WinRM can run over both HTTP, and HTTPS protocols, and, while it is quickest and easiest to get up and running over plain HTTP, this leaves you vulnerable to packet sniffers and the potential for sensitive data to be revealed on the network. This is especially true if basic authentication is being used. By default, and perhaps unsurprisingly, Windows does not allow remote management with WinRM over HTTP or using basic authentication.
Sometimes, basic authentication is sufficient (for example, in a development environment), and if it is to be used, then we definitely want to enable HTTPS as the transport for WinRM! However, later in the chapter, we will look at Kerberos authentication, which is preferable, and also enables the use of domain accounts. For now though, to demonstrate the process of connecting Ansible to a Windows host with a modicum of security, we will enable WinRM over HTTPS using a self-signed certificate, and enable basic authentication to allow us to work with the local Administrator account.
For WinRM to function over HTTPS, there must exist a certificate that has the following:
- A CN matching the hostname
- Server Authentication (1.3.6.1.5.5.7.3.1) in the Enhanced Key Usage field
Ideally, this should be generated by a central certificate authority (CA) to prevent man-in-the-middle attacks and such—more on this later. For the sake of simplicity, we will generate a self-signed certificate. Run the following command in PowerShell to generate a suitable certificate:
New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "$env:computername" -FriendlyName "WinRM HTTPS Certificate" -NotAfter (Get-Date).AddYears(5)
This should yield something like the following—make a note of the certificate thumbprint, as you will need it later:
With the certificate in place, we can now set up a new WinRM listener with the following command:
New-Item -Path WSMan:\Localhost\Listener -Transport HTTPS -Address * -CertificateThumbprint <thumbprint of certificate>
When successful, that command sets up a WinRM HTTPS listener on port 5986 with the self-signed certificate we generated earlier. To test this setup, we need to perform two more steps—open up this port on the firewall, and enable basic authentication so that we can test using the local Administrator account. This is achieved with the following two commands:
New-NetFirewallRule -DisplayName 'WinRM HTTPS Management' -Profile Domain,Private -Direction Inbound -Action Allow -Protocol TCP -LocalPort 5986
Set-Item -Path "WSMan:\localhost\Service\Auth\Basic" -Value $true
You should see output from the previous commands as follows:
These commands have been broken out individually to give you an idea of the process involved in setting up a Windows host for Ansible connectivity. For automated deployments, and systems where New-SelfSignedCertificate isn't available, consider using the ConfigureRemotingForAnsible.ps1 script available on the official Ansible GitHub account here:
This script performs all the steps we completed previously (and more), and can be downloaded and run in PowerShell as follows:
$ansibleconfigurl = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$ansibleconfig = "$env:temp\ConfigureRemotingForAnsible.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($ansibleconfigurl, $ansibleconfig)
powershell.exe -ExecutionPolicy ByPass -File $ansibleconfig
There are many other ways to roll out the required configuration of WinRM for Ansible, including via Group Policy—however, this section sufficiently outlines the steps involved for successful future rollout.