Looking for a Quick, Cheap Cron Job on Azure? Check Out Container App Jobs.

My software development team recently helped a client migrate their database from a manually-maintained VM to a managed Azure service. The migration went smoothly, but there was one lingering chore: finding a new home for a cron job.

Once a week, the old database server would copy a database between environments with a command like this:

mysqldump (... parameters) | mysql (...parameters)

I definitely didn’t want to keep an idle VM around, doing 10 minutes of work each week. We need something easier and cheaper, preferably with little to no maintenance overhead. I looked through various Azure resource types that can host long-running tasks and eventually settled on one.

Container App Job

Azure’s Container App Job is built to be able to handle a large swarm of custom Dockerized microservices, but it also easily meets my need. It can load an arbitrary Docker image, run a custom command that takes several minutes, and then quit (and stop incurring costs).

You can get a feel for the available configuration by clicking around the azure portal:

But, I wound up iterating on it with a repeatable Azure CLI command:

az containerapp job create -n my-db-copier -g my-resource-group \
    --trigger-type Schedule \
    --cron-expression "0 2 * * 6" \
    --replica-timeout 1800 \
    --replica-retry-limit 0 \
    --replica-completion-count 1 \
    --parallelism 1 \
    --image docker.io/mysql:8 \
    --command "bash" \
    --args "\-c" "set -o pipefail && mysqldump $SRC_DB_NAME ... | mysql ..." \
    --env-vars "SRC_DB_NAME=example1" "SRC_HOST=example2" ... \
    --workload-profile-name Consumption \
    --environment "/subscriptions/abc123/resourceGroups/my-resource-group/providers/Microsoft.App/managedEnvironments/managedEnvironment-foobar-abc123"

I love that we’re still using cron expressions, some ~50 years later.

What I Like About It

In addition to running on a schedule, the job can be invoked manually, which is occasionally handy.

One of my goals was for this to be inexpensive. Thanks to a generous base quota, so far it’s been completely free.

Because the one-line command depends on a couple of tools readily available in a public Docker image, we don’t have to build (and won’t have to maintain) an image of our own. Overall, this feels like an insultingly simple task for a sophisticated platform, but it’s been working great!

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *