Inadyn With Ansible

Updated

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