James Galley Software engineer - SaaS, AI automation & business operations

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.

AWS • DevOps

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"