Systemd timers instead of cron

  • As I'm sure most of you know, systemd has other units than just services. I'll be dealing with services, timers, and targets in this write up.

    The main reason for me switching was ansible-pull. Now it's mostly my fault because I didn't create a script with any logic and just assumed that ansible-pull was smart enough to do this (it's not the main function of Ansible so it's not surprising it doesn't). I was using Ansible pull for basic bare configs after kickstarting and then having it run every 10 minutes to check for changes. I set up a cronjob that called ansible-pull to checkout the repo and pull in any changes and run the playbook locally. Well what I didn't realize is that if there is any hangup in that process, ansible-pull isn't killed automatically and then when 10 minutes is up, it will start another ansible-pull process. So after 24 hours of that, some machines had a load of 8+. They were hanging during setup because they were having issues contacting a non-important NFS share that was automounted.

    Systemd timers will not run another instance until the first is completed, so that fixes this. It also lets you run a service one off unlike cron.

    First create your files in /usr/lib/systemd/system:

    touch myscript.{target,timer,service}
    touch myscript2.service

    You don't need a target, but if you want to have more than one script run, it makes it easier.

    Here's some examples with a snapshot backup I use for some of my VMs at home:


    Description=Backup PBX
    ExecStart=/usr/local/bin/snapshot PBX pbx-snap /var/backups/VMs/ hda


    Description=Backup Tower Data
    ExecStart=/usr/local/bin/snapshot Tower tower-snap /var/backups/VMs/ vdb

    Description=Snapshot based backup for VMs


    Description=Backup VMs
    OnCalendar=Sun *-*-* 00:00:00

    Now just enable each one

    systemctl enable backup-tower backup-pbx backup.timer

    And start the timer:

    systemctl start backup.timer

    Mine is set to run every week on Sunday at midnight.

    This allows us to one off run the services also without going into either crontab or a cron file and grabbing the whole command.

    systemctl start backup-tower

    These are also all logged with journalctl. So if you want to see all of the entries for backup-tower just run

    journalctl -u backup-tower
    Apr 23 13:58:29 systemd[1]: Starting Backup Tower data...
    Apr 23 13:58:29 snapshot[18508]: Domain snapshot tower-snap created
    Apr 23 13:58:29 snapshot[18508]: tar: Removing leading `/' from member names
    Apr 23 13:58:29 snapshot[18508]: /data/VMs/tower-var.qcow2
    Apr 23 14:02:38 snapshot[18508]: [43B blob data]
    Apr 23 14:02:38 snapshot[18508]: Successfully pivoted
    Apr 23 14:02:38 snapshot[18508]: Domain snapshot tower-snap deleted