Cron jobs on Elastic Beanstalk PHP apps
How to add a cron job to an Elastic Beanstalk PHP app, and how to make your environment variables available to the cron.
Elastic Beanstalk lets you run scheduled tasks on your PHP application's instances using a cron job, configured through an .ebextensions file. Here's how to add one, and how to make your environment variables available to it.
This assumes you already have an application running on Elastic Beanstalk. If yours is a single-instance environment, you may also want to put it behind HTTPS with CloudFront, or read up on migrating an application to the cloud in the first place.
Adding a cron job
Create a config file in .ebextensions, such as .ebextensions/01cronjob.config, containing:
---
files:
"/etc/cron.d/mycronfile":
mode: "000644"
owner: root
group: root
content: |
* * * * * root php /path/to/your/executable
commands:
remove_old_cron:
command: "rm -f /etc/cron.d/*.bak"
Passing environment variables to a cron job
When using the Amazon Linux 2 AMI, Elastic Beanstalk environment variables are not exposed to the operating system - this means when you access your EC2 via SSH, you can't use environment variables.
Furthermore, the environment variables also aren't exposed to the other Linux users, even the root user under which cron jobs are typically run.
AWS provide a helpful .ebextension solution here to create a file in /etc/profile.d/ which is read by bash and exposes the environment variables to the user's shell.
commands:
setvars:
command: /opt/elasticbeanstalk/bin/get-config environment | jq -r 'to_entries | .[] | "export \(.key)=\"\(.value)\""' > /etc/profile.d/sh.local
packages:
yum:
jq: []
This works great when you SSH onto the EC2 and run a PHP command as the ec2-user user - but for a cron job running under root you also need to expose the environment variables to the root user.
The below is what I've been using to pass the Elastic Beanstalk environment variables to the cron job. Add a reference to the sh.local file before your PHP command, so
* * * * * root php /path/to/your/executable
becomes this (note the dot .)
* * * * * root . /etc/profile.d/sh.local; php /path/to/your/executable
This extra bit exposes the Elastic Beanstalk environment variables stored in the file to the root user when running the cron.
Here's a complete cron config file:
---
files:
"/etc/cron.d/mycronfile":
mode: "000644"
owner: root
group: root
content: |
* * * * * root . /etc/profile.d/sh.local; php /path/to/your/executable
commands:
remove_old_cron:
command: "rm -f /etc/cron.d/*.bak"