Ansible for cron and at Jobs

ansible.builtin.cron edits a user's crontab or a file in /etc/cron.d. The name is mandatory in practice: the module writes it as a Ansible: <name comment above the job and uses it to find the job next time. Without a stable name, every run adds a duplicate.

yaml - ansible.builtin.cron: name: webasha heartbeat user: devops minute: "/2" job: logger "WebAsha heartbeat"

Time fields are minute, hour, day, month, weekday, all strings, default . specialtime: reboot|hourly|daily|weekly|... replaces them. state: absent with the same name removes a job, disabled: true comments it out.

System cron files need cronfile and a user that appears in the line:

yaml - ansible.builtin.cron: name: nightly backup cronfile: webasha-backup /etc/cron.d/webasha-backup user: root minute: "30" hour: "2" weekday: "1-5" job: /usr/local/bin/backup.sh

Environment lines (MAILTO, PATH) use env: true with name as the variable and job as the value.

One-off jobs. ansible.posix.at queues a command once; unique: true stops a second run from queuing it again.

yaml - ansible.posix.at: command: /usr/bin/df -h /tmp/df.txt count: 20 units: minutes unique: true

atd must be running. systemd timers have no dedicated module: drop the .service and .timer with copy and enable the timer with systemdservice.

Checking your work. ansible dev -m command -a 'crontab -l -u devops' shows the job with its Ansible: marker; cat /etc/cron.d/<file shows system jobs, and atq with at -c <id shows queued at jobs. Run the playbook twice and check that the crontab still has exactly one copy of each job. Remember that cron does not read the job for you: test the command itself once with an ad-hoc command run if you are unsure that its path or quoting is right.

Pitfalls. Writing minute: /2 unquoted (YAML alias error). Putting the job in root's crontab when the task says user X. Expecting cron to validate your command: it does not run it. Removing a job created by hand: only works if it has the Ansible: marker, otherwise edit with lineinfile.