Playbook execution from Ansible Host - Crob

Hello,

Have been using Ansible, but only scratching the surface. I’m new to this community.

I know you can schedule CRON jobs on remote systems with a playbook. I already do this. But is it possible to run an ansible-playbook command FROM the Ansible host itself, with Cron? For example, I can run the command (From the Ansible server) such as "ansible-playbook MyPlaybooknameHere.yml Works perfect. However, I want to run this on a schedule from the Ansible server via cron.

08 13 * * * /usr/bin/ansible-playbook /etc/ansible/playbooks/MyPlaybooknameHere.yml

So far, it doesn’t appear to be executing via cron. Am I missing something?

Thanks in advance!

If you have AWX or AAP (AKA: Tower), you create execution schedules for jobs.

If you are executing from CLI on a Linux/Unix system, you should be able to create a cron job that runs on whatever schedule you need.

Instead of executing the cron job as you have called out, I would probably have the cron job call a bash script that sets up the working environment (python virtual environment, environment variables, working directory, etc.). At the end of the bash script, have it call the ansible-playbook.

Lastly, I’d setup the cron job to log all stdout and stderr to a log file so you can see the results of the daily executions.

1 Like

Thanks for the feedback. Do you have an example bash script to do this? I’m new to this and a working example to work off of would be perfect for me to learn. Do you have anything like this you’d be willing to share?

This is a very rough, very incomplete bash script you could use as a start.

# Set your environment variables
export ANSIBLE_VAULT_PASSWORD_FILE=/home/dustin/venvs/IaC/my_ansible_vault_password.txt
export ANSIBLE_CONTROLLER=https://myawx.mydomain.com
export ANSIBLE_USERNAME=myansibleusername

# Change the current working directory to your playbook folder
cd /path/to/playbooks_directory

# Execute your playbook
/path/to/ansible-playbook /path/to/myplaybook.yml -i /path/to/inventory

Notes:

  • If you are unsure where your “ansible-playbook” executable is located, use the which command from the same environment you normally run your playbooks manually.
(IaC) dustin@mypc:~/venvs/IaC$ which ansible-playbook
/home/dustin/venvs/IaC/bin/ansible-playbook
(IaC) dustin@mypc:~/venvs/IaC$    
  • Make sure to set the “execute” permission on the bash script file to avoid any permissions issues with crontab.

  • When starting from the beginning, it is very tempting to just put your passwords in clear text in your scripts. What I put in the bash example above hints at how you can put your necessary passwords in an ansible-vault. Definitely put the effort into understanding how ansible-vault works, and find a way to keep from putting your passwords into files as clear text.

2 Likes

Let me know how this turns out. If it works for you, mind marking my answer as the solution?

Thank you, Dustin

So just to test, I tried the following:

#!/bin/bash

# Change the current working directory to your playbook folder
cd /etc/ansible/playbooks

# Execute your playbook
/usr/bin/ansible-playbook /etc/ansible/playbooks/qualify_trunk.yml

Then changed the permissions to the appropriate execute permissions, etc. I can run the file directly on the Ansible host, and it works fine. But it does not work via a cronjob. Cronjob example below.

44 12 * * *  /usr/bin/bash /etc/ansible/scripts/Cron_Qualify_Trunk.sh >/dev/null 2>&1

I realize the above are very simplistic, but just to see if the thing will work, I made it very simple. Any ideas what I am missing?

Hi,

it does not work via a cronjob

What hints you on that ? Have you check crond (or the cron service you’re using) logs ?

Things to check:

  • Permissions on your script
  • If crond service is running
  • If user running your cron is member of the appropriate group.s
  • selinux context of you cron file

Also, what if you run it with: run-parts <yourCronFilePath> -v ?

1 Like

Just to confirm, your cron schedule 44 12 * * * means you want to run the cron every day at 44 minutes past noon, local time of the server.

Here’s a good link for building cron schedules:
Cron Schedule Builder

Some things I would check:

Is the cron daemon running on the server?

Check Cron Deamon Status

Look for the running process using ps -ef | grep crond. If it is running, you’ll see it in the listed processes

[my_server~]$ps -ef | grep crond
root      1699     1  0  2022 ?        00:01:28 /usr/sbin/crond -n
[my_server~]$

Is the server time correct. Maybe it is running, but not at the time you think it is.

Check Server Time

Your cron says it will run 44 minutes after noon, local time to the server.
Use the date command to validate the time on the server.

[my_server~]$date
Tue Feb 13 14:45:37 EST 2024
[my_server~]$

Are their errors when you run your command manually.

Run Manually and Look For Errors

Simply copy your entire cron command, excluding the schedule 44 12 * * *, and paste it into the CLI terminal.
See if there are any errors or helpful information displayed.


Write all STDOUT and STDERR to a log file and look for errors there.

Write all output to log

Instead of dumping all output to null with >/dev/null 2>&1, create a log file to contain your cron results and dump all logs there.
Then, you can check that log to see if it ever executed and if it had any errors during execution.

0 0 * * * /bin/bash /path/to/my/script.sh &>> /path/to/log/file.txt
1 Like

I run ansible jobs from crontab all the time, without making a shell script.

Here is a simple example:

10 0 * * * cd /opt/ansible && ansible-playbook /opt/ansible/playbooks/playbook-name.yml

The key for me was to make sure that I changed directory into my ansible directory (/opt/ansible) before then running the playbook.

1 Like

I’ll give that a try as well. having trouble getting it to run, and I have a feeling it is because of changing to the ansible folder. I installed ansible using pip, so not sure how to get the location properly. using “which ansible-playbook” gives me a location, but that does not seem to work.

Thank you for your help! It is working now, and I am able to have it log properly as well. However the script does not get written to if I do it from the cronjob. If I direct the output to a log file from inside the script, it properly outputs to the log file.

This has been very helpful and a learning exercise for me. Thank you!

1 Like

Just an FYI, I use old school methods with my cron jobs to make logs - I just pipe the results into a log file. Not elegant, but effective lol.

The earlier example was a simplified version, but here’s one I use that outputs into a log:

10 0 * * * cd /opt/ansible && echo date >> /var/log/playbook-name.log && ansible-playbook /opt/ansible/playbooks/playbook-name.yml >> /var/log/playbook-name.log

1 Like