With Ansible configured on the Pi cluster, it is time to have it do something useful. When working with a clustered system, even the simplest tasks become tedious and time consuming. For example, updating the system. While I could manually update each of the 3 pi nodes, it is not scalable to 10 or 30 nodes, let alone hundreds or thousands. Tools like Ansible, make doing tasks such a supdating clustered systems, trivial again. In this post, I will walk through setting up an Ansible playbook to update my Pi cluster.
The first task when using Ansible is to setup the
hosts file. No, not the normal
/etc/hosts file, but the other one just for Ansible, which can be found at
/etc/ansible/hosts. Configuring the Ansible hosts file is fairly straightforward. Groups of computers are defined using
[brackets], with computer ip/hostnames of the group are listed below. For example:
A nice feature of group definitions is that hierical structures can be constructed using the
:child suffix in order to create groups of groups. For example, for my homelab, I like to make an ansible hosts file that splits out my servers based on their distribution, and then group those by their packaging type. This makes it easier for me to do generic updates, which is what I mostly use ansible for (at this point). So, for example:
[ubuntu] mrmime geodude [debian] ninetales [fedora] fedora-test [centos] tangels [arch] meowth staryu diglet [deb:children] ubuntu debian [rpm:children] fedora centos
For use with the cluster, I kept it simple, although I did opt to create rpi/bpi subgroups:
[cluster:children] rpis bpis [rpis] pi0 pi1 [bpis] bpi
Once the hosts file is setup, it can be tested using the
ping module. I tested my
cluser group, as well as the
ansible rpis -m ping ansible bpis -m ping ansible cluster -m ping
Assuming the steps of the last post were done correctly, this should work. If not, double check that post and make sure everything looks correct.
After confirming that the hosts file is properly configured, I started to dig into playbooks. Playbooks are Ansible’s scripting system used to configure, deploy, and orcistrate systems. They can describe ways in which systems should be configured (ex: enable ssh), or outline a set of steps for an IT task (ex: running updates, restarting a server). As stated in the playbook documentation:
Playbook files are expressed using YAML syntax, which is easy to read, but still powerful. The first step when creating a new playbook, being a YAML file, is to set the header and footer. The header consists of three
-’s at the top of the file, and the footer ends the file with three periods (
.). This indicates the start and end of the document.
When writing a playbook to update the pi cluster, I first needed to declare what systems the playbook is used with. To do that, I used the
hosts key, and provided it with the
cluster group name, which is defined in my
/etc/ansible/hosts file, as the value.
--- - hosts: cluster ...
After the hosts are defined, modules can be added to update the nodes. To list the tasks, I used the
taks: key, with the same indentation as the
hosts: keyword. Instead of using a single value, I provided the
tasks: keyword with a list of things to do. The first task I want to do when updating the nodes is to check that they running and connected. This can be accomplised with the ping module that I used earlier in the post. The ping module will try to connect to each node, verify that a usable python is installed, and return
pong upon success. To add the module, I added
- ping: ~, indented, to the line below
--- - hosts: cluster tasks: - ping: ~
After defining the ping module, I started to get a bit fancier. Well… a little bit fancier. Each node in my pi cluster is running some verison of Ubuntu, which uses apt as it’s package manager. If I wanted to ssh into each node and update them manually, the steps I would follow would be to 1) run the command
sudo apt-get update to update the repository cache, and 2) run
sudo apt-get upgrade to actually install the updates. To recreate these commands in the playbook, I used the apt module. To start with updating the repository cache, I added the following lines to my playbook:
- name: Update APT package manager repositories cache become: true apt: update_cache: yes
name: defines the name of the task, and is the text printed out to the console when executing this step of the playbook. Setting the
become key to
true tells Ansible to run the command with privilege escalation (sudo). Lastly, the remaining two lines run the
update_cache: functionality of the apt module.
With the repositories updated on each node, I can have ansible run the updates by adding the following lines to the playbook (after the cache update ones):
- name: Upgrade installed packages become: true apt: upgrade: dist
This set of commands is very similar to the last group. The
name: again provides a description of what the task is doing, and privilege escalation is used again via
become: true. The only difference is that the apt module is using the
upgrade: dist command instead. This will run the updates for any installed packages on the system.
Update Cluster Playbook
I then had a completed playbook to update the pi cluster:
--- - hosts: cluster tasks: - ping: ~ - name: Update APT package manager repositories cache become: true apt: update_cache: yes - name: Upgrade installed packages become: true apt: upgrade: dist ...
The last step is to test it out! Playbooks can be executed using the
When running the playbook, ansible will first attempt to gather facts about each node, and then begin to run each of the tasks defined in the playbook. At each step, it will print out the
name of each task, followed by the status/result for each node. When it completes, all the nodes in the cluster should be updated. Now you can update three+ computers with a single command! Enjoy!
Exporting Proxmox VMs Configuring Ansible on the Pi Cluster