How to Update your Linux and Windows Devices using Ansible and Gitlab Pipelines.
What is this?
Ensuring all your servers are running the latest software is something we all know we should be doing, however, can be a time-consuming task. This is a quick and dirty method (not for production) which can be used to take Ansible Pipelines and run them from a Gitlab Pipeline on a weekly schedule to ensure all your servers are getting updates applied
💡 Why do I say not production? In a production environment you should be testing updates, testing software runs on updates, caching the files and running security checks. However on a dev or home network, you may well just be happy deploying the OS's recommended updates.
Before you start with this, I'd strongly suggest reading a previous post which explains how Gitlab runs pipelines and uses schedules. the interface layout has changed a little since I wrote the post however the basic information is still relevant.
For this post the example setup is
1 x Fedora 38
2 x RPI Running Raspian
1 x Windows 11 Desktop
I'll run Ansible from the Fedora device and this is also a Gitlab runner using the tag : runner
Setup Ansible Host and Groups
On the host fedora.net a list of hosts which Anisible needs to contact
sudo nano /etc/ansible/hosts
Add the following hosts
Whats happening here?
I've setup groups
home = all devices
fedora = fedora hosts
raspberrypi = raspberry pi devices
win = windows devices
These groups are used in the ansible playbooks below
For Windows I've set up an Ansible user on Windows and will be using SSH rather than WinRM for communication from the ansible host to the windows server
💡 I've never had a good time with WinRM, and while the WinSSH is still in beta I found it easier to work with purely on a consistent factor.
Setup Windows with Ansible
The documentation for this setup was taken from Ansible's doc repository
I chose to manually install SSH on my single device, if you have more there is a choco install.
I downloaded the latest MSI From the site (this URL at time of writing)
This was installed and runs as a service.
Win32-OpenSSH authentication with Windows is similar to SSH authentication on Unix/Linux hosts. You can use a plaintext password or SSH public key authentication.
For the key-based authentication:
Add your public keys to an
authorized_keyfile in the
.sshfolder of the user’s profile directory.
Configure the SSH service using the
When using SSH key authentication with Ansible, the remote session will not have access to user credentials and will fail when attempting to access a network resource. This is also known as the double-hop or credential delegation issue. To work around this problem:
Use plaintext password authentication by setting the
becomedirective on the task with the credentials of the user that needs access to the remote resource.
To configure Ansible to use SSH for Windows hosts, you must set two connection variables:
ansible_shell_type variable should reflect the
DefaultShell configured on the Windows host. Set
cmd for the default shell. Alternatively, set
powershell if you changed
DefaultShell to PowerShell.
I've set these variables in the /etc/ansible/hosts file
To use windows functionality in a playbook the following collection needs to be installed.
ansible-galaxy collection install ansible.windows
Check SSH works from the Ansible host
Confirm you can ssh into the Windows device
If you have issues here try the following:
Check the service is running on Windows
Check the ssh port is open on windows firewall
Check any firewalls between the ansible host and the windows device
Check the Windows logs
With communications setup from your ansible host and the various endpoints the next step is to create playbooks for updating
Ansible Playbook for Fedora
Because I'm running Fedora on my host I've pointed this playbook to the local server.
- hosts: 127.0.0.1
# become_user: root
- name: Update all installed packages using YUM module
- name: Remove packates not needed anymore
Using dnf to update
Ansible Playbook for Raspbian
From the Fedora host this playbook is targeting the raspberrypi group we previously setup in the /etc/ansible/host file
- hosts: raspberrypi
# become_user: root
- name: Update apt repo and cache on all Debian/Ubuntu boxes
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
- name: Upgrade all packages on servers
apt: upgrade=dist force_apt_get=yes
- name: Clean unwanted olderstuff
- name: Check if a reboot is needed on all servers
stat: path=/var/run/reboot-required get_md5=no
Ansible Playbook for Windows
This will run on Windows 7 ,10 and 11 and will update multiple types of upgrades available to Windows.
The Playbook will reboot the windows host if required.
- name: Windows connection testing from Ansible
- name: Ansible ping testing to Windows
- name: windows rolling update
- name: Install all critical and security updates
Gitlab Pipeline files
With the Playbooks in place Gitlab requires a .gitlab.yaml file which acts as the pipeline which will be run at the schedule time
# - test
##Updates to Manjaro servers using pacman
- hostname -f
- /usr/bin/ansible-playbook updatelocalserver.yaml
- hostname -f
- /usr/bin/ansible-playbook updateubuntu.yaml
- hostname -f
- /usr/bin/ansible-playbook updatewindows.yaml
I've set the pipeline to run as a deploy, however provided a test block if needed prior to updates.
Within Gitlab the pipeline would be displayed as follows
And a run will look as follows
This is an overview, its designed to point a person in a direction and needs work to be used in anything other than a dev/home lab.
However it does show that updates can be automated using code and pipeline across Linux and Windows.