Skip to main content

CronOperation

A CronOperation creates Operations on a schedule, like Kubernetes CronJobs. Use CronOperations for recurring operational tasks such as database backups, certificate rotation, or periodic maintenance.

How CronOperations work

CronOperations contain a template for an Operation and create new Operations based on a cron schedule. Each scheduled run creates a new Operation that executes once to completion.

apiVersion: ops.crossplane.io/v1alpha1
kind: CronOperation
metadata:
name: daily-backup
spec:
schedule: "0 2 * * *" # Daily at 2 AM
concurrencyPolicy: Forbid
successfulHistoryLimit: 5
failedHistoryLimit: 3
operationTemplate:
spec:
mode: Pipeline
pipeline:
- step: backup
functionRef:
name: function-database-backup
input:
apiVersion: fn.crossplane.io/v1beta1
kind: DatabaseBackupInput
retentionDays: 7
important

CronOperations are an alpha feature. You must enable Operations by adding --enable-operations to Crossplane's arguments.

Key features

  • Standard cron scheduling syntax - Uses the same format as Kubernetes CronJobs
  • Configurable concurrency policies (Allow, Forbid, Replace)
  • Automatic cleanup of old Operations - Maintains history limits
  • Tracks run history and running operations - Provides visibility into scheduled runs

Scheduling

CronOperations use standard cron syntax:

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of the month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
│ │ │ │ │
* * * * *

Common schedule examples:

  • "0 2 * * *" - Every day at 2:00 AM
  • "0 0 * * 0" - Every Sunday at midnight
  • "0 0 1 * *" - Every month on the first at midnight
  • "*/15 * * * *" - Every 15 minutes

Concurrency policies

CronOperations support three concurrency policies:

  • Allow (default): Multiple Operations can run simultaneously. Use this when operations don't interfere with each other.
  • Forbid: New Operations don't start if previous ones are still running. Use this for operations that can't run concurrently.
  • Replace: New Operations stop running ones before starting. Use this when you always want the latest operation to run.

History management

Control the number of completed Operations to keep:

spec:
successfulHistoryLimit: 5 # Keep 5 successful operations
failedHistoryLimit: 3 # Keep 3 failed operations for debugging

This helps balance debugging capabilities with resource usage.

Common use cases

note

The following examples use hypothetical functions for illustration. At launch, only function-python supports operations.

Scheduled database backups

apiVersion: ops.crossplane.io/v1alpha1
kind: CronOperation
metadata:
name: postgres-backup
spec:
schedule: "0 3 * * *" # Daily at 3 AM
concurrencyPolicy: Forbid # Don't allow overlapping backups
operationTemplate:
spec:
mode: Pipeline
pipeline:
- step: backup
functionRef:
name: function-postgres-backup
input:
apiVersion: fn.crossplane.io/v1beta1
kind: PostgresBackupInput
instance: production-db
s3Bucket: db-backups

Scheduled maintenance

apiVersion: ops.crossplane.io/v1alpha1
kind: CronOperation
metadata:
name: weekly-maintenance
spec:
schedule: "0 3 * * 0" # Weekly on Sunday at 3 AM
operationTemplate:
spec:
mode: Pipeline
pipeline:
- step: cleanup-logs
functionRef:
name: function-log-cleanup
input:
apiVersion: fn.crossplane.io/v1beta1
kind: LogCleanupInput
retentionDays: 30
- step: update-certificates
functionRef:
name: function-cert-renewal

Periodic health checks

apiVersion: ops.crossplane.io/v1alpha1
kind: CronOperation
metadata:
name: health-check
spec:
schedule: "*/30 * * * *" # Every 30 minutes
operationTemplate:
spec:
mode: Pipeline
pipeline:
- step: check-cluster-health
functionRef:
name: function-health-check
input:
apiVersion: fn.crossplane.io/v1beta1
kind: HealthCheckInput
alertThreshold: 80

Advanced configuration

Complex scheduling patterns

Advanced cron schedule examples for specific use cases:

# Weekdays only at 9 AM (Monday-Friday)
schedule: "0 9 * * 1-5"

# Every 4 hours during business days
schedule: "0 8,12,16 * * 1-5"

# First and last day of each month
schedule: "0 2 1,L * *"

# Every quarter (1st of Jan, Apr, Jul, Oct)
schedule: "0 2 1 1,4,7,10 *"

# Business hours only, every 2 hours
schedule: "0 9-17/2 * * 1-5"

Starting deadline

CronOperations support a startingDeadlineSeconds field that controls how long to wait after the scheduled time before considering it too late to create the Operation:

apiVersion: ops.crossplane.io/v1alpha1
kind: CronOperation
metadata:
name: deadline-example
spec:
schedule: "0 9 * * 1-5" # Weekdays at 9 AM
startingDeadlineSeconds: 900 # 15 minutes
operationTemplate:
spec:
mode: Pipeline
pipeline:
- step: morning-tasks
functionRef:
name: function-morning-tasks

If the Operation can't start in 15 minutes of 9 AM (due to controller downtime, resource constraints, etc.), the scheduled run is skipped.

Skip operations for:

  • Time-sensitive operations - Skip operations that become meaningless if delayed
  • Resource protection - Prevent backup Operations piling up during outages
  • SLA compliance - Ensure operations run in acceptable time windows

Time zone considerations

important

CronOperations use the cluster's local time zone, same as Kubernetes CronJobs. To ensure consistent scheduling across different environments, consider:

  1. Standardize cluster time zones - Use UTC in production clusters
  2. Document time zone assumptions - Note expected time zone in comments
  3. Account for DST changes - Be aware that some schedules may skip or repeat during transitions

Status and monitoring

CronOperations provide status information about scheduling:

status:
conditions:
- type: Synced
status: "True"
reason: ReconcileSuccess
- type: Scheduling
status: "True"
reason: ScheduleActive
lastScheduleTime: "2024-01-15T10:00:00Z"
lastSuccessfulTime: "2024-01-15T10:02:30Z"
runningOperationRefs:
- name: daily-backup-1705305600

Key status fields:

  • Conditions: Standard Crossplane conditions (Synced) and CronOperation-specific conditions:
    • Scheduling: True when the CronOperation is actively scheduling operations, False when paused or has incorrect schedule syntax
  • lastScheduleTime: When the CronOperation last created an Operation
  • lastSuccessfulTime: When an Operation last completed successfully
  • runningOperationRefs: Running Operations

Events

CronOperations emit events for important activities:

  • CreateOperation (Warning) - Scheduled operation creation failures
  • GarbageCollectOperations (Warning) - Garbage collection failures
  • ReplaceRunningOperation (Warning) - Running operation deletion failures
  • InvalidSchedule (Warning) - Cron schedule parsing errors

Monitoring

Monitor CronOperations using:

# Check CronOperation status
kubectl get cronoperation my-cronop

# View recent Operations created by the CronOperation
kubectl get operations -l crossplane.io/cronoperation=my-cronop

# Check events
kubectl get events --field-selector involvedObject.name=my-cronop

Best practices

Scheduling considerations

  1. Consider time zones - CronOperations use the host's local time (same as Kubernetes CronJobs)
  2. Plan for long-running operations - Ensure operations complete before next scheduled run
  3. Set reasonable history limits - Balance debugging needs with cluster resource usage

Concurrency policies

  1. Choose appropriate concurrency policies:
    • Forbid for backups, maintenance, or operations that must complete alone
    • Replace for health checks or monitoring where latest data is most important
    • Allow for independent tasks that can run simultaneously

For general Operations best practices including function development and operational considerations, see Operation best practices.

Troubleshooting

CronOperation not creating Operations

  1. Check the cron schedule syntax
  2. Verify the CronOperation has Synced=True condition
  3. Look for events indicating schedule parsing errors

Operations failing often

  1. Check Operation events and logs
  2. Verify function capabilities include operation
  3. Review retry limits and adjust as needed

Resource cleanup issues

  1. Verify you set history limits appropriately
  2. Check for events about garbage collection failures