Updating your Homelab with Ansible

What is Ansible?

Ansible is a simple automation and configuration management platform that makes it easy to push config to all your servers. Ansible uses the SSH protocol so it doesn’t rely on any agents. This makes it very easy to configure and crossplatform for Linux and Windows. Perfect for your Homelab!

Installing Ansible

Ansible can be installed on multiple distro’s of Linux. For this example I will be showing how to install it on Ubuntu 20.04 LTS.

First update your Ubuntu installation:

sudo apt update && sudo apt upgrade
sudo reboot

Next install Ansible via apt:

sudo apt install ansible

Creating your inventory file

When you use Ansible you need to setup a couple of things. Firstly a file containing information about the hosts you want to manage. This is called the Inventory:

sudo nano /etc/ansible/hosts

In this file you will declare information about your hosts you want to manage with Ansible. This can be an ip adres, host or fqdn. In this example i have split up the hosts in multiple groups with variables that are assigned to groups. These group names can be used later in Playbooks. Example inventory file:

[linux]

[linux:children]
ubuntu

[ubuntu]
ubuntuhost01
ubuntuhost02
ubuntuhost03
ubuntuhost04
ubuntuhost05

[linux:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_connection=ssh
ansible_user=ansible
ansible_become=yes
ansible_become_method=sudo

[windows]
windowshost01
windowshost02
windowshost03

[windows:vars]
ansible_connection=ssh
ansible_user=administrator@ad.domain.tld
ansible_shell_type=cmd

The example above has a couple of groups and variables. It starts with declaring [linux] servers. It then definies the childeren of [linux] servers via [linux:children]. In this example [ubuntu] with the hosts ubuntuhost01 through ubuntuhost05. Attached to [linux] are a couple of variables via [linux:vars].

[linux:vars]
# This defines the python interpreter used for all linux servers.
ansible_python_interpreter=/usr/bin/pytho

# Defines to use ssh for the connection to the host.
ansible_connection=ssh 

# Defines the user that is being used for the connection to the host.
ansible_user=ansible 

# Define Ansible to elevate to root account.
ansible_become=yes 

# Define to use the sudo method to elevate to root.
ansible_become_method=sudo

After creating your inventory file. You can test the Ansible connection with the ping command:

ansible all -m ping

For more examples and options for inventory files. Have a look at the Ansible documentation at https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

Connecting to Windows hosts via SSH

As you may have noticed in the [windows:vars] section i have defined a couple of variables for Windows hosts. Starting with declaring to use the SSH protocol. To be able to use SSH on Windows we need to first prepare Windows to allow SSH connection. This can be done as followed:

# Install the OpenSSH Server.
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

# Start the sshd service.
Start-Service sshd

# Setting the sshd service to startup automaticly.
Set-Service -Name sshd -StartupType 'Automatic'

# Confirm the Firewall rule is configured. It should be created automatically by setup.
Get-NetFirewallRule -Name *ssh*

# There should be a firewall rule named "OpenSSH-Server-In-TCP", which should be enabled.

# If the firewall does not exist, create one.
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

You should now be able to connect to your Windows host via SSH.

Ansible Playbooks

Pushing configuration via Ansible to hosts defined in your inventory file is done via Playbooks. Playbooks are YAML files declaring what Ansible should do on the target hosts.

Running playbooks with Ansible is very straightforward. The most basic command is this:

ansible-playbook playbook.yml

This command runs Ansible with the playbook playbook.yml against the default inventory file we created earlier in /etc/ansible/hosts.

For more indepth options about the ansible-playbook command have a look at the documentation at https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html

Playbook to update Linux servers

Now on to the main task updating your servers with Ansible. We are going to start with the Linux servers. As stated earlier Ansible uses playsbook for defining tasks. So we need to start building out a playbook that sets up a connection to the host, run apt update, run apt upgrade and reboot if needed. For these tasks i use the playbook below.

---
 - hosts: ubuntu
   gather_facts: true
   tasks:
   - name: Check and update
     block:
       - name: Install all updates
         apt:
             update_cache: yes
             upgrade: dist
             autoremove: yes
             autoclean: yes
         register: update_results
       - name: Update results
         debug:
             msg: "Update results: {{ update_results.stdout_lines }}"
       - name: Reboot system if required
         shell: shutdown -r now 'Rebooting to complete system upgrade'
         args:
             removes: /var/run/reboot-required
       - name: Wait for system to become reachable again
         wait_for_connection:
             delay: 60
             timeout: 300

Ansible has loads of predefined commands you can use to build up your playsbook. In this example i am using the buildin apt module. The playbook is really straight forward. First it runs the apt command with the options update_cache, upgrade, autoremove and autoclean. It then registers the results in the variable update_results. It then messages the results to the prompt. After that i checks if the updates require a reboot and performs the reboot if needed.

Playbook to update Windows servers

As stated above Ansible has loads of buildin modules readily available for you to use in your playbooks. This also counts for updating Windows servers. For this i use the following playbook.

---
 - hosts: windows
   gather_facts: true
   tasks:
   - name: Windows updates
     block:
       - name: Install Windows updates
         win_updates:
           category_names:
            - CriticalUpdates
            - SecurityUpdates
            - UpdateRollups
            - Updates
            - DefinitionUpdates
           reboot: yes
           log_path:  C:/ansible_windows_updates.log
         register: update_results
       - name: Update results
         debug:
           msg: "Update results: {{ update_results }}"

Like the Linux update playbook this Windows update playbook is really straight forward. It uses the win_updates module with the specified categories. It then reboots the servers if needed and appends the logs to the ansible_windows_updates.log file and reports the results to the prompt.

Conclusion

You should now have a basic understanding about using Ansible to perform updates on your Linux and Windows servers in your homelab. Ansible is a very powerful tool that offers loads of options. For more playbook examples have a look at my GitHub page at https://github.com/tizutech

6 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. Hi, thanks for your post, it was good to see how I can perhaps use Ansible in my own home lab as well. I’ve been working through Jeff Geerling’s guide on Ansible for DevOps. I’ve gotten my head around how I can use Ansible to update my servers and to help in completing ad-hoc commands. But, haven’t quite worked out how I can set playbook’s to build – say a new replacement server for my network – and built it the way I want – Have you created any Play’s that like include other roles etc from say – Ansible-Galaxy etc? One of the things I’m conscious of is, I don’t want to re-write the wheel if I know I can include roles from other projects to make mine work – Hopefully that’s making sense. How you got any more play’s you can push to Github?