Quick guide to install Ansible on a Raspberry Pi and manage other Pi’s remotely.
All you need….
- Ansible [ www.ansible.com ] - we install the free version
- PuttY or similar [ www.putty.org ]
- Raspbian Buster Lite [ version August 20th 2020 ] [ .zip ] [ www.raspberrypi.org ]
Step 1
Install Ansible on the Master Node and add Ansible under Debian to PPA [Personal Package Archive].
cd /etc/apt
sudo nano sources
A great thing is that the Ubuntu PPA works also for Raspbian Buster, at the top of the file add:
deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main
Step 2
Update your image and install Ansible.
sudo apt-get update
sudo apt-get install ansible
Step 3
Open the [hosts] file and add the following.
sudo nano /etc/ansible/hosts
Define your hosts on the network as [master] and [slaves]. The great thing is Ansible controls via SSh so no extra installation on the [slaves]. However, note that you need to setup SSH on all nodes to remove the password prompts.
## set up ssh user name and path to python3 ##
[all:vars]
ansible_user='pi'
ansible_become=yes
ansible_become_method=sudo
ansible_python_interpreter='/usr/bin/env python3'
[master]
pi@10.0.30.101 //or whatever IP your Pi is under
[slave]
pi@10.0.30.102 //or whatever IP your Pi is under
pi@10.0.30.103 //or whatever IP your Pi is under
Note you can also combine IP ranges as [slaves] and write the IP’s like the following.
pi@10.0.30.[102:103]
Step 4
Let’s [“ping”: “pong”] our Pi’s.
ansible all -m ping
10.0.30.101 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.0.30.102 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.0.30.103 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Step 5
Writing a playbook. Let’s [update] and [upgrade] all Pi’s at once…
cd /etc/ansible
mkdir playbooks
touch update_upgrade.yml
Inside the playbook [update_upgrade.yml], we also add to the configuration to use sudo to install the updates and upgrades. Always good to find out if we need to reboot the Pi afterwards.
---
- hosts: all
remote_user: pi
become: true
become_method: sudo
tasks:
- name: Update apt repo and cache on all boxes
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
- name: Upgrade all packages on Pi's
apt: upgrade=dist force_apt_get=yes
- name: Check if a reboot is needed on all Pi's
register: reboot_required_file
stat: path=/var/run/reboot-required get_md5=no
- name: Reboot the Pi's if kernel updated
reboot:
msg: "Reboot initiated by Ansible for kernel updates"
connect_timeout: 5
reboot_timeout: 300
pre_reboot_delay: 0
post_reboot_delay: 30
test_command: uptime
when: reboot_required_file.stat.exists
Step 6
Run the playbook on the master Pi.
ansible-playbook -i hosts update.yml
The file is now in [staging] try to run [git status] again. You should see your file in green that should be committed. To commit the file with a note run:
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************
ok: [pi@10.0.30.101]
ok: [pi@10.0.30.103]
ok: [pi@10.0.30.102]
TASK [Update apt repo and cache on all boxes] *****************************************************************
changed: [pi@10.0.30.101]
changed: [pi@10.0.30.103]
changed: [pi@10.0.30.102]
TASK [Upgrade all packages on Pi's] ******************************************************************
ok: [pi@10.0.30.101]
ok: [pi@10.0.30.103]
ok: [pi@10.0.30.102]
TASK [Check if a reboot is needed on all Pi's] ****************************************************************
ok: [pi@10.0.30.101]
ok: [pi@10.0.30.103]
ok: [pi@10.0.30.102]
TASK [Reboot the Pi's if kernel updated] ******************************************************************
ok: [pi@10.0.30.101]
ok: [pi@10.0.30.103]
ok: [pi@10.0.30.102]
PLAY RECAP **************************************************************************
pi@10.0.30.101 : ok=2 changed=0 unreachable=0 failed=0
pi@10.0.30.102 : ok=2 changed=0 unreachable=0 failed=0
pi@10.0.30.103 : ok=2 changed=0 unreachable=0 failed=0
Step 6
Done. Well, there is a lot more you can achieve with Ansible…