|
| 1 | +--- |
| 2 | +weight: 60 |
| 3 | +--- |
| 4 | + |
| 5 | +# ScheduledTrigger |
| 6 | + |
| 7 | +ScheduledTrigger adds cron-like automation to Tekton Triggers. Instead of waiting for external webhooks, you can ask the platform to render a TriggerTemplate on a repeating schedule, optionally honoring a specific timezone and injecting time-aware parameters into every run. |
| 8 | + |
| 9 | +## Terminology Explanation |
| 10 | + |
| 11 | +| Term | Description | |
| 12 | +|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------| |
| 13 | +| ScheduledTrigger | A Kubernetes custom resource that defines when and how a TriggerTemplate should run on a schedule. | |
| 14 | +| TriggerTemplate | The Tekton template that creates PipelineRuns, TaskRuns, or other resources. | |
| 15 | +| Schedule | A cron expression that describes the desired cadence (minute, hour, day, month, weekday). | |
| 16 | +| TimeZone | An optional Olson timezone string (for example `Asia/Shanghai`) that adjusts how the cron expression is evaluated. | |
| 17 | +| Context Parameters | Built-in placeholders (`$(context.date)` and `$(context.datetime)`) that resolve to the scheduled firing time before the TriggerTemplate runs. | |
| 18 | + |
| 19 | +## Why We Need ScheduledTrigger |
| 20 | + |
| 21 | +### Challenges of Time-Based Automation |
| 22 | + |
| 23 | +- Teams often pair Tekton with ad-hoc CronJobs, shell scripts, or external schedulers just to trigger periodic pipelines. |
| 24 | +- Operational tasks (nightly scans, weekly cleanups, end-of-month reports) require consistent timing and visibility. |
| 25 | +- Overlapping cron jobs and manual scripts increase maintenance costs and make auditing difficult. |
| 26 | + |
| 27 | +### How ScheduledTrigger Helps |
| 28 | + |
| 29 | +ScheduledTrigger keeps scheduling and pipeline execution in the same system: |
| 30 | + |
| 31 | +1. **Single definition** – declare the cadence, timezone, and template in one manifest. |
| 32 | +2. **Event parity** – TriggerTemplates run exactly as if they were invoked by an EventListener, so downstream tooling, RBAC, and observability behave the same. |
| 33 | +3. **Context awareness** – every run receives structured timestamps, enabling deterministic naming, reporting, or data partitioning. |
| 34 | +4. **Built-in catch-up** – if the controller restarts, it can replay missed ticks up to a reasonable limit, reducing manual intervention. |
| 35 | + |
| 36 | +## Advantages |
| 37 | + |
| 38 | +- **Declarative scheduling** using Kubernetes-native CRDs. |
| 39 | +- **Timezone control** to ensure nightly jobs align with business hours anywhere in the world. |
| 40 | +- **Consistent parameterization** via context placeholders and user-defined params. |
| 41 | +- **Reduced glue code** because no extra CronJobs or webhook shims are required. |
| 42 | +- **Unified observability**: events, status, and logs live alongside other Tekton resources. |
| 43 | +- **Safer retries** thanks to controlled catch-up behavior for missed executions. |
| 44 | + |
| 45 | +## Applicable Scenarios |
| 46 | + |
| 47 | +1. **Nightly regression tests or security scans** that must run even when no Git activity occurs. |
| 48 | +2. **Maintenance workflows** such as cache cleanup, asset rotation, or database exports. |
| 49 | +3. **Compliance and auditing jobs** that must fire on a fixed calendar cadence. |
| 50 | +4. **Hybrid automation** where webhook-triggered pipelines are supplemented with periodic baseline runs. |
| 51 | +5. **Environment synchronization** tasks that keep staging or demo environments fresh. |
| 52 | + |
| 53 | +## Constraints and Limitations |
| 54 | + |
| 55 | +- ScheduledTrigger accepts cron expressions supported by `robfig/cron` (standard five-field form). |
| 56 | +- Only string parameters are supported in TriggerTemplates; convert complex data to strings before passing it. |
| 57 | +- Excessive missed ticks are intentionally capped to protect clusters from bursts of backlogged executions. |
| 58 | +- Timezone names must match entries in the TZ database available inside the controller container. |
| 59 | +- ScheduledTrigger focuses on TriggerTemplate execution. For generic Pods without Tekton context, Kubernetes CronJobs may still be preferable. |
| 60 | + |
| 61 | +## How ScheduledTrigger Works |
| 62 | + |
| 63 | +1. **Define the schedule** – provide a cron expression and (optionally) a timezone. The controller evaluates the next firing time based on those values. |
| 64 | +2. **Attach a TriggerTemplate** – reference an existing template or embed one inline. Every tick renders the template with the latest specification, so updates take effect automatically. |
| 65 | +3. **Pass parameters** – use static values or context placeholders. `$(context.date)` resolves to `YYYY-MM-DD`, and `$(context.datetime)` resolves to an RFC3339 timestamp of the scheduled execution. |
| 66 | +4. **Controller execution** – at each tick, the controller creates the resources defined in the TriggerTemplate and records the last schedule time in the resource status. |
| 67 | +5. **Observability** – Kubernetes events report success or failure, enabling standard tooling (kubectl, dashboards) to track scheduled runs. |
| 68 | + |
| 69 | +## Configuration Examples |
| 70 | + |
| 71 | +### Basic ScheduledTrigger |
| 72 | + |
| 73 | +```yaml |
| 74 | +apiVersion: tekton.alaudadevops.io/v1alpha1 |
| 75 | +kind: ScheduledTrigger |
| 76 | +metadata: |
| 77 | + name: nightly-security-scan |
| 78 | + namespace: cicd |
| 79 | +spec: |
| 80 | + schedule: "0 2 * * *" # Every day at 02:00 |
| 81 | + triggerTemplate: |
| 82 | + ref: security-scan-template |
| 83 | + params: |
| 84 | + - name: scan_date |
| 85 | + value: "$(context.date)" |
| 86 | + - name: environment |
| 87 | + value: "production" |
| 88 | +``` |
| 89 | +
|
| 90 | +### Timezone-Aware Schedule |
| 91 | +
|
| 92 | +```yaml |
| 93 | +apiVersion: tekton.alaudadevops.io/v1alpha1 |
| 94 | +kind: ScheduledTrigger |
| 95 | +metadata: |
| 96 | + name: weekly-cleanup |
| 97 | +spec: |
| 98 | + schedule: "30 3 * * 1" # Mondays at 03:30 |
| 99 | + timeZone: "Europe/Paris" |
| 100 | + triggerTemplate: |
| 101 | + ref: cleanup-template |
| 102 | +``` |
| 103 | +
|
| 104 | +### Inline TriggerTemplate |
| 105 | +
|
| 106 | +```yaml |
| 107 | +apiVersion: tekton.alaudadevops.io/v1alpha1 |
| 108 | +kind: ScheduledTrigger |
| 109 | +metadata: |
| 110 | + name: refresh-demo-data |
| 111 | +spec: |
| 112 | + schedule: "0 */6 * * *" # Every 6 hours |
| 113 | + triggerTemplate: |
| 114 | + spec: |
| 115 | + params: |
| 116 | + - name: target_cluster |
| 117 | + default: "demo" |
| 118 | + resourcetemplates: |
| 119 | + - apiVersion: tekton.dev/v1 |
| 120 | + kind: PipelineRun |
| 121 | + metadata: |
| 122 | + generateName: refresh-demo- |
| 123 | + spec: |
| 124 | + pipelineRef: |
| 125 | + name: refresh-pipeline |
| 126 | + params: |
| 127 | + - name: cluster |
| 128 | + value: "$(tt.params.target_cluster)" |
| 129 | +``` |
| 130 | +
|
| 131 | +## Important Parameter Explanations |
| 132 | +
|
| 133 | +### schedule |
| 134 | +
|
| 135 | +Uses the standard cron format `minute hour day-of-month month day-of-week`. The value of this field follows the [Cron](https://en.wikipedia.org/wiki/Cron) syntax. |
| 136 | + |
| 137 | +``` |
| 138 | +# ┌───────────── minute (0 - 59) |
| 139 | +# │ ┌───────────── hour (0 - 23) |
| 140 | +# │ │ ┌───────────── day of the month (1 - 31) |
| 141 | +# │ │ │ ┌───────────── month (1 - 12) |
| 142 | +# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday) |
| 143 | +# │ │ │ │ │ OR sun, mon, tue, wed, thu, fri, sat |
| 144 | +# │ │ │ │ │ |
| 145 | +# │ │ │ │ │ |
| 146 | +# * * * * * |
| 147 | +``` |
| 148 | +
|
| 149 | +For example, `0 3 * * 1` means this task is scheduled to run weekly on a Monday at 3 AM. |
| 150 | +
|
| 151 | +The format also includes extended "Vixie cron" step values. As explained in the |
| 152 | +[FreeBSD manual](https://www.freebsd.org/cgi/man.cgi?crontab%285%29): |
| 153 | +
|
| 154 | +> Step values can be used in conjunction with ranges. Following a range |
| 155 | +> with `/<number>` specifies skips of the number's value through the |
| 156 | +> range. For example, `0-23/2` can be used in the hours field to specify |
| 157 | +> command execution every other hour (the alternative in the V7 standard is |
| 158 | +> `0,2,4,6,8,10,12,14,16,18,20,22`). Steps are also permitted after an |
| 159 | +> asterisk, so if you want to say "every two hours", just use `*/2`. |
| 160 | +
|
| 161 | +A question mark (`?`) in the schedule has the same meaning as an asterisk `*`, that is, |
| 162 | +it stands for any of available value for a given field. |
| 163 | +
|
| 164 | +Other than the standard syntax, some macros like `@monthly` can also be used: |
| 165 | +
|
| 166 | +| Entry | Description | Equivalent to | |
| 167 | +|------------------------|------------------------------------------------------------|---------------| |
| 168 | +| @yearly (or @annually) | Run once a year at midnight of 1 January | 0 0 1 1 * | |
| 169 | +| @monthly | Run once a month at midnight of the first day of the month | 0 0 1 * * | |
| 170 | +| @weekly | Run once a week at midnight on Sunday morning | 0 0 * * 0 | |
| 171 | +| @daily (or @midnight) | Run once a day at midnight | 0 0 * * * | |
| 172 | +| @hourly | Run once an hour at the beginning of the hour | 0 * * * * | |
| 173 | +
|
| 174 | +### timeZone |
| 175 | +
|
| 176 | +For ScheduledTriggers with no time zone specified, the controller interprets schedules relative to its local time zone. |
| 177 | +
|
| 178 | +You can specify a time zone for a ScheduledTrigger by setting `.spec.timeZone` to the name |
| 179 | +of a valid [time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). |
| 180 | +For example, setting `.spec.timeZone: "Etc/UTC"` instructs to interpret |
| 181 | +the schedule relative to Coordinated Universal Time. |
| 182 | +
|
| 183 | +A time zone database from the Go standard library is included in the binaries and used as a fallback in case an external database is not available on the system. |
| 184 | +
|
| 185 | +### params |
| 186 | +
|
| 187 | +Key/value list passed down to the TriggerTemplate. They behave exactly like Tekton Trigger params, so each entry can be used inside the template via `$(tt.params.<name>)`. Combine static values with context placeholders to keep runs self-describing. |
| 188 | +
|
| 189 | +### Context placeholders |
| 190 | +
|
| 191 | +You can use the following context placeholders in `spec.params` |
| 192 | +
|
| 193 | +- `$(context.date)` → `YYYY-MM-DD` |
| 194 | +- `$(context.datetime)` → RFC3339 timestamp, such as `2006-01-02T15:04:05Z` |
| 195 | +
|
| 196 | +Use them for consistent labels, artifact names, or date partitioning regardless of when the controller actually processes the event. |
| 197 | +
|
| 198 | +### triggerTemplate |
| 199 | +
|
| 200 | +Either reference a reusable TriggerTemplate (`ref`) or embed a full template (`spec`). Use references when multiple ScheduledTriggers should share the same behavior; use inline specs for self-contained jobs or when you want all configuration in a single manifest. |
| 201 | +
|
| 202 | +## Reference Materials |
| 203 | +
|
| 204 | +- [TriggerTemplate Documentation](https://tekton.dev/docs/triggers/triggertemplates/) |
| 205 | +- [CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) |
0 commit comments