Installing Ansible in a mixed Operating System lab environment

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.

5/20/20245 min read

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/id_rsa.pub | 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:

SeAssignPrimaryTokenPrivilege

SeTcbPrivilege

SeBackupPrivilege

SeRestorePrivilege

SeImpersonatePrivilege

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:

[development-win]

<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:

https://github.com/ansible/ansible/blob/devel/examples/scripts/ConfigureRemotingForAnsible.ps1

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

AND

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.

Pete