Hits: 12298

Ansible is a very powerful IT automation platform which can manage significant numbers of mixed operating system devices, from a central instance. Installing this into my Development lab environment has proven to be highly beneficial, but due to the mix and age of the server estate, it was not particularly straightforward. This blog post describes what I had to do, in order to implement it.

The central server is a Linux box and the clients are comprised of a Windows 2016 server and a further Linux instance.
Before Ansible can execute commands on these clients remotely, it needs to be able to connect to them using ssh without a password. Once that is set up then Ansible can run the relevant scripts. There is a -ask-pass option in Ansible but that requires a password to be stored and it added as a variable to the scripts.

Create Ansible logins for the Linux devices

Log in A as user a and generate a pair of authentication keys. Do not enter a passphrase
ssh-keygen -t rsa
Use ssh to create a directory ~/.ssh as user b on B
ssh b@B mkdir -p .ssh
enter password
Append a's new public key to b@B:.ssh/authorized_keys
cat .ssh/ | ssh b@B 'cat >> .ssh/authorized_keys'
From a on A you can now ssh b@B
You might need to add the public key to .ssh/authorized_keys
You might need to change permissions of .ssh to 700
You might need to change permissions of .ssh/authorized_keys2 to 640

Create Ansible logins for the Windows server

For Windows 2016 server, if it is new enough
Update the server with the latest patches and upgrade if necessary
Load a Windows Subsystem for Linux
Turn on Developer mode
Settings -> Update and security -> For developers
Open a PowerShell prompt as Admin and run the command
Windows -> Windows PowerShell ISE
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
Restart the windows server
So WSL (Windows Subsystem for Linux) is installed but Ubuntu is not yet.
Open a command window and type bash
Accept the license
Enter a username and password once prompted
Can use the shortcut, start menu item or type bash at the command.
However, this server was "elderly" and therefore does not support WSL. So, I cut my expecations down to only OpenSSH on the Windows box as that is all that is required for Ansible to run. Below is the process (with the many blind alleys cut out for the sake of brevity and your sanity) :-)
Download OpenSSH for Windows
Extract the zip file into C:\Program Files\OpenSSH
In Powershell, go to that directory and run .\install-sshd.ps1
Then create a directory call ssh in c:\ProgramData
Back in C:\Program Files\OpenSSH run .\ssh-keygen -A
then PowerShell -ExecutionPolicy ByPass -File .\FixHostFilePermissions.ps1
In Windows FIrewall, permit incoming connections to tcp port 22
Finally in Services, start the OpenSSH Authentication Agent, followed by the OpenSSH SSH Server.
For me, the OpenSSH SSH Server started and then died, due to a problem with User Rights Assignment. If you have the same problem then for the OpenSSH SSH Server, right click on it, go to the Log On tab and get it to log on as Administrator. You will know if the below fix will sort this, if you can start sshd.exe from the command line as Administrator and it does not die. If so then please do the below.
1. First, lets find the missing user privileges so run regedit and look for ssh to look for permissions. I found them in HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\sshd. This gave me the below list:
2. I then googled these to see firstly what group policy setting each corresponds to and also how to assign them to Administrator. This is what I found
SeAssignPrimaryTokenPrivilege -> Replace a process level toekn
SeTcbPrivilege -> Act as part of the operating system
SeBackupPrivilege -> Back up files and directories
SeRestorePrivilege -> Restore files and directories
SeImpersonatePrivilege -> Impersonate a client after authentication
3. Ok, so how do I add them to the local Administrator?
Run the local group policy editor and then navigate to local computer policies -> computer configuration -> windows settings -> security settings -> local policies -> user rights assignment. Then select each of the above e.g. Act as part of the operating system, right click on it, go to Properties and then add user or group. Add Administrator and click Check Names then ok. Do this for each of the above 5 privileges.
Assuming that all of the above has worked, you should now be open to start the OpenSSH SSH Server services, logged on as Administrator, and it should stay up.
I could now ssh into the server from the rest of my Linux network and once it was tested ok, I set it to start Automatically. Job done :-)
Unfortunately not. Although the above gave me command line ssh access to my Windows client from my Linux central server, it did not work for Ansible. For Ansible, I ended up using WinRM (see the Windows 2016 server section) but I only found that out once I had installed Ansible.

Installing Ansible

Finally, I can get to the Ansible installation and unsurprisingly, I have picked a Linux box to run it from. Having worked through the above so it can ssh into every other server (both Windows and Linux), I was ready to install Ansible. As I am running Ubuntu on this box, I did the following:
I had Python already on this box for the AWS CLI but I was not sure if I had all that Ansible needed so I checked for the pre-requisite
sudo apt-get install python-software-properties
sudo apt-add-repository -y ppa:ansible/ansible
sudo apt-get update
sudo apt-get install -y ansible
This all seems to go swimmingly so I checked by running ansible --version and yes, all is well.

Windows 2016 server management

As I said previously, I had to install WinRM on the Windows 2016 server, despite being able to use command line ssh already.
1. Install and configure WinRM on the Ansible host do:
sudo apt install python-pip (in case it is not installed)
pip install "pywinrm>0.2.2"
2. Created development-win-inventory.yml file which just had the [header] and then the single Win 2016 server in it. So it looks like this:
<Central Ansible server> ansible_user: Administrator ansible_password: <password for administrator> ansible_port: 5986 ansible_connection: winrm ansible_winrm_server_cert_validation: ignore
3. Create a new ansible.cfg file called ansible=windows.cfg in /etc/ansible
In ansible-windows.cfg, under [ssh_connection] add the line ssh_args = -C-o ControlMaster = yes ControlPersist = 60s
4. Install and configure WinRM on the Windows 2016 server by running the Powershell script, ConfigureRemotingForAnsible.ps1
from here:
5. Finally, back on the Ansible Linux box, run the following:
ansible development-win -m win_ping -i /etc/ansible/development-win-inventory.yml --extra-vars "ansible_config /etc/ansible/ansible-windows.cfg"

Using Ansible

Works for local linux and ec2 instances
ansible development-linux -m ping
get the .pem file for the ec2 instance and do
ansible ec2 -m ping -u ec2-user --key-file /home/pgroom/ec2-key-pair.pem
Can pull back files using sudo by doing
ansible development-linux --become-method=sudo -m fetch -a "src=/etc/hosts dest=/tmp"
I hope that the above may of some benefit to someone as there were a few "rabbit holes" that I had to navigate in order to build this. If you are building an Ansible environment then I bid you good luck.
I have also written up my notes for Selenium & Python, Docker and php & curl, which may prove useful to someone. 
All the best.