Skip to content

Cron Jobs with Random Start Time per Host#

Problem#

How to create a Cron Job which starts differently per host but remains idempotent?

Solution#

Take the filter random and apply it with seed=inventory_hostname:

- name: Setup a cron job to cleanup docker leftovers
  ansible.builtin.cron:
    name: Docker cleanup
    minute: "{{ 59 | random(seed=inventory_hostname) }}"
    hour: "{{ 23 | random(seed=inventory_hostname) }}"
    user: root
    job: "docker system prune -f --filter 'until=2h' -a >/dev/null 2>&1"
    cron_file: docker_cleanup

Explanation#

We can use the random filter to select a random number from a range. However, we do not want to keep a new number with every Playbook run, but rather the same random number idempotently. To do this, we give random a constant but different String for each Host: inventory_hostname, i.e. the hostname in the inventory, is a suitable candidate.

Info

As our fleet grows, Cron Jobs with a fixed start time can become a problem and put unnecessary pressure on peripheral systems. Hundreds or thousands of log rotations executed at the same time can have a noticeable impact on a centralised storage system. Keep this in mind.