Inadyn With Ansible
Introduction
I've been learning Ansible for the last few months, which has been a lot of fun! It's not really hard, but due to family commitments progress has been slow and irregular.
This is from one of my playbooks, and I've setup inadyn to automagically update a DNS post if my public IP at home ever changes. I'm using the HE.net DNS service for this example.
All of this is from my mono-repo called vyos-home-network
, which is where everything started. It's roles are organized into folders per hostname, which is not optimal but works great for me this far. A better alternative might be to organize for functionality (router, DHCP, fileserver…) or in separate repositories.
Tasks, templates and secrets
Under my roles
folder I have created a folder named tinkerboard
as that's the hostname of the machine running this. I have a few roles for this machine, one for my local DNS zone, one for Telegraf (used to collect various metrics) and so forth.
The machine running this is a SBC (as the hostname might have given away), running Armbian. The inadyn
version is 1.99.4.
Tasks
I started using a separate template for the configuration file, but that could be done inline in the tasks file instead, but leaving that as an exercise for the (potential) reader. :)
# ./roles/tinkerboard/inadyn/tasks/main.yml
---
- name: Install inadyn if not present
package:
name: "inadyn"
state: present
tags: inadyn
- name: Install configuration file
template:
dest: /etc/inadyn.conf
src: inadyn.conf.j2
register: inadyn_config
tags: inadyn
- name: Change /etc/defaults/inadyn
lineinfile:
path: /etc/default/inadyn
regexp: "^RUN_DAEMON="
line: RUN_DAEMON="yes"
state: present
register: inadyn_config
tags: inadyn
- name: Enable inadyn service
systemd:
name: "inadyn.service"
enabled: yes
masked: no
tags: inadyn
- name: Restart inadyn service when needed
systemd:
name: "inadyn.service"
state: restarted
when: inadyn_config.changed
tags: inadyn
# Used to throw an error. Seems to work now?
# https://github.com/ansible/ansible/issues/71528
- name: Start inadyn if not running
service:
name: "inadyn.service"
state: started
tags: inadyn
Template
Not much here. You might understand why this probably should/could be inline in the tasks file.
# ./roles/tinkerboard/inadyn/templates/inadyn.conf.j2
# {{ ansible_managed }}
username {{ dyndns_username }}
alias {{ dyndns_username }}
password {{ dyndns_password }}
period {{ dyndns_update_period }}
system dyndns@he.net
forced-update {{ dyndns_forced_update_period }}
drop-privs debian-inadyn:debian-inadyn
Secrets
I keep my secrets in an Ansible vault.
# ./host_vars/tinkerboard/vault
dyndns_username: "hello"
dyndns_password: "world"
# 5 minutes
dyndns_update_period: 300
# 2 weeks
dyndns_forced_update_period: 1209600
Playbook
I only have two roles for this playbook, and the other, secret playbook is just two more lines of yaml.
# ./tinkerboard.yml
---
- name: "Setup tinkerboard"
hosts: tinkerboard
tasks:
- import_role:
name: tinkerboard/inadyn
Inventory
This file is pretty stupid - I'm defining a group called tinkerboard
with one member, called tinkerboard
. It's throwing warnings when I run it. I'm just pointing to the correct IP address, instead of using a FQDN in my local DNS zone. This is due to reasons.
# ./inventory
[tinkerboard]
tinkerboard ansible_host=192.168.0.x
Applying it
ansible-playbook tinkerboard.yml --tags=inadyn
Verifying it
Aside from the Ansible output when running the previous command, here's how to verify that it worked:
journalctl -u inadyn.service
Conclusion
This playbook is trivial and probably not very portable - but I would have like to see more examples like this when learning Ansible myself. So I wrote it. :)