Inadyn With Ansible

Posted on Apr 10, 2021


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 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.


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
      name: "inadyn"
      state: present
    tags: inadyn

  - name: Install configuration file
      dest: /etc/inadyn.conf
      src: inadyn.conf.j2
    register: inadyn_config
    tags: inadyn

  - name: Change /etc/defaults/inadyn
      path: /etc/default/inadyn
      regexp: "^RUN_DAEMON="
      line: RUN_DAEMON="yes"
      state: present
    register: inadyn_config
    tags: inadyn

  - name: Enable inadyn service
      name: "inadyn.service"
      enabled: yes
      masked: no
    tags: inadyn

  - name: Restart inadyn service when needed
      name: "inadyn.service"
      state: restarted
    when: inadyn_config.changed
    tags: inadyn

  # Used to throw an error. Seems to work now?
  - name: Start inadyn if not running
      name: "inadyn.service"
      state: started
    tags: inadyn


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 }}
  forced-update {{ dyndns_forced_update_period }}
  drop-privs debian-inadyn:debian-inadyn


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


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
    - import_role:
        name: tinkerboard/inadyn


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 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


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. :)