DEV Community

loading...
Cover image for Consequences of updating cron jobs within Ansible's playbook
Bornfight

Consequences of updating cron jobs within Ansible's playbook

wnbsmart profile image Maroje Macola Updated on ・3 min read

Hello fellow dev.to readers!

Should you read this?

Today, I am writing about a smaller issue which occurred to us recently. More precisely, I will show you the pitfall and how we dealt with it.
If you have written a cron job within Ansible's playbook, but have never updated its values afterwards, you are a perfect reader for this post. Other than that, if you are interested in Ansible and want to learn something new, read on!

Cron job example

---
- hosts: all
  tasks:
    - name: Send emails about expiry dates
      cron:
        name: "Send expiry date emails (runs each day, 15 minutes after midnight)"
        minute: "15"
        hour: "0"
        job: "php path/to/console email-expiry-dates/send-email"
Enter fullscreen mode Exit fullscreen mode

So, what do we have here?
It's a simple job which runs every day at 00:15 per server's time and executes a command which sends some emails.

If we would want to get a list of all cron's on the server, we could execute crontab -l on the server, and get something like this:

#Ansible: Send expiry date emails (runs each day, 15 minutes after midnight)
15 0 * * * php path/to/console email-expiry-dates/send-email
Enter fullscreen mode Exit fullscreen mode

Updating cron job

Let's say that server's current time zone is UTC+00:00, and a change request comes up for the existing cron job, something like:

Emails should be delivered right after midnight in New York's time zone

What did we do to implement necessary changes? Updated cron job's execution time, but also its name (or we can say, the description):

---
- hosts: all
  tasks:
    - name: Send emails about expiry dates
      cron:
        name: "Send expiry date emails (runs each day, 15 minutes after midnight in New York's time zone)"
        minute: "15"
        hour: "5"
        job: "php path/to/console email-expiry-dates/send-email"
Enter fullscreen mode Exit fullscreen mode

After deploying and listing server's cron jobs, we expected to have a single job as before, but with updated values, respectively. This was the actual result:

#Ansible: Send expiry date emails (runs each day, 15 minutes after midnight)
15 0 * * * php path/to/console email-expiry-dates/send-email

#Ansible: Send expiry date emails (runs each day, 15 minutes after midnight in New York's time zone)"
15 5 * * * php path/to/console email-expiry-dates/send-email
Enter fullscreen mode Exit fullscreen mode

What happened after update?

The result was 2 cron jobs. The old one stayed as is and the new one, with different parameters, was added to the list. Therefore, the same command was being executed 2 times a day, which definitely was not part of the acceptance criteria.

Since the name was changed, Ansible recognised this as a new cron job. This resulted in an unsynchronised state between server's and playbook's cron jobs.

Fixing the unexpected problem

---
- hosts: all
  tasks:
    - name: Old (Send emails about expiry dates)
      cron:
        name: "Send expiry date emails (runs each day, 15 minutes after midnight)"
        minute: "15"
        hour: "0"
        job: "php path/to/console email-expiry-dates/send-email"
        state: absent
    - name: Send emails about expiry dates
      cron:
        name: "Send expiry date emails (runs each day, 15 minutes after midnight in New York's time zone)"
        minute: "15"
        hour: "5"
        job: "php path/to/console email-expiry-dates/send-email"
Enter fullscreen mode Exit fullscreen mode

As visible above, we tried to be in sync with the server, by adding another cron job (with old values). Besides that, we added an additional parameter to the old cron job - state: absent, which disabled its execution by removing it from the list of cron jobs on the server.

After deploying this fix to the server, this was a final result after listing cron jobs:

#Ansible: Send expiry date emails (runs each day, 15 minutes after midnight in New York's time zone)"
15 5 * * * php path/to/console email-expiry-dates/send-email
Enter fullscreen mode Exit fullscreen mode

Yaay! A single cron job with all parameters set correctly 🎉

Conclusion

Changing a cron job's name will not result in an update of the existing cron job. Its name is some sort of an ID, and therefore should not be changed (in most cases). But, what we can do, is play around with tasks' name property, since it will not lead to the problem we occurred :)

Do you have any tips regarding this topic? I would be glad to hear them!

Discussion (2)

pic
Editor guide
Collapse
renatoruk profile image
Renato Ruk

Thanks for sharing! As I am currently learning to use Ansible, this will surely come in handy.
The fix is also pretty elegant 👍🏻

Collapse
wnbsmart profile image
Maroje Macola Author

Glad to be of help!
Good luck in your "Ansible adventures" 💪🏻