Automating cron jobs with the ansible cron module


Over the past month I have been rewriting some cron scripts to enhance monitoring and observability. I’ve also been refactoring my ansible playbooks to handle deploying these scripts in a consistent fashion. Ansible ships with the cron module which makes this process a breeze. The cron module has all of the familiar cron attributes (hour, minute, second, program to run, etc.) and takes the following form:

- name: Cron job to prune old elasticsearch indexes
  cron:
    name: cleanup-elasticsearch-indexes
    minute: 0
    hour: 0
    job: /scripts/curator/curator_clean_logs.sh
    state: present
    user: curator

When I first played around with this module I noticed that each playbook run would result in a cron entry being added. So instead of getting one curator log cleanup job when the play is executed I would get a one entry per run. This is obviously very bad. When I read back through the cron module documentation I came across this little nugget for the “name” parameter:

Note that if name is not set and state=present, then a new crontab entry will always be created, regardless of existing ones.

Ansible uses the name to tag the entry and if the tag already exists a new cron job won’t be added to the system (in case your interested this is implemented by the find_job() method in cron.py). Small subtleties like this really bring to light the importance of a robust test environment. I am currently using vagrant to solve this problem but there are also a number of solutions documented in the Ansible testing strategies guide.

This article was posted by Matty on 2017-08-17 14:58:00 -0400 -0400