Using systemd as cron

Tradionally, *nix users are familiar (or maybe not so much) with cron syntax, whereas you define applications to be run at specific schedules.

What most people don’t know is that you can also use the power of Systemd to do the same, and in return get all the benefits by doing so, such as centralized logging through journald.

In order to use it you will need at least two files, one for a “service” unit, and another called timer unit.

Here are the files and the contents of a minimal setup:

/etc/systemd/system/myprogram.service

[Unit]
Description=Runs my program which does something

[Service]
Type=oneshot
User=git
Group=git
ExecStart=/usr/local/bin/my-program

/etc/systemd/system/myprogram.timer

[Unit]
Description=Automatically runs myprogram every 15 minutes

[Timer]
OnCalendar=*:0/15

[Install]
WantedBy=timers.target

After you place both files at the specific location, you will need to reload systemd, then enable and start the timer.

  1. Reload systemd
    systemctl daemon-reload
    
  2. Now enable and start the timer
    systemctl enable --now myprogram.timer
    

Get familiar with the OnCalendar syntax on the systemd.timer(5) manpage. Also check out the incredible Arch Guide on the same subject.

Automating it

For the best experience you should automate this. Here is the Ansible snippet to do so. Remember to put both .service and .timer files under the files folder in the same level as this playbook below.

- hosts: all
  tasks:
    - name: create git-sync crontab entry
      become: true
      notify: 
        - reload systemd daemon
        - enable myprogram timer
      ansible.builtin.copy:
        src: "\{\{ item \}\}"
        dest: /etc/systemd/system/\{\{ item \}\}
      loop:
        - myprogram.service
        - myprogram.timer

  handlers:
    - name: reload systemd daemon
      become: true
      ansible.builtin.systemd: daemon_reload=yes

    - name: enable myprogram timer
      become: true
      ansible.builtin.systemd: name=myprogram.timer enabled=yes state=restarted