Automatically configure and update your Raspberry PI with Ansible scripts

Ansible logo

Ansible is a simple to use but yet very very powerful free software provisioning, and configuration management.

You can use to define in a readable YAML config file with everything you want installed and configured inside the raspberry (list of packages, fstab, crontab entries, samba config, DHCP config, ssh authorized keys, customs scripts..), and just run it.

With one command (ansible-playbook ~/your-config.yaml), Ansible will check your playbook (the YAML file) and install/update what’s missing. This is extremely useful when you want to make a change, and a big time saver if you need to reinstall, upgrade, or move SD card.


Here is a piece of the template I use to:

  • Mount an external USB disk into `/ext-disk`
  • Install and configure Samba sharing the disk and the pi home as R/W (also restart samba if the config is updated)
  • Switch off audio and wifi at startup
  • Set static IP and DNS
  • Set SSH authorized keys
  • Shutdown at 2am (Useful to save energy if you have a digital time to switch the power off after 2 am and switch it on back he next day when you normally start using it)
  • Every month launch a script to clean logs, upgrade packages and the raspberry OS
# Run with `ansible-playbook ~/raspberry-config.yaml`
- hosts: raspberry
gather_facts: no
remote_user: root
- name: Install packages
update_cache: yes
autoremove: yes
state: present
- samba
- samba-common-bin
- smbclient
- python-mako
- vim

- name: "reset cron"
shell: "crontab -r || echo already clean"
tags: [ cron ]

- file: { path: /ext-disk, state: directory }
tags: [ disk ]

- name: '/etc/fstab'
path: /etc/fstab
line: 'UUID=240A-1CED /ext-disk vfat auto,nofail,noatime,rw,exec,uid=plex,gid=plex,nouser,async 0 0'
regexp: ^.*\/ext-disk
register: fstab
tags: [ disk, fstab ]

- name: audio off
path: /boot/config.txt
line: 'dtparam=audio=off'
state: present
tags: [ audio ]

- name: static ip
dest: /etc/dhcpcd.conf
owner: root
group: root
mode: 0664
content: |
option rapid_commit
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
option interface_mtu
require dhcp_server_identifier
slaac private
interface wlan0
static ip_address=
static routers=
static domain_name_servers=
tags: [ network ]

- name: samba config
path: /etc/samba/smb.conf
block: |
path = /ext-disk
read only = no
public = no
writable = yes
create mask=0644
directory mark=0755
force user = root
path = /home/pi
read only = no
public = no
writable = yes
create mask=0644
directory mark=0755
force user = root
- restart samba
tags: [ samba ]

- name: "authorise SSH key mac 13 e 15"
dest: /root/.ssh/authorized_keys
content: |
ssh-rsa copy me from your local ~/.ssh/
ssh-rsa copy me from your local ~/.ssh/
ssh-rsa copy me from your local ~/.ssh/
tags: [ ssh ]

- cron:
name: "shutdown wifi at startup time"
special_time: reboot
user: root
job: "ifdown wlan0; ifconfig wlan0 down"
state: present
tags: [ cron ]

- cron:
name: "shutdown at 2am"
minute: "0"
hour: "2"
user: root
job: "/sbin/shutdown -P now"
tags: [ cron ]

- cron:
name: "every month at 1am launch"
minute: "0"
hour: "1"
day: 1
user: root
job: "/bin/sh /usr/local/bin/"
tags: [ cron ]

- name: "maintenance script to delete logs, update dist upgrade"
dest: /usr/local/bin/
content: |
set -x
find /var/log -name '*.gz' | xargs rm -f {}
find /var/log -type f | xargs cat /dev/null > {}
apt update -y
apt autoremove
apt upgrade -y
apt dist-upgrade -y
tags: [ cron ]

- name: restart samba
command: service smbd restart

As you can see, in the second line, I’m telling ansible to look for the raspberry as “raspberry”. To tell ansible where the “raspberry” is, you need to add a line to `/etc/ansible/hosts` with the raspberry IP. In this example I’m using the static IP I’ve set in the config itself.

raspberry_1 ansible_ssh_host=

You can also define this in separate file and point it with from the playbook command `ansible-playbook yourFile.yml -i fileabove.ini`


As written above, the command to run is:

ansible-playbook ~/raspberry-config.yaml 

Ansible has to be installed in your host machine of course, normally a very quick process.

More advanced config: tags

In the example playbook I’m using tags. If you run the playbook with -t tag1,tag2 only the config entries with tag1 and tag2 will be executed

Reference contains everything you need to know about ansible. To find the reference for the single config, it’s probably quicker to google them e.g.“ansible lineinfile” or “ansible file”, or “ansible copy” to quickly jump to the reference pages.


You’ll surely run the same install and config operations more than once, so investing a few minutes in writing a YAMl file and run it with ansible will save your time, and be less stressful when you need to reinstall it. Ansible is also useful to install any other kind of machine, so you can also use it to install packages and set config for your Mac or Linux machine.

Clap if useful. Feel free to comment for clarifications


Software Engineer @ London

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store