If you are not familiar with modules, check out Ansible - Getting Started with Modules.
The cron module is used to manage a users cron table. This is based off of the Linux crontab command. On some systems (such as Fedora), cron is not included with the install of the operating system. In this scenario, the dnf module can be used to install cronie, and the systemd module can be used to start and enable crond.
At the bare minimum, the following is all that is needed to create or update a job in a users cron table. If the job does not exist, it will be created. If the job does exist, it will be updated (if there are any changes to the job).
- In this example, since the "name" key was not included #Ansible: None is appended before the job.
- In this example, since the "user" key was not included, this will update the cron table for whatever user Ansible is making the SSH connection to the target server as. For example, if --user or remote_user is john.doe, this will update john.doe cron table.
- In this example, since the following keys were not included, the job defaults to * * * * * meaning that the job will run once every minute.
- hour
- minute
- day
- month
- weekday
- special_time
---
- hosts: all
tasks:
- ansible.builtin.cron:
job: /etc/cron.d/example.sh
...
In this example, the users cron table should have the following.
#Ansible: None
* * * * * /etc/cron.d/example.sh
The name parameter is how Ansible keeps track of the job
In the above example, since the name parameter was not used, the name defaults to be Ansible: None. Each time the Ansible playbook is run, the playbook locates the job in the users cron table that has comment Ansible: None and updates the cron job if any changes were made in the cron task in the Ansible playbook.
For this reason, you will almost always want to include a unique name. A good strategy is to have the name be the same as the job, since each job in your users cron table is probably unique.
---
- hosts: all
tasks:
- ansible.builtin.cron:
name: /etc/cron.d/example.sh
job: /etc/cron.d/example.sh
...
This will produce the following entry in the users cron table, where the comment is the name of the script being run (in this example). This allows you to update the other parameters of the cron job in the Ansible playbook, and as long as the name does not change, then Ansible will update the job matching the value of the name parameter.
#Ansible: /etc/cron.d/example.sh
* * * * * /etc/cron.d/example.sh
When the state parameter is not used, or when the state parameter is set to state: present, if the user's cron table does not contain the job, the job will be created. On the other hand, if the user's cron table contains the job, the job will be updated, if any changes are made to the job.
---
- hosts: all
tasks:
- name: ensure cron contains the following: 00 01 * * * /etc/cron.d/example.sh
ansible.builtin.cron:
name: Invoke example.sh at 1:00 am
user: root
job: /etc/cron.d/example.sh
hour: '01'
minute: '00'
state: present
...
In this example, the user's cron table would have the following.
#Ansible: Invoke example.sh at 1:00 am
00 01 * * * /etc/cron.d/example.sh
The cron_file option can be used to create a shared cron table entry.
---
- hosts: all
tasks:
- name: ensure /etc/cron.d/foo contains the following: 00 01 * * * /etc/cron.d/example.sh
ansible.builtin.cron:
name: Invoke example.sh at 1:00 am
user: john.doe
cron_file: /etc/cron.d/foo
job: /etc/cron.d/example.sh
hour: '01'
minute: '00'
state: present
...
Notice in this example that john.doe is the user that invokes example.sh in the shared /etc/cron.d/foo file.
#Ansible: Invoke example.sh at 1:00 am
00 01 * * * john.doe /etc/cron.d/example.sh
Hourly, Daily, Weekly, Monthly, Annualy, Reboot
The special_time option can be used to run a command or script once every hour, once every day, once every week, once every month, or when the server is restarted. The valid values for special_time are:
- hourly
- daily
- weekly
- monthly
- annualy
- reboot
---
- hosts: all
tasks:
- name: example.sh after reboot
ansible.builtin.cron:
name: Invoke example.sh after reboot
special_time: reboot
job: /etc/cron.d/example.sh
...
The cron table should have something like this.
@reboot /etc/cron.d/example.sh
Variables can be defined in the cron table. In this example, the FOO variable contains a value of bar. In this example, bar would be appended to out.txt once every minute.
---
- hosts: all
tasks:
- name: Create the "FOO=bar" variable
ansible.builtin.cron:
env: yes
name: FOO
job: bar
- name: append bar to out.txt once every minute
ansible.builtin.cron:
name: append bar to out.txt once every minute
user: root
job: echo $FOO >> out.txt
state: present
...
The cron table should then have the following.
FOO="bar"
#Ansible: append bar to out.txt once every minute
* * * * * echo $FOO >> out.txt
disabled: true can be used to comment out the crontab job. Then, disabled: false can be used to uncomment the crontab job.
---
- hosts: all
tasks:
- name: ensure cron does not contains the following: 00 01 * * * /etc/cron.d/example.sh
ansible.builtin.cron:
name: Invoke example.sh at 1:00 am
user: root
job: /etc/cron.d/example.sh
hour: '01'
minute: '00'
state: absent
disabled: true
...
In this example, the user's cron table would have the following.
#Ansible: Invoke example.sh at 1:00 am
#00 01 * * * root /etc/cron.d/example.sh
When state: absent is used and the disabled parameter is not used, if the user's cron table contains the job, the job will be removed from the user's cron table.
---
- hosts: all
tasks:
- name: "ensure cron does not contains the following: 00 01 * * * /etc/cron.d/example.com"
ansible.builtin.cron:
name: Invoke example.sh at 1:00 am
user: root
job: /etc/cron.d/example.sh
hour: '01'
minute: '00'
state: absent
...
By default, cron will send an email each time cron is invoked. cronvar can be used to define the target email.
---
- hosts: all
tasks:
- name: send email to john.doe@example.com when cron is invoked
community.general.cronvar:
name: MAILTO
value: john.doe@example.com
user: john.doe
...
Or value can be empty to not send an email when cron is invoked.
---
- hosts: all
tasks:
- name: do not send email when cron is invoked
community.general.cronvar:
name: MAILTO
value:
user: john.doe
...
Did you find this article helpful?
If so, consider buying me a coffee over at 