Workflow Triggers
Configure when and how workflows run. Workflows can have multiple triggers active simultaneously.
Trigger Types
Manual Trigger
Always enabled. Users can run workflows on-demand.
| Field | Description |
|---|---|
| Require Inputs | Prompt for variables when running |
| Input Schema | Define input fields |
Input Schema Example:
{
"environment": {
"type": "select",
"required": true,
"options": ["dev", "staging", "prod"]
},
"version": {
"type": "string",
"required": true
}
}
Scheduled Trigger
Run workflows on a schedule using cron expressions.
| Field | Required | Description |
|---|---|---|
| Schedule | Yes | Cron expression |
| Timezone | Yes | Schedule timezone |
| Variables | No | Fixed variables |
Cron Format
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6)
│ │ │ │ │
* * * * *
Common Schedules
| Schedule | Cron | Description |
|---|---|---|
| Every hour | 0 * * * * | At minute 0 |
| Daily at 2am | 0 2 * * * | 2:00 AM |
| Every Monday | 0 0 * * 1 | Monday midnight |
| Every 15 min | */15 * * * * | Quarter hour |
| Weekdays 9am | 0 9 * * 1-5 | Mon-Fri |
Webhook Trigger
Trigger workflows via HTTP POST requests from external systems like GitHub Actions, GitLab CI, monitoring tools, or custom applications.
| Field | Description |
|---|---|
| URL | Auto-created webhook endpoint |
| Secret | Authentication token for request validation |
| Payload Mapping | Map JSON fields to workflow variables |
| IP Whitelist | Optional IP restriction for security |
Creating Webhook URL
Navigate to Workflow Settings
Open your workflow and click Triggers tab.
Enable Webhook Trigger
Toggle "Webhook" trigger on.
Copy Webhook URL
ops0 provides a unique endpoint:
https://api.ops0.io/webhooks/wf_abc123def456/trigger
Copy Secret Token
Secret automatically created for authentication:
whsec_abc123def456ghi789jkl012mno345
URL Format:
wf_abc123def456- Workflow-specific identifier- URL is unique per workflow
- URL remains same unless regenerated
Regenerating Webhook Secret
Rotate secret token for security:
Open Webhook Settings
Navigate to workflow triggers configuration.
Click "Regenerate Secret"
Creates a new random secret token.
Update External Systems
Replace old secret in all calling systems (GitHub, GitLab, etc.).
Test New Secret
Verify webhook calls work with new secret.
Old secret stops working immediately after regeneration. Update all webhook callers before regenerating to avoid failed triggers.
When to Regenerate:
- Secret exposed or committed to version control
- Employee departure (secret access removal)
- Regular security rotation (quarterly recommended)
- Suspected unauthorized access
Authentication
All webhook requests must include secret token in header:
Required Header:
X-Webhook-Secret: whsec_abc123def456ghi789jkl012mno345
Example Request:
curl -X POST \
-H "X-Webhook-Secret: whsec_abc123def456ghi789jkl012mno345" \
-H "Content-Type: application/json" \
-d '{"version": "1.2.3", "environment": "prod"}' \
https://api.ops0.io/webhooks/wf_abc123def456/trigger
Response (Success):
{
"status": "triggered",
"workflow_id": "wf_abc123def456",
"execution_id": "exec_xyz789",
"message": "Workflow started successfully"
}
Response (Failed Auth):
{
"status": "error",
"code": "INVALID_SECRET",
"message": "Webhook secret is invalid"
}
Payload Mapping
Map JSON fields from webhook payload to workflow variables:
Incoming Payload:
{
"version": "1.2.3",
"environment": "production",
"commit": {
"sha": "a1b2c3d4",
"author": "john@company.com",
"message": "Fix critical bug"
},
"build": {
"id": "12345",
"status": "success"
}
}
Payload Mapping Configuration:
| JSON Path | Workflow Variable Name |
|---|---|
$.version | version |
$.environment | env |
$.commit.sha | commit_sha |
$.commit.author | author |
$.build.id | build_id |
Access in Workflow Steps:
steps:
- name: deploy
run: |
echo "Deploying version ${trigger.payload.version}"
echo "To environment: ${trigger.payload.env}"
echo "Commit: ${trigger.payload.commit_sha}"
echo "Build: ${trigger.payload.build_id}"
IP Whitelisting
Restrict webhook calls to specific IP addresses:
Enable IP Whitelist
In webhook settings, toggle "Restrict by IP".
Add Allowed IPs
Enter CIDR blocks:
192.168.1.0/24
203.0.113.50/32
Save Configuration
Requests from other IPs will be rejected with 403.
Common IP Ranges:
| Service | IP Ranges |
|---|---|
| GitHub Actions | GitHub Meta API - actions field |
| GitLab CI | GitLab IP ranges |
| Jenkins | Your Jenkins server IP |
| CircleCI | CircleCI IPs |
Testing Webhooks
Test webhook integration before deploying:
Use Test Button
In webhook settings, click Test Webhook.
Provide Sample Payload
Enter JSON payload to test:
{
"version": "1.0.0-test",
"environment": "staging"
}
Review Execution
Workflow starts with test payload. Check execution logs.
Verify Variable Mapping
Confirm variables populated correctly from payload.
Command-Line Testing:
# Test from terminal
curl -X POST \
-H "X-Webhook-Secret: your_secret_here" \
-H "Content-Type: application/json" \
-d '{"version": "test", "environment": "dev"}' \
https://api.ops0.io/webhooks/wf_abc123/trigger
# Expected response
{"status":"triggered","execution_id":"exec_test123"}
Webhook Security Best Practices
Store webhook secret in GitHub Secrets, GitLab CI/CD Variables, or environment variable manager. Never commit secrets to version control.
ops0 webhooks are HTTPS-only. Never use HTTP webhook endpoints (not supported).
Use payload mapping to validate required fields. Workflow fails if mapped fields are missing from payload.
Enable IP whitelisting for production webhooks to prevent unauthorized trigger attempts.
Webhook Logs
View webhook request history and debug failed requests:
Webhook Log Columns:
| Column | Description |
|---|---|
| Timestamp | When request received |
| Source IP | Caller IP address |
| Status | Success, Auth Failed, or Error |
| Payload Size | Request body size |
| Execution ID | Triggered workflow execution (if successful) |
Failed Request Details:
Webhook Request Failed
─────────────────────────────────────
Time: 2024-01-15 14:30:22 UTC
Source IP: 203.0.113.45
Status: 401 Unauthorized
Reason: Invalid webhook secret
Payload: {"version": "1.2.3", ...}
Expected secret header:
X-Webhook-Secret: whsec_...
Received header:
X-Webhook-Secret: old_secret_123
Integrating with GitHub Actions
GitHub Workflow Example:
name: Trigger ops0 Deployment
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Trigger ops0 Workflow
run: |
curl -X POST \
-H "X-Webhook-Secret: ${{ secrets.OPS0_WEBHOOK_SECRET }}" \
-H "Content-Type: application/json" \
-d '{
"version": "${{ github.sha }}",
"environment": "production",
"commit": {
"sha": "${{ github.sha }}",
"author": "${{ github.actor }}",
"message": "${{ github.event.head_commit.message }}"
}
}' \
https://api.ops0.io/webhooks/wf_abc123/trigger
Setup:
- Add webhook secret to GitHub repository secrets as
OPS0_WEBHOOK_SECRET - Configure payload mapping in ops0 workflow
- Push to
mainbranch triggers deployment
Troubleshooting Webhooks
Check: Webhook trigger enabled, correct URL, valid secret, IP not blocked.
Fix: Review webhook logs for error details. Test with curl command.
Cause: Invalid or missing X-Webhook-Secret header.
Fix: Copy current secret from workflow settings. Update calling system.
Cause: IP whitelist enabled and caller IP not allowed.
Fix: Add caller IP to whitelist or disable IP restriction.
Cause: Payload mapping missing required fields or workflow step error.
Fix: Check execution logs. Verify payload structure matches mapping configuration.
Git Push Trigger
Trigger on repository changes.
| Field | Required | Description |
|---|---|---|
| Repository | Yes | GitHub repository |
| Branch Filter | No | Branches to match |
| Path Filter | No | File paths to match |
| Events | Yes | push, pull_request, merge |
Branch Filters
| Pattern | Matches |
|---|---|
main | Only main branch |
release/* | Any release branch |
feature/** | Nested feature branches |
Path Filters
| Pattern | Matches |
|---|---|
terraform/** | All Terraform files |
*.tf | Root .tf files |
!*.md | Exclude markdown |
Available Variables
| Variable | Description |
|---|---|
${trigger.branch} | Branch name |
${trigger.commit} | Commit SHA |
${trigger.author} | Commit author |
${trigger.message} | Commit message |
Incident Trigger
Trigger on Kubernetes incidents.
| Field | Required | Description |
|---|---|---|
| Clusters | Yes | Which clusters |
| Severity | No | Minimum severity |
| Types | No | Incident types |
Incident Types
| Type | Description |
|---|---|
| CrashLoopBackOff | Container crashing |
| OOMKilled | Out of memory |
| ImagePullBackOff | Image pull failure |
| NodeNotReady | Node unhealthy |
Available Variables
| Variable | Description |
|---|---|
${trigger.incident_id} | Incident ID |
${trigger.type} | Incident type |
${trigger.severity} | Severity level |
${trigger.cluster} | Cluster name |
${trigger.pod} | Pod name |
Workflow Trigger
Trigger when another workflow completes.
| Field | Required | Description |
|---|---|---|
| Source Workflow | Yes | Which workflow |
| On Status | Yes | success, failed, any |
Chain Workflows
Workflow A (Deploy)
│
▼ on success
Workflow B (Test)
│
▼ on success
Workflow C (Notify)
Available Variables
| Variable | Description |
|---|---|
${trigger.source_workflow} | Source workflow name |
${trigger.source_run_id} | Source execution ID |
${trigger.status} | How it completed |
${trigger.outputs} | Source outputs |
Multiple Triggers
Workflows can have multiple active triggers:
Workflow: production-deploy
─────────────────────────────────────
Triggers:
✓ Manual
✓ Scheduled: 0 2 * * * (daily 2am)
✓ Git Push: main branch
○ Webhook (disabled)
Example: GitOps Workflow
Trigger Configuration
Trigger: Git Push
Repository: acme/infrastructure
Branch: main
Path Filter: terraform/**
Events: push
Workflow
┌─────────┐ ┌──────────┐ ┌─────────┐ ┌────────┐
│ Plan │───▶│ Approval │───▶│ Apply │───▶│ Notify │
└─────────┘ └──────────┘ └─────────┘ └────────┘
Git Push Event
Repository: acme/infrastructure
Branch: main
Commit: a1b2c3d
Author: jane@example.com
Message: "Add new RDS instance"
Files:
- terraform/rds.tf (modified)
- terraform/variables.tf (modified)
Execution
Workflow: infrastructure-deploy
Run ID: wfr_xyz789
Status: Running
Triggered By: Git Push
Branch: main
Commit: a1b2c3d
Author: jane@example.com
Steps:
1. Plan ▶ Running
2. Approval ○ Pending
3. Apply ○ Pending
4. Notify ○ Pending
Example: Scheduled Backup
Trigger Configuration
Trigger: Scheduled
Cron: 0 3 * * *
Timezone: America/New_York
Variables:
backup_type: full
retention_days: 30
Next Runs
Schedule: Daily at 3:00 AM EST
─────────────────────────────────────
Next 5 runs:
1. Tomorrow 3:00 AM
2. Wed Jan 8 3:00 AM
3. Thu Jan 9 3:00 AM
4. Fri Jan 10 3:00 AM
5. Sat Jan 11 3:00 AM
Example: Incident Auto-Response
Trigger Configuration
Trigger: Incident
Clusters: production-eks
Severity: Critical, High
Types: OOMKilled, CrashLoopBackOff
Workflow Steps
| Step | Action |
|---|---|
| 1 | Get pod details via Script |
| 2 | Restart deployment via kubectl |
| 3 | Wait 60 seconds |
| 4 | Check health via HTTP |
| 5 | Notify via Slack |
Incident Event
Incident: INC-2024-0147
Type: OOMKilled
Severity: Critical
Cluster: production-eks
Namespace: api
Pod: api-gateway-7d9f8c6b4d-2xkjp
Triggered Workflow: incident-response
Run ID: wfr_inc147