I have so many cron jobs running in specific user. Try to check individual cron jobs is enabled or not. Moreover, everyday on some period, I will check by ansible.
- name: cronjob for test script
remote_user: {{root_user}}
become: true
cron:
user: "{{ app_user }}"
name: "test script"
hour: 20
weekday: 6
job: "/bin/bash {{test}}/test.sh >> {{test}}/test-cron-error.log 2>&1"
tags:
- deploy_test
- name: enable for test script
remote_user: {{root_user}}
become: true
cron:
user: "{{ app_user }}"
name: "test script"
hour: 20
weekday: 6
disabled: no
job: "/bin/bash {{test}}/test.sh >> {{test}}/test-cron-error.log 2>&1"
tags:
- enable_deploy_test
You can use a cron module to maintain a crontab for specific user by specifying user parameter. To periodically check the state of your crontabs, you can set a cron job running your playbook on your ansible master, if you have one. To ensure that your crontab doesn't contain other entries, you can remove all cron files before using the playbook, however you need to be sure that those "rewrites" are not happening at the same time as your jobs.
EDIT: Your cron task creates a cron job right away, there is no need to call the same task with disabled: no. If you have a task with cron module with state=present (this is default) and without disabled: yes - it will set a job as you defined.
Related
I've created a cron job in Drone CI using the following command
drone cron add --branch master "foo/bar" "every-5-mins" "0 */5 * * * *"
And when I look in the UI, I can see the cron job has been created. However, it doesn't fire, even though I have it defined in my drone yaml file.
- name: cron-job
pull: if-not-exists
image: foo-image
commands:
- *random
- echo "I am testing a cron job"
when: &cron-demo
event:
- cron
cron:
- every-5-mins
Does something else need to be done to get it to work on schedule?
And also, is there a way to manually trigger a cron job? I can't seem to find anything in the docs.
You might find this helpful.
https://docs.drone.io/api/cron/cron_trigger/
Basically, what you need is something like this.
curl -X POST -H "Authorization: Bearer $DRONE_TOKEN" "$DRONE_SERVER/api/repos/foo/bar/cron/every-5-mins"
I currently have a cronjob that creates a backup of a postgres db in ansible
- name: Create a cron job to export database.
become_user: postgres
cron:
name: "Export database"
minute: "*/2"
job: "pg_dump -U postgres -W -F t db_name > db_backup-$(date +%Y-%m-%d-%H.%M.%S).tar"
I want to run a gsutil cp command in the same job that then uploads this backup to a storage location in GCP.
I understand that with a cronjob you would simply separate the two jobs with && however I'm not sure how this would work in ansible.
Any pointers would be great, thank you!
What you put in the job attribute will end up in the crontab. (You can check this with crontab -l on the machine).
So you can do everything in ansible, you could do on the crontab directly, including chaining multiple commands separated by && or ;.
If you have a very long line here, I'd suggest to write a script and have cron execute that for readability reasons.
I have added the following line to cron to run the script on reboot
#reboot /usr/local/bin/autostart.sh
But when I prepared the ansible script for it I found that it adds 1 more line each time I apply the ansible.
The task is below:
- name: Add autostart script to cron
cron:
special_time: reboot
user: user
state: present
job: /usr/local/bin/autostart.sh
And after several updates I get the following cron:
#Ansible: None
#reboot /usr/local/bin/autostart.sh
#Ansible: None
#reboot /usr/local/bin/autostart.sh
#Ansible: None
#reboot /usr/local/bin/autostart.sh
#Ansible: None
#reboot /usr/local/bin/autostart.sh
As for me this is strange behavior because state: present should check if the record is already present.
Or maybe have I missed anything else?
Add name parameter. For example
- name: Add autostart script to cron
cron:
name: "autostart"
special_time: reboot
user: user
state: present
job: /usr/local/bin/autostart.sh
Quoting from cron
name: Description of a crontab entry or, if env is set, the name of environment variable. Required if state=absent. Note that if name is not set and state=present, then a new crontab entry will always be created, regardless of existing ones. This parameter will always be required in future releases.
I have about 50 Debian Linux servers with a bad cron job:
0 * * * * ntpdate 10.20.0.1
I want to configure ntp sync with ntpd and so I need to delete this cron job. For configuring I use Ansible. I have tried to delete the cron entry with this play:
tasks:
- cron: name="ntpdate" minute="0" job="ntpdate 10.20.0.1" state=absent user="root"
Nothing happened.
Then I run this play:
tasks:
- cron: name="ntpdate" minute="0" job="ntpdate pool.ntp.org" state=present
I see new cron job in output of "crontab -l":
...
# m h dom mon dow command
0 * * * * ntpdate 10.20.0.1
#Ansible: ntpdate
0 * * * * ntpdate pool.ntp.org
but /etc/cron.d is empty! I don't understand how the Ansible cron module works.
How can I delete my manually configured cron job with Ansible's cron module?
User's crontab entries are held under /var/spool/cron/crontab/$USER, as mentioned in the crontab man page:
Crontab is the program used to install, remove or list the tables used to drive the cron(8) daemon. Each user can have their own crontab, and though these are files in /var/spool/ , they are not intended to be edited directly. For SELinux in mls mode can be even more crontabs - for each range. For more see selinux(8).
As mentioned in the man page, and the above quote, you should not be editing/using these files directly and instead should use the available crontab commands such as crontab -l to list the user's crontab entries, crontab -r to remove the user's crontab or crontab -e to edit the user's crontab entries.
To remove a crontab entry by hand you can either use crontab -r to remove all the user's crontab entries or crontab -e to edit the crontab directly.
With Ansible this can be done by using the cron module's state: absent like so:
hosts : all
tasks :
- name : remove ntpdate cron entry
cron :
name : ntpdate
state : absent
However, this relies on the comment that Ansible puts above the crontab entry that can be seen from this simple task:
hosts : all
tasks :
- name : add crontab test entry
cron :
name : crontab test
job : echo 'Testing!' > /var/log/crontest.log
state : present
Which then sets up a crontab entry that looks like:
#Ansible: crontab test
* * * * * echo Testing > /var/log/crontest.log
Unfortunately if you have crontab entries that have been set up outside of Ansible's cron module then you are going to have to take a less clean approach to tidying up your crontab entries.
For this we will simply have to throw away our user's crontab using crontab -r and we can invoke this via the shell with a play that looks something like following:
hosts : all
tasks :
- name : remove user's crontab
shell : crontab -r
We can then use further tasks to set the tasks that you wanted to keep or add that properly use Ansible's cron module.
If you have very complicated crontab entries so you can also delete it by shell module of ansible as shown in below example.
---
- name: Deleting contab entry
hosts: ecx
become: true
tasks:
- name: "decroning entry"
shell:
"crontab -l -u root |grep -v mybot |crontab -u root -"
register: cronout
- debug: msg="{{cronout.stdout_lines}}"
Explanation:- You have to just replace "mybot" string on line 8 with your unique identity of crontab entry. that's it. for "how to delete multiple crontab entries by ansible" you can use multiple strings in grep as shown below
"crontab -l -u root |grep -v 'strin1\|string2\|string3\|string4' |crontab -u root -"
I have one application on elastic beanstalk and cron jobs for it.
The code of setting cron is
container_commands:
01_some_cron_job:
command: "echo '*/5 * * * * wget -O - -q -t 1 http://site.com/cronscript/' | crontab"
leader_only: true
This script calls the mail sender. And I'm receive two message per time.
code of http://site.com/cronscript/ looks like (php code)
require_once('ses.php');
$ses = new SimpleEmailService(EMAIL_SHORTKEY, EMAIL_LONGKEY);
$m = new SimpleEmailServiceMessage();
$m->addTo('user#domain.com');
$m->setFrom('response_service#domain.com');
$m->setSubject('test message');
$m->setMessageFromString('', 'message content');
$send_emails=($ses->sendEmail($m));
When I call http://site.com/cronscript/ from browser's address bar, I receive one message as I want.
I believe what's happening is that first time you deploy your app, AutoScaling picks one instance to be a leader and new cron job is created on that instance. Next time you deploy your app, AutoScaling picks another instance to be a leader. So you end up with the same cron job on two instances.
So the basic test would be to ssh to all instances and check their crontab contents with crontab -l
You can avoid duplicate cron jobs by removing old cron jobs on the instance regardless whether it is a leader or not.
container_commands:
00_remove_old_cron_jobs:
command: "crontab -r || exit 0"
01_some_cron_job:
command: "echo '*/5 * * * * wget -O - -q -t 1 http://example.com/cronscript/' | crontab"
leader_only: true
As mentioned in Running Cron In Elastic Beanstalk Auto-Scaling Environment: || exit 0 is mandatory because if there is no crontab in the machine the crontab -r command will return a status code > 0 (an error). Elastic Beanstalk stop the deploy process if one of the container_commands fail.
Although I personally never experienced a situation when crontab was not found on Elastic Beanstalk Instance.
You can run /opt/elasticbeanstalk/bin/leader-test.sh to test whether it is a leader instance or not.
Hope it helps.
I had the same problem, only change the user from root to the one which I'm logging in with eb ssh and it works.
My code looks like this.
files:
"/etc/cron.d/mycron":
mode: "000644"
owner: ec2-user
group: ec2-user
content: |
30 1 * * * echo $(date) >> /tmp/cron_start.log; /usr/local/bin/daily_script.sh >> /tmp/crons.log 2>&1;
"/usr/local/bin/daily_script.sh":
mode: "000755"
owner: ec2-user
group: ec2-user
content: |
#!/bin/bash
date > /tmp/date
# Your actual script content
/opt/python/run/venv/bin/python3 /opt/python/current/app/cronjob_files/email_data.py >> /opt/python/current/app/cron.logs 2>&1
exit 0
...