Automate Fedora IoT configuration on a Raspberry Pi 4 with Ansible
In Install Fedora IoT on Raspberry Pi 4, I explained how to install Fedora IoT. If you followed along with the article, you have a functional Raspberry Pi 4 system with the latest updates but no configuration.
In this article, I'll use Ansible to automate the device configuration by creating a playbook that sets the hostname, adds a new user, layers additional packages, and more.
By default, Fedora IoT comes with Python preinstalled. Together with Secure Shell (SSH), it has everything needed to support Ansible automation as a client. To follow along with this example, you need Ansible installed in a "control" machine that has access to the Raspberry Pi.
[ Get started with IT automation with the Red Hat Ansible Automation Platform beginner's guide. ]
Test connectivity with Raspberry Pi
Before working on the playbook, ensure Ansible can talk to the Raspberry Pi. To do this, first create an inventory file with connection details. You'll use this inventory file again later to execute the playbook.
Create the inventory file inventory.yaml
with this content, replacing the IP address and SSH key with the ones appropriate for your environment:
all:
children:
edge:
vars:
ansible_ssh_private_key_file: /home/ricardo/.ssh/id_rsa
ansible_ssh_user: root
hosts:
rpi4iot:
ansible_host: 192.168.10.152
Then run ansible
with the ping
module to test connectivity:
$ ansible edge -i inventory.yaml -m ping
rpi4iot | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
Create the Ansible playbook
Ansible is highly flexible and you can use it to configure every aspect of your Raspberry Pi, including deploying the applications you want to run on it. For this example, I'm starting with the basic configuration.
This playbook has four goals:
- Adding a new unprivileged user with
sudo
access to avoid usingroot
to connect to the system. - Configure the system hostname
- Deploy additional required packages layered on top of the base image:
- tmux
- htop
- cockpit
- cockpit-podman
- Enable Cockpit to start on boot
You can use this playbook as a starting point to add your own configurations later.
[ Write your first playbook in this hands-on interactive lab. ]
In addition to the builtin
collection, you need to install two additional collections to enable Ansible to support these goals: ansible.posix
to update firewall rules and community.general
to manage sudoers
files and layer new packages to ostree
. Install them using ansible-galaxy
:
$ ansible-galaxy collection install \
ansible.posix community.general
Then create the playbook playbook.yaml
with this content. Replace the variables with values that are appropriate for your environment:
---
- name: Configure Fedora IoT on Raspberry Pi
hosts: edge
gather_facts: true
vars:
user_name: ricardo
user_full_name: Ricardo
user_ssh_pub_key: /home/ricardo/.ssh/id_rsa.pub
tasks:
- name: Define hostname
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
- name: Add unprivileged user
ansible.builtin.user:
name: "{{ user_name }}"
comment: "{{ user_full_name }}"
uid: 1000
group: wheel
state: present
- name: Set authorized key for new user
ansible.posix.authorized_key:
user: "{{ user_name }}"
state: present
key: "{{ lookup('file', user_ssh_pub_key) }}"
- name: Allow group wheel sudo access no password
community.general.sudoers:
name: wheel-all
group: wheel
commands: ALL
nopassword: true
- name: Ensure packages tmux, htop, and cockpit are available
community.general.rpm_ostree_pkg:
name:
- tmux
- htop
- cockpit
- cockpit-podman
state: present
register: ostree_results
- name: Reboot system to enable new packages
ansible.builtin.reboot:
reboot_timeout: 600
when:
- ostree_results is changed
- name: Ensure Cockpit socket is started and enabled
ansible.builtin.systemd:
name: cockpit.socket
state: started
enabled: true
- name: Allow access to Cockpit
ansible.posix.firewalld:
service: cockpit
permanent: true
state: enabled
immediate: true
Notice that I added a when
condition to the "Reboot" task to execute only if the previous task makes a change to the system. The line "Ensure packages tmux, htop, and cockpit are available" does make a change to the system. This enables the playbook to be idempotent, ensuring the system reboots only if needed.
[ Download now: A system administrator's guide to IT automation. ]
Execute the playbook
Now, run the playbook using the inventory file inventory.yaml
that you created before:
$ ansible-playbook -i inventory.yaml playbook.yaml
PLAY [Configure Fedora IoT on Raspberry Pi] ***********************************
TASK [Gathering Facts] ********************************************************
ok: [rpi4iot]
TASK [Define hostname] ********************************************************
changed: [rpi4iot]
TASK [Add unprivileged user] **************************************************
changed: [rpi4iot]
TASK [Set authorized key for new user] ****************************************
changed: [rpi4iot]
TASK [Allow group wheel sudo access no password] ******************************
changed: [rpi4iot]
TASK [Ensure packages tmux, htop, and cockpit are available] ******************
changed: [rpi4iot]
TASK [Reboot system to enable new packages] ***********************************
changed: [rpi4iot]
TASK [Ensure Cockpit socket is started and enabled] ***************************
changed: [rpi4iot]
TASK [Allow access to Cockpit] ************************************************
changed: [rpi4iot]
PLAY RECAP ********************************************************************
rpi4iot : ok=9 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Now you can access the Raspberry Pi with the regular user you created instead of root
:
$ ssh -i /home/ricardo/.ssh/id_rsa 192.168.10.152
Boot Status is GREEN - Health Check SUCCESS
Web console: https://rpi4iot:9090/ or https://192.168.10.152:9090/
Last login: Thu Mar 9 05:28:28 2023 from 192.168.10.122
[ricardo@rpi4iot ~]$
Notice that the hostname is updated and Cockpit is available.
[ Download the Raspberry Pi cheat sheet. ]
What's next?
Your Fedora IoT on Raspberry Pi looks much better now—even with a basic configuration. Use this Ansible automation playbook as a starting point and add remaining configurations according to your requirements. The best part is that it's reproducible. If you have an issue or need to reinstall the system, you can use the same playbook and, in a few minutes, your Raspberry Pi will be ready again.
Now the system is ready to run workloads like the container-based home automation application I want to run on mine. But before that, in the next article, I'll show how to use Greenboot to run health checks and ensure the system runs smoothly and resiliently.
Ricardo Gerardi
Ricardo Gerardi is Technical Community Advocate for Enable Sysadmin and Enable Architect. He was previously a senior consultant at Red Hat Canada, where he specialized in IT automation with Ansible and OpenShift. More about me