AWS Elastic Beanstalk, running a cronjob

This is how I added a cron job to Elastic Beanstalk:

Create a folder at the root of your application called .ebextensions if it doesn’t exist already. Then create a config file inside the .ebextensions folder. I’ll use example.config for illustration purposes. Then add this to example.config

container_commands:
  01_some_cron_job:
    command: "cat .ebextensions/some_cron_job.txt > /etc/cron.d/some_cron_job && chmod 644 /etc/cron.d/some_cron_job"
    leader_only: true

This is a YAML configuration file for Elastic Beanstalk. Make sure when you copy this into your text editor that your text editor uses spaces instead of tabs. Otherwise you’ll get a YAML error when you push this to EB.

So what this does is create a command called 01_some_cron_job. Commands are run in alphabetical order so the 01 makes sure it’s run as the first command.

The command then takes the contents of a file called some_cron_job.txt and adds it to a file called some_cron_job in /etc/cron.d.

The command then changes the permissions on the /etc/cron.d/some_cron_job file.

The leader_only key ensures the command is only run on the ec2 instance that is considered the leader. Rather than running on every ec2 instance you may have running.

Then create a file called some_cron_job.txt inside the .ebextensions folder. You will place your cron jobs in this file.

So for example:

# The newline at the end of this file is extremely important.  Cron won't run without it.
* * * * * root /usr/bin/php some-php-script-here > /dev/null

So this cron job will run every minute of every hour of every day as the root user and discard the output to /dev/null. /usr/bin/php is the path to php. Then replace some-php-script-here with the path to your php file. This is obviously assuming your cron job needs to run a PHP file.

Also, make sure the some_cron_job.txt file has a newline at the end of the file just like the comment says. Otherwise cron won’t run.

Update:
There is an issue with this solution when Elastic Beanstalk scales up your instances. For example, lets say you have one instance with the cron job running. You get an increase in traffic so Elastic Beanstalk scales you up to two instances. The leader_only will ensure you only have one cron job running between the two instances. Your traffic decreases and Elastic Beanstalk scales you down to one instance. But instead of terminating the second instance, Elastic Beanstalk terminates the first instance that was the leader. You now don’t have any cron jobs running since they were only running on the first instance that was terminated. See the comments below.

Update 2:
Just making this clear from the comments below:
AWS has now protection against automatic instance termination. Just enable it on your leader instance and you’re good to go. – Nicolás Arévalo Oct 28 ’16 at 9:23

Leave a Comment