I have recently been looking at using Ansible for managing some Windows-based web servers.  Fortunately, I was able to get the authentication configured properly, but as soon as I got to downloading PHP, the Ansible win_get_url module started behaving oddly.  It downloaded some other files as I would have expected, but it would download the PHP distributable as a 1KB file.

What was weird was that the win_get_url command was returning HTTP 200 as the response code, which didn’t make much sense.  After some troubleshooting, I tried downloading the PHP binary using PowerShell directly.

PS C:\Users\fahmad\Desktop\temp> Invoke-WebRequest https://windows.php.net/downloads/releases/php-7.2.4-Win32-VC15-x64.zip
Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
At line:1 char:1
+ Invoke-WebRequest https://windows.php.net/downloads/releases/php-7.2.4-Win32-VC1 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Finally, I had some specifics that I could focus on.  A little more troubleshooting and I learned that this was caused by mismatching TLS configuration in PowerShell and windows.php.net’s appropriate modern requirement of TLS 1.2.

Looking around a little more, I found this post showing how to force PowerShell to use TLS 1.2.  I tried to figure out if there was a way to do this in context of the win_get_url module, but, unfortunately, I couldn’t figure it out.  So, I resorted to using the win_shell module and ended up with the following task.

- name: Download PHP
  win_shell: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri '{{ latest_php_url }}' -OutFile '{{ working_dir }}\\{{ latest_php_filename }}'"

Obviously, this is a time-dependent and not a long-term solution because once TLS 1.2 gets deprecated, this will have to be updated.  Hopefully, by then PowerShell can properly figure out the appropriate protocol automatically.

Back to blog...