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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Chris Local Network
# {{ ansible_managed }}
# 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

templates/02-localnet.conf.j2

1
2
3
4
5
6
# Local network dnsmasq config
# {{ ansible_managed }}
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:

1
2
3
4
5
6
7
8
[vms]
checkmk-01 ansible_ssh_host=checkmk-01 ansible_ssh_user=cbergeron ansible_ssh_pass="{{ USER_PW }}" host_key_checking=false
db-01 ansible_ssh_host=db-01 ansible_ssh_user=cbergeron ansible_ssh_pass="{{ USER_PW }}" host_key_checking=false
dockerhost-01 ansible_ssh_host=dockerhost-01 ansible_ssh_user=cbergeron ansible_ssh_pass="{{ USER_PW }}" host_key_checking=false
ns-01 ansible_ssh_host=ns-01 ansible_ssh_user=cbergeron ansible_ssh_pass="{{ USER_PW }}" host_key_checking=false
[pis]
ns-02 ansible_ssh_host=ns-02 ansible_ssh_user=cbergeron ansible_ssh_pass="{{ USER_PW }}" 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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:
PiHoleAnsible
Comments