Clear all cronjobs via ansible playbook - ansible

I have been making cron jobs like this
- name: Add in cronjob to run every 30 mins to update do cool things
cron:
name="Run cool.py"
minute="30"
job="cd /home/www/ && . env/bin/activate && python /home/www/cool.py >/dev/null 2>&1"
user=cooluser
Now I'd like to know, how to delete all the cronjobs in my ubuntu box. Since I've made a few while testing and want to start fresh

There are multiple ways. If you want to do it "correctly", you set state: absent on all cronjobs and run the playbook:
- name: Add in cronjob to run every 30 mins to update do cool things
cron:
name: "Run cool.py"
user: cooluser
state: absent
You need to set them for each cronjob you created, they are matched by name. Check the docs of the cron module.
If you just want to remove all the crontabs for a certain user, you can ssh to that box and run crontab -r -u cooluser. This will remove all jobs for cooluser, but leave everything in /etc/ untouched. But ansible does not add anything there.
If you want to do that, but use ansible, you can use the command module:
- name: remove all cronjobs for user cooluser
command: crontab -r -u cooluser
The first one is the one you should use in a production playbook. The other two can be used, if you just want to do a one-time cleanup to start fresh.
You can also check crontab -l -u cooluser to see all currently available cronjobs and crontab -e -u cooluser to edit them.

Related

what is the cleanest way to run 4 commands 1 after the other using ansible

I am trying to run 4 commands, one after the other, using ansible.
sudo qmicli -d /dev/cdc-wdm0 -p --wds-set-autoconnect-settings=disabled,roaming-allowed
sudo qmicli -d /dev/cdc-wdm0 -p --wds-get-autoconnect-settings
sudo systemctl daemon-reload
sudo systemctl restart redbox-lte.service
- name: run first command
shell: qmicli -d /dev/cdc-wdm0 -p --wds-set-autoconnect-settings=disabled,roaming-allowed
become: true
etc. for every command
I was wondering what best practice is; I am sure that must be a better way.
The following tasks accomplish what you want to do:
- name: Execute
become: true
shell: |
qmicli -d /dev/cdc-wdm0 -p --wds-set-autoconnect-settings=disabled,roaming-allowed && \
qmicli -d /dev/cdc-wdm0 -p --wds-get-autoconnect-settings
- name: Restart redbox-lte
become: true
systemd:
state: restarted
daemon_reload: yes
name: redbox-lte
However, regarding best practice, you should always make sure to write your ansible scripts in an idempotent matter and print proper tasks statuses. For that reason (especially for the shell module) you should use options like changed_when.
Once you ensured that your shell module is only being executed when needed you should go ahead and define the systemd restart as a handler, which will only execute if there was a change in the task that triggers the handler.

How do I setup and use Laravel Scheduling on AWS Elastic Beanstalk?

Scenario
As a fairly new user of Laravel and Elastic Beanstalk I soon found my self in the need to schedule operations, like most of us do.
In the past I had always used simple crontab scheduling for this. So now I stood before a list of questions:
How do I run Laravel code using crontab?
How do I setup crontab in my Elastic Beanstalk environment?
Finding the individual answers to these questions weren't that hard. Combining them and actually getting it all to work however turned out to be a bit tricky, which is why I've decided to share the solution here for others struggling with getting this to work properly.
Environment
Laravel 5.6
PHP 7.1
TL;DR:
See working .ebextentions configuration at the end of answer.
Environment
Laravel 5.6
PHP 7.1
How to I run Laravel code using crontab?
The answers to this question is of course the most obvious and if you're even the slightest in to Laravel you surely know the answer: Scheduling!
I won't bore you with explaining the brilliant thing that is Laravel Scheduling since you can read about it in the documentation yourself.
But the key thing we need to take with us is that Laravel Scheduling uses crontab to execute, as described in the documentation:
* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
Which brings us to the next, and a bit more tricky, question...
How do I setup crontab in my Elastic Beanstalk environment?
At first glance the answer to this question may seem pretty straight forward. I found this in the AWS Knownledge Center: How do I create a cron job on EC2 instances in an Elastic Beanstalk environment?
Here they describe how to setup a cron job on your Elastic Beanstalk EC2 machine using .ebextentions. In short what it does is creating a new file in the directory /etc/cron.d/ in which we put our desired cron job.
Files in this directory is then processed by crontab as the root user. There are some of the traps I walked in to, as I've commented below:
files:
# The name of the file should not contain any dot (.) or dash (-), this can
# cause the script not to run. Underscore (_) is OK.
"/etc/cron.d/mycron":
# This permissions is important so that root user can run the script.
mode: "000644"
# As the file is run by the root user it needs to be the owner of the file.
owner: root
# For consistency it's a good idea to have root as the group aswell.
group: root
# NOTE: We need to explicitly tell the cron job to be run as the root user!
content: |
* * * * * root /usr/local/bin/myscript.sh
# There need to be a new line after the actual cron job in the file.
Once we have stayed clear all of those traps, it's time to put in our Laravel Scheduling cron job from above. That should look something like this:
files:
"/etc/cron.d/schedule_run":
mode: "000644"
owner: root
group: root
content: |
* * * * * root php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
This won't really work in most cases though. That's because the Laravel Scheduler won't have access to your ENV variables and must noticeably not your database settings.
I found the answer to this here: How to Get Laravel Task Scheduling Working on AWS Elastic Beanstalk Cron
So a big shout out to George Bönnisch; I salute you sir for sharing this!
So with this last piece of the puzzle I was finally able to get the setup to work properly:
Working Solution
File structure:
[Project root]
|-- .ebextensions
| |-- cronjob.config
cronjob.config:
files:
"/etc/cron.d/schedule_run":
mode: "000644"
owner: root
group: root
content: |
* * * * * root . /opt/elasticbeanstalk/support/envvars && /usr/bin/php /var/www/html/artisan schedule:run 1>> /dev/null 2>&1
commands:
remove_old_cron:
command: "rm -f /etc/cron.d/*.bak"
Tip when using Laravel Scheduling on AWS Elastic Beanstalk!
Since one of the key features of Elastic Beanstalk is that it can autoscale and add more servers when needed, you might want to have a look on the new feature in Laravel Scheduling: Running Tasks On One Server.
In many cases you don't want your cron job to be executed on more than just one server. For example if you have a scheduled command for sending emails you don't want those sent multiple times.
NOTE: This requires that you use memcached or redis as your cache engine, as stated in the documentation. If you don't, have a look at the AWS service Elasticache.
NOTE 2: When using onOneServer() you must give the scheduled task a name using the name() method (before calling onOneServer()). Like so:
$schedule->command('my:task')
->name('my:task')
->daily()
->onOneServer();
A simpler approach is to use the new Periodic Tasks feature. Using the .ebextensions for cron jobs may lead to multiple machines running the same job or other race conditions with auto-scaling.
Jobs defined in cron.yaml are loaded only by the Worker environment and are guaranteed to run only by one machine at a time (the leader). It has a nice syncing mechanism to make sure there's no duplication. From the docs:
Elastic Beanstalk uses leader election to determine which instance in your worker environment queues the periodic task. Each instance attempts to become leader by writing to an Amazon DynamoDB table. The first instance that succeeds is the leader, and must continue to write to the table to maintain leader status. If the leader goes out of service, another instance quickly takes its place.
Creating a Cron for a Single or Multiple Workers
Place cron.yaml in the root of the project:
version: 1
cron:
- name: "schedule"
url: "/worker/schedule"
schedule: "* * * * *"
One thing to take into consideration is that in Beanstalk periodic tasks are designed to make an HTTP POST request to a URL in your application that in turn triggers the job you want to run. This is similar to how it also manages queues with SQS.
For Laravel
For Laravel specifically, you may create the routes and controllers to handle each scheduled job. But a better approach is to use Laravel's scheduler and have a single route that you call every minute.
This package will create those routes automatically for you https://github.com/dusterio/laravel-aws-worker
Troubleshooting Permissions
If you are running into trouble with the DynamoDB create Leader Table permissions when triggering a deploy from CodePipeline, it's because the CodePileline service role needs dynamodb:CreateTable. For instructions check these StackOverflow Question
Official Elastic Beanstalk Periodic Tasks Docs
you can use this with amazon Linux 2
using .ebextensions configurations you can run the commands directly
first you need to configure the command in separate file
create file under .ebextensions called cron_job.txt and add this line
* * * * * root . /opt/elasticbeanstalk/deployment/env && /usr/bin/php /var/www/html/artisan schedule:run 1>> /var/www/html/laralog.log 2>&1
notice that the first part different from amazon Linux 2 from amazon Linux 1
it loads the environment variables:
Linux 1 : . /opt/elasticbeanstalk/support/envvars
Linux 2 : . /opt/elasticbeanstalk/deployment/env
and after initialing the command in this separated file
we need to fire it through the init.config file which have the container commands in .ebextensions
we can define it as follow :
container_commands:
03cronjob:
command: 'cat .ebextensions/cron_jobs.txt > /etc/cron.d/cron_jobs && chmod 644 /etc/cron.d/cron_jobs'
and that's it you can try it and find the cron jobs executed successfully.
and you can also read this explained article
https://medium.com/qosoor/the-ultimate-guide-to-setup-cron-jobs-with-laravel-elastic-beanstalk-d497daaca1b0
Hope this is helpful
In AWS ECS we can use this without adding cron in to the container
https://github.com/spatie/laravel-cronless-schedule
This is how you can start the cronless schedule:
php artisan schedule:run-cronless
This is for docker users, had some trouble with this so thought its worth posting.
The cron needs to be added to schedule_run file on the server. However, even if you add a container_name to the Dockerrun.aws.json file it changes it to that plus some extra information and therefore you cannot use the normal service name to run the cron.
So using $(docker ps -qf name=php-fpm) where name is part of the name of your container it will return the ID of the container. My container is called php-fpm.
Here is my working file (.ebextensions/01-cron.config).
files:
"/etc/cron.d/schedule_run":
mode: "000644"
owner: root
group: root
content: |
* * * * * root docker exec -t $(docker ps -qf name=php-fpm) sh -c "php artisan schedule:run" >> /var/log/eb-cron.log 2>&1
commands:
002-remove_old_cron:
command: "rm -f /etc/cron.d/*.bak"
Note: it mite be that the first time this cron runs the container is not up. Since the cron in my example is running each minute it didnt matter too much as by the time it runs the 2nd time, the container is up and working.
After several efforts, I found an alternative way to run a cron job easily. You can run a cron job easily in 3 Steps.
Step 1: Create a route
routes/web.php
Route::get('/cron/run',[HomeController::class, 'cron'])->name('cron');
Step 2: Create a function in the HomeController
public function cron()
{
\Artisan::call("schedule:run");
return 'run cron successful';
}
Step 3:
Run the URL every minute using https://cron-job.org/en/
The cron is not triggered because the location of the env file in the old solutions is wrong. Actually, there is nothing wrong with anything. Below is the command you can use currently. We use it in all projects.
Create a cronjob.config in the .ebextensions folder. Then put these to the inside of the file.
files:
"/etc/cron.d/schedule_run":
mode: "000644"
owner: root
group: root
content: |
* * * * * root . /opt/elasticbeanstalk/deployment/env && /usr/bin/php /var/www/html/artisan schedule:run 1>> /var/www/html/storage/logs/laravel_cron.log 2>&1
commands:
remove_old_cron:
command: "rm -f /etc/cron.d/*.bak"
The accepted answer (of #Niklas) unfortunately didn't work for me.
There's even a more comprehensive explanation of that answer here:
https://medium.com/qosoor/the-ultimate-guide-to-setup-cron-jobs-with-laravel-elastic-beanstalk-d497daaca1b0
But as I said, that didn't work for me.
What worked for me is simpler:
(.ebextensions/cron.config)
files:
"/etc/cron.d/mycron":
mode: "000644"
owner: root
group: root
content: |
* * * * * root /usr/local/bin/myscript.sh
"/usr/local/bin/myscript.sh":
mode: "000755"
owner: root
group: root
content: |
#!/bin/bash
date > /tmp/date
cd /var/www/html/ && php artisan schedule:run >> /dev/null 2>&1
exit 0
commands:
remove_old_cron:
command: "rm -f /etc/cron.d/mycron.bak"
I simply copied the command from Laravel documentation and put it into the config file given by AWS documentation.

Can't run sudo command in Ansible playbook

I am writing an Ansible playbook to automate a series of sudo commands on various hosts. When I execute these commands individually in puTTY, I have no permission problems, as I have been granted proper access. However, when I attempt to create a playbook to do the same thing, I am told
user is not allowed to execute ... on host_name
For example, if I do $ sudo ls /root/, I have no problem, and, once I enter my password, can see the contents of /root/
In the case of my Ansible playbook ...
---
- host: servers
tasks:
- name: ls /root/
shell: ls /root/
become: true
become_method: sudo
...I then get the error mentioned above.
Any ideas why this would be the case? It seems to be telling me I don't have permission to run a command that I otherwise could run in an individual puTTY terminal.
[ ] automate a series of sudo commands on various hosts. When I execute these commands individually [ ]
Any ideas why this would be the case?
Sounds like you configured specific commands in the sudoers file (unfortunately you did not provide enough details, fortunately you asked for "ideas" not the real cause).
Ansible shell module does not run the command you specify prepended with sudo - it runs the whole shell session with sudo, so the command doesn't match what you configured in sudoers.
Either allow all commands to be run with elevated privileges for the Ansible user, or use raw module instead of shell.

Stuck on debugging an ansible task running remote command that freezes

I'm setting up an Ansible role to install Ahsay Offsite Backup Server.
After downloading and extracting the compressed file containing the software, I need to run the install script. I've determined that it's a step early in the script where it checks that your current user has appropriate permissions which is failing to run.
When I run the playbook, the final task never finishes.
The role
- name: Check if OBS install files have already been downloaded
stat:
path: /tmp/obs/version.txt
register: stat_result
- name: Ensures /tmp/obs exists
file: path=/tmp/obs state=directory
- name: Download and extract OBS install files
unarchive:
src: https://ahsay-dn.ahsay.com/v6/obsr/62900/obsr-nix.tar.gz
dest: /tmp/obs
remote_src: true
validate_certs: no
when: stat_result.stat.exists == false
- name: Install OBS
command: bash -lc "/tmp/obs/bin/install.sh > /tmp/install_output.log"
The playbook configuration is for all tasks to become sudo.
If I run the command in a shell on the remote host, it executes successfully.
I've hit similar issues before where commands fail because (in the case of rvm) it requires the bash_profile to load and pull in a bunch of environment variables first. The fix for that was as I've done above, to wrap the command in bash -lc "...", but that hasn't helped this time.
I'd love any suggestions of how I could continue troubleshooting this one.
you are checking for file presence before ensuring the folder.
some applications require tty, and when not on it they ask some stupid question
to really debug while the command is "stuck" connect to the offending machine, and try analyzing what does the script do: look in its /proc/${PID} folder (if you're on linux), maybe connect to it via strace -p ${PID} and maybe dup its stderr to see maybe it prints something that makes sense to you.
Also, you don't really have to run command, you can use shell module, and specify its args to make sure the command runs from specific folder, like so:
- name: Install OBS
shell: |
./bin/install.sh \
1> /tmp/install.output.log \
2> /tmp/install.error.log
args:
executable: /bin/bash
chdir: /tmp/obs

How do you run a crontab in Cygwin on Windows?

Some cygwin commands are .exe files, so you can run them with the standard Windows Scheduler, but others don't have an .exe extension so can't be run from DOS (it seems like).
For example I want updatedb to run nightly.
How do I make cron work?
You need to also install cygrunsrv so you can set cron up as a windows service, then run cron-config.
If you want the cron jobs to send email of any output you'll also need to install either exim or ssmtp (before running cron-config.)
See /usr/share/doc/Cygwin/cron-*.README for more details.
Regarding programs without a .exe extension, they are probably shell scripts of some type. If you look at the first line of the file you could see what program you need to use to run them (e.g., "#!/bin/sh"), so you could perhaps execute them from the windows scheduler by calling the shell program (e.g., "C:\cygwin\bin\sh.exe -l /my/cygwin/path/to/prog".)
You have two options:
Install cron as a windows service, using cygrunsrv:
cygrunsrv -I cron -p /usr/sbin/cron -a -n
net start cron
Note, in (very) old versions of cron you need to use -D instead of -n
The 'non .exe' files are probably bash scripts, so you can run them via the windows scheduler by invoking bash to run the script, e.g.:
C:\cygwin\bin\bash.exe -l -c "./full-path/to/script.sh"
hat tip http://linux.subogero.com/894/cron-on-cygwin/
Start the cygwin-setup and add the “cron” package from the “Admin” category.
We’ll run cron as a service by user SYSTEM. Poor SYSTEM therefore needs a home directory and a shell. The “/etc/passwd” file will define them.
$ mkdir /root
$ chown SYSTEM:root /root
$ mcedit /etc/passwd
SYSTEM:*:......:/root:/bin/bash
The start the service:
$ cron-config
Do you want to remove or reinstall it (yes/no) yes
Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec
Do you want the cron daemon to run as yourself? (yes/no) no
Do you want to start the cron daemon as a service now? (yes/no) yes
Local users can now define their scheduled tasks like this (crontab will start your favourite editor):
$ crontab -e # edit your user specific cron-table HOME=/home/foo
PATH=/usr/local/bin:/usr/bin:/bin:$PATH
# testing - one per line
* * * * * touch ~/cron
#reboot ~/foo.sh
45 11 * * * ~/lunch_message_to_mates.sh
Domain users: it does not work. Poor cron is unable to run scheduled tasks on behalf of domain users on the machine. But there is another way: cron also runs stuff found in the system level cron table in “/etc/crontab”. So insert your suff there, so that SYSTEM does it on its own behalf:
$ touch /etc/crontab
$ chown SYSTEM /etc/crontab
$ mcedit /etc/crontab
HOME=/root
PATH=/usr/local/bin:/usr/bin:/bin:$PATH
* * * * * SYSTEM touch ~/cron
#reboot SYSTEM rm -f /tmp/.ssh*
Finally a few words about crontab entries. They are either environment settings or scheduled commands. As seen above, on Cygwin it’s best to create a usable PATH. Home dir and shell are normally taken from “/etc/passwd”.
As to the columns of scheduled commands see the manual page.
If certain crontab entries do not run, the best diagnostic tool is this:
$ cronevents
Just wanted to add that the options to cron seem to have changed. Need to pass -n rather than -D.
cygrunsrv -I cron -p /usr/sbin/cron -a -n
Applied the instructions from this answer and it worked
Just to point out a more copy paste like answer ( because cygwin installation procedure is kind of anti-copy-paste wise implemented )
Click WinLogo button , type cmd.exe , right click it , choose "Start As Administrator". In cmd prompt:
cd <directory_where_i_forgot_the setup-x86_64.exe> cygwin installer:
set package_name=cygrunsrv cron
setup-x86_64.exe -n -q -s http://cygwin.mirror.constant.com -P %package_name%
Ensure the installer does not throw any errors in the prompt ... If it has - you probably have some cygwin binaries running or you are not an Windows admin, or some freaky bug ...
Now in cmd promt:
C:\cygwin64\bin\cygrunsrv.exe -I cron -p /usr/sbin/cron -a -D
or whatever full file path you might have to the cygrunsrv.exe and
start the cron as windows service in the cmd prompt
net start cron
Now in bash terminal run
crontab -e
set up you cron entry an example bellow:
#sync my gdrive each 10th minute
*/10 * * * * /home/Yordan/sync_gdrive.sh
# * * * * * command to be executed
# - - - - -
# | | | | |
# | | | | +- - - - day of week (0 - 6) (Sunday=0)
# | | | +- - - - - month (1 - 12)
# | | +- - - - - - day of month (1 - 31)
# | +- - - - - - - hour (0 - 23)
# +--------------- minute
I figured out how to get the Cygwin cron service running automatically when I logged on to Windows 7. Here's what worked for me:
Using Notepad, create file C:\cygwin\bin\Cygwin_launch_crontab_service_input.txt with content no on the first line and yes on the second line (without the quotes). These are your two responses to prompts for cron-config.
Create file C:\cygwin\Cygwin_launch_crontab_service.bat with content:
#echo off
C:
chdir C:\cygwin\bin
bash cron-config < Cygwin_launch_crontab_service_input.txt
Add a Shortcut to the following in the Windows Startup folder:
Cygwin_launch_crontab_service.bat
See http://www.sevenforums.com/tutorials/1401-startup-programs-change.html if you need help on how to add to Startup. BTW, you can optionally add these in Startup if you would like:
Cygwin
XWin Server
The first one executes
C:\cygwin\Cygwin.bat
and the second one executes
C:\cygwin\bin\run.exe /usr/bin/bash.exe -l -c /usr/bin/startxwin.exe
The correct syntax to install cron in cygwin as Windows service is to pass -n as argument and not -D:
cygrunsrv --install cron --path /usr/sbin/cron --args -n
-D returns usage error when starting cron in cygwin:
$
$cygrunsrv --install cron --path /usr/sbin/cron --args -D
$cygrunsrv --start cron
cygrunsrv: Error starting a service: QueryServiceStatus: Win32 error 1062:
The service has not been started.
$cat /var/log/cron.log
cron: unknown option -- D
usage: /usr/sbin/cron [-n] [-x [ext,sch,proc,parc,load,misc,test,bit]]
$
Below page has a good explanation.
Installing & Configuring the Cygwin Cron Service in Windows:
https://www.davidjnice.com/cygwin_cron_service.html
P.S. I had to run Cygwin64 Terminal on my Windows 10 PC as administrator in order to install cron as Windows service.
Getting updatedb to work in cron on Cygwin -- debugging steps
1) Make sure cron is installed.
a) Type 'cron' tab tab and look for completion help.
You should see crontab.exe, cron-config, etc. If not install cron using setup.
2) Run cron-config. Be sure to read all the ways to diagnose cron.
3) Run crontab -e
a) Create a test entry of something simple, e.g.,
"* * * * * echo $HOME >> /tmp/mycron.log" and save it.
4) cat /tmp/mycron.log. Does it show cron environment variable HOME
every minute?
5) Is HOME correct? By default mine was /home/myusername; not what I wanted.
So, I added the entry
"HOME='/cygdrive/c/documents and settings/myusername'" to crontab.
6) Once assured the test entry works I moved on to 'updatedb' by
adding an entry in crontab.
7) Since updatedb is a script, errors of sed and find showed up in
my cron.log file. In the error line, the absolute path of sed referenced
an old version of sed.exe and not the one in /usr/bin. I tried changing my
cron PATH environment variable but because it was so long crontab
considered the (otherwise valid) change to be an error. I tried an
explicit much-shorter PATH command, including what I thought were the essential
WINDOWS paths but my cron.log file was empty. Eventually I left PATH alone and
replaced the old sed.exe in the other path with sed.exe from /usr/bin.
After that updatedb ran to completion. To reduce the number of
permission error lines I eventually ended up with this:
"# Run updatedb at 2:10am once per day skipping Sat and Sun'
"10 2 * * 1-5 /usr/bin/updatedb --localpaths='/cygdrive/c' --prunepaths='/cygdrive/c/WINDOWS'"
Notes: I ran cron-config several times throughout this process
to restart the cygwin cron daemon.

Resources