A simple Ansible playbook for updating multiple Pihole DNS

I wrote a very simple little playbook for updating my local DNS records for my piholes. For me it’s easier than manually ssh’ing onto each node and editing a file and restarting the service. Here’s the playbook:

update_dns.yml

#!/usr/bin/env ansible-playbook

- hosts: ns-01, ns-02
gather_facts: yes
sudo: yes
tasks:
- name: TASK | Copy dnsmasq config for cbnet
template: src=templates/02-localnet.conf.j2 dest=/etc/dnsmasq.d/02-localnet.conf force=yes
- name: TASK | Copy updated dns file
template: src=templates/localnet.list.j2 dest=/etc/pihole/localnet.list force=yes
- name: TASK | Restart dnsmasq
service:
name: dnsmasq
state: restarted

This playbook adds a DNSmasq config file for my local network and copies a template file (dnsmasq include file for my local network) and restarts DNSmasq. Here is the template (sample):

templates/localnet.list.j2

# Chris Local Network
#
# Gateway
192.168.35.1 pfsense-01
# Static DHCP Reservations
192.168.35.64 gitlab-ce-01
192.168.35.66 dockerhost-01
192.168.35.70 nextcloud-01
192.168.35.74 elk-01
192.168.35.76 checkmk-01
192.168.35.86 homeassistant-01
192.168.35.23 ns-01
192.168.35.10 ns-02
# DHCP Range - 5 - 25
192.168.35.5 cbguest-05
192.168.35.19 cbguest-19
# VPN Reservations
192.168.2.2 vpn-01
192.168.2.3 vpn-02
# Split DNS Entries
192.30.252.153 www.chrisbergeron.com
192.30.252.154 www.chrisbergeron.com
192.30.252.153 chrisbergeron.com
192.30.252.154 chrisbergeron.com


The DNSmasq config file

### templates02-localnet.conf.j2

# Local network dnsmasq config
#
addn-hosts=/etc/pihole/localnet.list
localise-queries
no-resolv


You’ll also need an Ansible hosts file with entries for your piholes. Here’s a sample:
[vms]
checkmk-01 ansible_ssh_host=checkmk-01 ansible_ssh_user=cbergeron ansible_ssh_pass="" host_key_checking=false
db-01 ansible_ssh_host=db-01 ansible_ssh_user=cbergeron ansible_ssh_pass="" host_key_checking=false
dockerhost-01 ansible_ssh_host=dockerhost-01 ansible_ssh_user=cbergeron ansible_ssh_pass="" host_key_checking=false
ns-01 ansible_ssh_host=ns-01 ansible_ssh_user=cbergeron ansible_ssh_pass="" host_key_checking=false
[pis]
ns-02 ansible_ssh_host=ns-02 ansible_ssh_user=cbergeron ansible_ssh_pass="" host_key_checking=false


### Running the playbook
To update my local DNS, I just edit the templates/localnet.conf.j2 Jinja2 YAML file. I then run the playbook like so:

1
ansible-playbook update_dns.yml -e @vault/vault.yml --vault-password-file ~/.somefile.password.txt

I get the following output when it’s complete:


PLAY [ns-01, ns-02]
TASK [Gathering Facts]
ok: [ns-02]
ok: [ns-01]

TASK [TASK | Copy dnsmasq config for cbnet]
ok: [ns-02]
ok: [ns-01]

TASK [TASK | Copy updated dns file]
changed: [ns-02]
changed: [ns-01]

TASK [TASK | Restart dnsmasq]
changed: [ns-02]
changed: [ns-01]

PLAY RECAP
ns-01 : ok=4 changed=2 unreachable=0 failed=0
ns-02 : ok=4 changed=2 unreachable=0 failed=0

real 0m14.294s
user 0m2.977s
sys 0m1.437s

It takes 15 seconds to run this on 1 Pihole as a VM and 1 Pihole on a Raspberry Pi.


Technology Used:
PiHoleAnsibleDNSmasq
Comments