Deploy a Cron Job with Terraform

A cron job runs your container on a schedule. It starts, runs to completion, and exits. Use it for nightly batches, periodic clean-ups, scheduled exports, or any workload that runs at a fixed cadence.

Updated 23 Jun 20263 min read

A cron job runs your container on a schedule. It starts, runs to completion, and exits. Use it for nightly batches, periodic clean-ups, scheduled exports, or any workload that runs at a fixed cadence.

Required fields

FieldTypeExampleDescription
handlestring"nightly-cleanup"Permanent identifier.
namestring"Nightly Cleanup"Display name.
imagestring"myorg/cleanup:v1"Full image reference including tag.
typestring"cronjob"Must be set to cronjob. The type is permanent.
schedulestring"0 2 * * *"A standard 5-field cron expression.
timezonestring"Europe/London"IANA timezone for the schedule.
mincpustring"100"Guaranteed CPU in millicores.
minmemorystring"256"Guaranteed memory in megabytes.
autoscalingminreplicasstring"1"Set to "1".
activeregionslist["falkenstein-1"]One or more regions to run in.
projectstringbahriya_project.x.idThe project UUID (not handle).

Cron jobs do not need containerport or healthcheckpath.

Minimal example

resource "bahriya_container" "cleanup" {
  handle    = "nightly-cleanup"
  name      = "Nightly Cleanup"
  type      = "cronjob"
  image     = "myorg/cleanup:v1.0.0"
  schedule  = "0 2 * * *"
  timezone  = "Europe/London"
  mincpu    = "100"
  minmemory = "256"
 
  autoscalingminreplicas = "1"
  activeregions          = ["falkenstein-1"]
  project                = bahriya_project.app.id
}

With retry limits and deadlines

resource "bahriya_container" "report" {
  handle    = "daily-report"
  name      = "Daily Report"
  type      = "cronjob"
  image     = "myorg/report:v2.0.0"
  schedule  = "30 8 * * 1-5"
  timezone  = "Asia/Karachi"
  mincpu    = "500"
  minmemory = "1024"
 
  autoscalingminreplicas = "1"
  activeregions          = ["falkenstein-1"]
  project                = bahriya_project.app.id
 
  backofflimit            = 3
  activedeadlineseconds   = 3600
  ttlsecondsafterfinished = 600
 
  newenvvar {
    key   = "REPORT_FORMAT"
    value = "pdf"
  }
}

Schedule reference

ExpressionMeaning
0 2 * * *Every day at 02:00
*/15 * * * *Every 15 minutes
0 9 * * 1Every Monday at 09:00
0 0 1 * *First day of every month at midnight
30 8 * * 1-5Weekdays at 08:30

Concurrency policy

If a previous run is still going when the next is scheduled, the concurrencypolicy field decides what happens:

ValueBehaviour
Forbid (default)Skip the new run.
AllowRun both in parallel.
ReplaceCancel the old run, start the new one.
resource "bahriya_container" "cleanup" {
  # ... required fields ...
  concurrencypolicy = "Replace"
}

Suspend and resume

Set suspended = true to pause scheduling without deleting the cron job:

resource "bahriya_container" "cleanup" {
  # ... required fields ...
  suspended = true
}

Remove the flag (or set it to false) and apply again to resume.

Notes

  • The type field is permanent — you cannot convert a cron job to an HTTP container or worker.
  • The schedule fires in the configured timezone, regardless of which region the job runs in.
  • Billing is per-minute per execution, rounded up to 60 seconds minimum. No charge between executions or while suspended.