AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible Cron Module: Schedule Jobs & Tasks on Linux (Complete Guide)

By Luca Berton · Published 2024-01-01 · Category: troubleshooting

How to schedule cron jobs with Ansible cron module (ansible.builtin.cron). Create, modify, remove crontab entries. Set minute, hour, day, month, weekday.

Ansible Cron Module: Schedule Jobs & Tasks on Linux (Complete Guide)

I'm going to show you a live Playbook and some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot.

Ansible schedule a Cron Job task in Linux

• ansible.builtin.cron • Manage cron.d and crontab entries

Today we're talking about Ansible module cron. The full name is ansible.builtin.cron, which means that is part of the collection of modules "builtin" with ansible and shipped with it. It's a module pretty stable and out for years and it works in a different variety of operating systems. It manages cron.d and crontab entries. For Windows targets, use the ansible.windows.win_scheduled_task module instead.

See also: Ansible localhost & delegate_to: Run Tasks on Control Node Guide

Parameters

• name string - crontab name • state string - present/absent • job string - command to execute • user string - defaults to the current user • minute, hour, day, month, weekday string - '\', '1–31', '\/2' • special_time - annually/daily/hourly/monthly/reboot/weekly/yearly • cron_file - NEVER use for /etc/crontab

This module has some parameters to perform any tasks. The only required is "name", where you specify the description of a crontab entry. The parameter "state" sets whether the cron job is present or not in the target host. The parameter "job" sets the command to execute or, if env is set, the value of the environment variable. The parameter "user" sets the specific user for the crontab, when unset, this parameter defaults to the current user. The most important part is the moment to run the crontab, specifically: "minute", "hour", "day", "month", "weekday". In this field, you could use the star operator "\*" to specify all the minutes, hours, weekdays, days, and months. You could be more specific with a single number, range, or intervals. There are also some special times already defined in the parameter "special_time". The options are: annually, daily, hourly, monthly, reboot, weekly, yearly. Let me also highlight that we could also specify the "cron_file" if you want a specific name and not under the user.

Links

• https://docs.ansible.com/ansible/latest/collections/ansible/builtin/cron_module.html • https://crontab.guru/

## Playbook

Ansible schedule a Cron Job task in Linux.

code

• cron.yml
---
- name: cron module Playbook
  hosts: all
  tasks:
   - name: "example cronjob"
     ansible.builtin.cron:
      name: "test"
      state: present
      minute: "*/2"
      hour: "*"
      day: "*"
      month: "*"
      weekday: "*"
      job: 'logger "ansible-pilot"'

execution

$ ansible-playbook -i virtualmachines/demo/inventory schedule\ cron\ job\ task/cron.yml
PLAY [cron module Playbook] ***************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [example cronjob] ****************************************************************************
changed: [demo.example.com]
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

before execution

$ ssh devops@demo.example.com
Last login: Wed Dec  8 15:28:44 2021 from 192.168.0.101
[devops@demo ~]$ crontab -l
no crontab for devops
[devops@demo ~]$

after execution

$ ssh devops@demo.example.com
Last login: Wed Dec  8 15:30:58 2021 from 192.168.0.101
[devops@demo ~]$ crontab -l
#Ansible: test
*/2 * * * * logger "ansible-pilot"
[devops@demo ~]$ sudo tail -f /var/log/cron
Dec  8 15:26:47 rhel8 crond[905]: (CRON) INFO (Syslog will be used instead of sendmail.)
Dec  8 15:26:47 rhel8 crond[905]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 43% if used.)
Dec  8 15:26:47 rhel8 crond[905]: (CRON) INFO (running with inotify support)
Dec  8 15:26:47 rhel8 CROND[916]: (root) CMD (bash -c '/bin/updatedb ; rm --force /etc/cron.d/updatedb')
Dec  8 15:28:52 rhel8 crontab[5139]: (devops) LIST (devops)
Dec  8 15:30:10 rhel8 crontab[5191]: (devops) LIST (devops)
Dec  8 15:30:45 rhel8 crontab[5453]: (devops) LIST (devops)
Dec  8 15:30:45 rhel8 crontab[5455]: (devops) REPLACE (devops)
Dec  8 15:30:58 rhel8 crontab[5706]: (devops) LIST (devops)
Dec  8 15:31:18 rhel8 crontab[5749]: (devops) LIST (devops)
Dec  8 15:32:01 rhel8 CROND[5760]: (devops) CMD (logger "ansible-pilot")
Dec  8 15:34:01 rhel8 CROND[5766]: (devops) CMD (logger "ansible-pilot")
Dec  8 15:36:01 rhel8 CROND[5770]: (devops) CMD (logger "ansible-pilot")
Dec  8 15:38:01 rhel8 CROND[5775]: (devops) CMD (logger "ansible-pilot")
Dec  8 15:40:01 rhel8 CROND[5781]: (devops) CMD (logger "ansible-pilot")
Dec  8 15:42:01 rhel8 CROND[5787]: (devops) CMD (logger "ansible-pilot")
Dec  8 15:44:01 rhel8 CROND[5791]: (devops) CMD (logger "ansible-pilot")
Dec  8 15:46:01 rhel8 CROND[5796]: (devops) CMD (logger "ansible-pilot")
^C
[devops@demo ~]$ sudo tail -f /var/log/messages 
Dec  8 15:41:43 rhel8 systemd[1]: Started Cleanup of Temporary Directories.
Dec  8 15:42:01 rhel8 systemd[1]: Started Session 18 of user devops.
Dec  8 15:42:01 rhel8 devops[5787]: ansible-pilot
Dec  8 15:42:01 rhel8 systemd[1]: session-18.scope: Succeeded.
Dec  8 15:44:01 rhel8 systemd[1]: Started Session 19 of user devops.
Dec  8 15:44:01 rhel8 devops[5791]: ansible-pilot
Dec  8 15:44:01 rhel8 systemd[1]: session-19.scope: Succeeded.
Dec  8 15:46:01 rhel8 systemd[1]: Started Session 20 of user devops.
Dec  8 15:46:01 rhel8 devops[5796]: ansible-pilot
Dec  8 15:46:01 rhel8 systemd[1]: session-20.scope: Succeeded.
Dec  8 15:48:01 rhel8 systemd[1]: Started Session 21 of user devops.
Dec  8 15:48:01 rhel8 devops[5807]: ansible-pilot
Dec  8 15:48:01 rhel8 systemd[1]: session-21.scope: Succeeded.
Dec  8 15:50:01 rhel8 systemd[1]: Starting system activity accounting tool...
Dec  8 15:50:01 rhel8 systemd[1]: sysstat-collect.service: Succeeded.
Dec  8 15:50:01 rhel8 systemd[1]: Started system activity accounting tool.
Dec  8 15:50:01 rhel8 systemd[1]: Started Session 22 of user devops.
Dec  8 15:50:01 rhel8 devops[5814]: ansible-pilot
Dec  8 15:50:01 rhel8 systemd[1]: session-22.scope: Succeeded.
Dec  8 15:52:01 rhel8 systemd[1]: Started Session 23 of user devops.
Dec  8 15:52:01 rhel8 devops[5818]: ansible-pilot
Dec  8 15:52:01 rhel8 systemd[1]: session-23.scope: Succeeded.
Dec  8 15:54:01 rhel8 systemd[1]: Started Session 24 of user devops.
Dec  8 15:54:01 rhel8 devops[5823]: ansible-pilot
Dec  8 15:54:01 rhel8 systemd[1]: session-24.scope: Succeeded.
Dec  8 15:56:01 rhel8 systemd[1]: Started Session 25 of user devops.
Dec  8 15:56:01 rhel8 devops[5827]: ansible-pilot
Dec  8 15:56:01 rhel8 systemd[1]: session-25.scope: Succeeded.

code with ❤️ in GitHub

See also: Ansible Set File Permissions 755: chmod with file Module Guide

Conclusion

Now you know how to schedule a Cron Job task in Linux with Ansible.

Create a Cron Job

- ansible.builtin.cron:
    name: "Backup database"
    minute: "0"
    hour: "2"
    job: "/opt/scripts/backup-db.sh >> /var/log/backup.log 2>&1"
  become: true

See also: Add Windows Registry on Windows-like systems - Ansible module win_regedit

Special Time Strings

# Every reboot
- cron:
    name: "Start app on boot"
    special_time: reboot
    job: "/opt/myapp/start.sh"

# Daily (midnight) - cron: name: "Daily cleanup" special_time: daily job: "/opt/scripts/cleanup.sh"

# Hourly - cron: name: "Health check" special_time: hourly job: "/opt/scripts/healthcheck.sh"

# Weekly (Sunday midnight) - cron: name: "Weekly report" special_time: weekly job: "/opt/scripts/report.sh"

Common Schedules

# Every 5 minutes
- cron:
    name: "Check queue"
    minute: "*/5"
    job: "/opt/scripts/check-queue.sh"

# Every weekday at 9 AM - cron: name: "Morning report" minute: "0" hour: "9" weekday: "1-5" job: "/opt/scripts/morning-report.sh"

# First day of each month - cron: name: "Monthly billing" minute: "0" hour: "6" day: "1" job: "/opt/scripts/billing.sh"

# Every 15 minutes during business hours - cron: name: "Business hours sync" minute: "*/15" hour: "8-18" weekday: "1-5" job: "/opt/scripts/sync.sh"

Remove a Cron Job

- cron:
    name: "Old backup job"
    state: absent

Cron for Specific User

- cron:
    name: "User backup"
    user: deploy
    minute: "30"
    hour: "3"
    job: "/home/deploy/backup.sh"
  become: true

Cron Environment Variables

- cron:
    name: PATH
    env: true
    job: "/usr/local/bin:/usr/bin:/bin"

- cron: name: MAILTO env: true job: "admin@example.com"

Disable (Comment Out) a Job

- cron:
    name: "Maintenance task"
    minute: "0"
    hour: "3"
    job: "/opt/scripts/maintenance.sh"
    disabled: true  # Comments out the job

Cron with Locking (Prevent Overlap)

- cron:
    name: "Long-running sync"
    minute: "*/10"
    job: "flock -n /tmp/sync.lock /opt/scripts/sync.sh"

Manage Crontab File

# Deploy entire crontab from template
- cron:
    name: "Job 1"
    cron_file: myapp
    user: deploy
    minute: "0"
    hour: "*/2"
    job: "/opt/myapp/task1.sh"
  become: true
# Creates /etc/cron.d/myapp

Full Example

- name: Configure all cron jobs
  hosts: all
  become: true
  tasks:
    - cron:
        name: "{{ item.name }}"
        minute: "{{ item.minute | default('*') }}"
        hour: "{{ item.hour | default('*') }}"
        day: "{{ item.day | default('*') }}"
        weekday: "{{ item.weekday | default('*') }}"
        job: "{{ item.job }}"
        user: "{{ item.user | default('root') }}"
      loop:
        - { name: "DB backup", minute: "0", hour: "2", job: "/opt/backup-db.sh" }
        - { name: "Log rotate", minute: "0", hour: "0", job: "/opt/rotate-logs.sh" }
        - { name: "Health check", minute: "*/5", job: "/opt/healthcheck.sh" }
        - { name: "Report", minute: "0", hour: "8", weekday: "1", job: "/opt/weekly-report.sh" }

FAQ

How do I see current cron jobs?

ansible web1 -m command -a "crontab -l" -b

Does the cron module create the script too?

No — it only manages the crontab entry. Deploy scripts separately with copy or template.

How to ensure cron daemon is running?

- service: { name: cron, state: started, enabled: true }

Related Articles

environment keyword vs lookup env in AnsibleAnsible Windows playbook patternsinventory configuration in AnsibleAnsible Cron Module Guiderole dependencies in Ansible

Category: troubleshooting

Watch the video: Ansible Cron Module: Schedule Jobs & Tasks on Linux (Complete Guide) — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home