Getting started

OpenNTPD, ifupdown and systemd integration

The openntpd Debian package provides an ifupdown hook, /etc/network/if-up.d/openntpd. It's used to restart the NTP daemon on any network interface changes so that it can re-bind itself properly.

Unfortunately, the hook is not systemd-aware and this causes several problems:

  • During boot, when ifupdown configures each interface, systemd is forced to restart the openntpd service early each time. This might cause dependency problems and leave the NTP daemon service in a failed state.

  • During ifupdown interface reconfiguration, especially when multiple interfaces are created or destroyed, the openntpd service is restarted multiple times in rapid succession. This might result in the systemd not starting the service when it hits the rate limits and leaving it in a failed state.

To fix these issues, debops.ntp role will divert the original openntpd hook and create its own, which is systemd-aware. The hook will only restart the openntpd service if it's already running, and will queue the restart command in the background which should ensure that during interface configuration NTP daemon is restarted only once, or just a few times and won't hit rate limits. On boot, the NTP daemon will be started after network configuration has been completed.

Example inventory

To configure the NTP service using the debops.ntp role, a host needs to be included in the [debops_service_ntp] Ansible inventory group. An example inventory can look like this:

[debops_all_hosts]
hostname

[debops_service_ntp]
hostname

Example playbook

Here's an example playbook for using the role without the DebOps playbook:

---

- name: Manage Network Time Protocol service
  collections: [ 'debops.debops', 'debops.roles01',
                 'debops.roles02', 'debops.roles03' ]
  hosts: [ 'debops_service_ntp' ]
  become: True

  environment: '{{ inventory__environment | d({})
                   | combine(inventory__group_environment | d({}))
                   | combine(inventory__host_environment  | d({})) }}'

  roles:

    - role: ferm
      tags: [ 'role::ferm', 'skip::ferm' ]
      ferm__dependent_rules:
        - '{{ ntp__ferm__dependent_rules }}'

    - role: ntp
      tags: [ 'role::ntp', 'skip::ntp' ]