- Random Access Musings
- Posts
- Unwrapping the Power of Ansible: A Practical Journey with Pi-hole (Part 4)
Unwrapping the Power of Ansible: A Practical Journey with Pi-hole (Part 4)
Translating Ansible theory into action through a guided playbook creation

Image by fabrikasimf on Freepik
Introduction to Configuration Management (Part 1)
Configuration Management Tools Unveiled (Part 2)
Demystifying Ansible: A Michelin Star Chef in Your IT Kitchen (Part 3)
Hello Muser!
In our last conversation, we demystified Ansible, the versatile IT configuration management tool. We dissected its core components, showing how they all come together to create an elegant, robust, and efficient IT automation framework.
This time, let's make things more tangible. Today, we are rolling up our sleeves and bringing Ansible theory to life with a real-world playbook, guiding you step-by-step through the process.
We'll create a comprehensive playbook that automates the installation and configuration of Pi-hole — a network-wide ad blocker that doubles as a DNS server. I've chosen Pi-hole because it's a powerful, yet light application that runs perfectly on small servers and even Raspberry Pis. It's a great example that demonstrates Ansible's power in a digestible package.
Let's dive right in!
Our playbook will incorporate all key Ansible components we've previously discussed. Don't worry, we'll also break down how each part correlates to our Ansible concepts. Along the way, we'll commit our progress to a GitHub repository, allowing you to keep track of each step.

Make a Github Repository
First, let's set up our GitHub repository.
1. Log in to GitHub and create a new repository. For this demo, we'll name our repository "ansible-pihole".
2. Clone the repository to your local workstation. Replace [your-username]
with your GitHub username:
git clone https://github.com/[your-username]/ansible-pihole.git
cd ansible-pihole
If this is feeling foreign to you, feel free to reference my series of posts on Git with the first part here!

Setting up the Inventory
We'll begin by setting up our inventory. The inventory is a list of the nodes or "hosts" that Ansible will manage. For this demo, we'll manage one host.
Create a new file named hosts
in the ansible-pihole
directory:
nano hosts
Add your server's IP address to the file:
[pihole] # This is how you'll reference your hosts
192.168.1.10
This places our host in a group named "pihole". Save and close the file, then commit the file to Git:
git add hosts
git commit -m "Add Ansible inventory file"

Update and Upgrade System Packages
For the "system" role, we'll update and upgrade all packages on the system. Create the respective directories and file:
mkdir -p roles/system/tasks
nano roles/system/tasks/main.yaml
Add the following tasks:
---
- name: Update all packages
apt: # The apt module handles apt command line actions
update_cache: yes
- name: Upgrade all packages
apt:
upgrade: 'yes'

Install Dependencies
Pi-hole has some dependencies that need to be installed. For the "dependencies" role, create the respective directories and file:
mkdir -p roles/dependencies/tasks
nano roles/dependencies/tasks/main.yaml
Add the following tasks:
---
- name: Install dependencies
apt:
name:
- curl
- dnsutils
- netcat
state: present

Install Pi-hole
Finally, for the "pihole" role, we'll install Pi-hole itself. Create the respective directories and file:
mkdir -p roles/pihole/tasks
nano roles/pihole/tasks/main.yaml
Add the following tasks to the file:
---
- name: Check if Pi-hole is already installed
stat:
path: /etc/.pihole
register: pihole_directory
- name: Create /etc/pihole directory
file:
path: /etc/pihole
state: directory
mode: '0755'
when: pihole_directory.stat.exists == false
- name: Create setupVars.conf file for Pi-hole configuration
become: true
copy:
dest: /etc/pihole/setupVars.conf
content: |
PIHOLE_INTERFACE=eth1
PIHOLE_DNS_1=8.8.8.8
PIHOLE_DNS_2=8.8.4.4
QUERY_LOGGING=true
INSTALL_WEB_SERVER=true
INSTALL_WEB_INTERFACE=true
LIGHTTPD_ENABLED=true
CACHE_SIZE=10000
DNS_FQDN_REQUIRED=true
DNS_BOGUS_PRIV=true
DNSMASQ_LISTENING=local
BLOCKING_ENABLED=true
when: pihole_directory.stat.exists == false
- name: Install Pi-hole
become: true
shell: curl -sSL https://install.pi-hole.net | bash /dev/stdin --unattended
when: pihole_directory.stat.exists == false
- name: Remove Web Admin Password
become: true
shell: echo "" | pihole -a -p
This uses
the
stat
module to check if Pi-hole is already installedthe
file
module to create the/etc/pihole
directorythe
copy
module to set the contents of the/etc/pihole/setupVars.conf
fileand the
shell
module to run the Pi-hole installation script & remove the web password if Pi-hole isn’t installed.
The register
keyword stores the result of the stat
command in a variable named pihole_directory
, which we then use in the when
condition. The become
directives force the use of sudo
for all the commands.
We now have three roles that we can include in our playbook.

Adding Roles to the Playbook
Edit the pihole.yaml
file:
nano pihole.yaml
And add the roles to the playbook:
---
- name: Install Pi-hole
hosts: pihole # See the [pihole] section in hosts file
become: yes
roles:
- system
- dependencies
- pihole
Save and close the file.
Then commit the changes to Git:
git add pihole.yaml roles/
git commit -m "Add roles to Ansible playbook"

This playbook demonstrates Ansible's key concepts:
Inventory: We defined a single host that Ansible will manage.
Roles: We divided our playbook into three roles to modularize the Pi-hole installation process.
Tasks: Each role performs a task using Ansible's modules.
Playbooks: We defined a playbook to orchestrate the entire operation and use our roles.
Modules: We used the
apt
,stat
, andcommand
modules to manage packages, check the state of files, and run shell commands on the server.
Additionally, we committed our playbook to a Git repository on GitHub at each step of the process. This allows us to track changes to the playbook and collaborate with others.
In the next post, we'll look at how to run this playbook and what to expect!
Stay tuned, and happy cooking with Ansible!
Enjoyed this post? Don't miss our next one where we'll explore different tools available for configuration management. Subscribe now and share with your colleagues who might find this useful!
Have any questions or experiences to share about Ansible Playbooks? Leave a comment below. Also, your comments help me understand what you're curious about, and what topics you'd like to see covered next! I'd love to hear from you!
Keep learning and keep growing,
Reply