ops0ops0

Workflow Triggers

Configure when and how workflows run. Workflows can have multiple triggers active simultaneously.

Trigger Types

Manual
User clicks Run button
Scheduled
Cron expression
Webhook
HTTP POST request
Git Push
Repository changes
Incident
Kubernetes incidents
Workflow
Chain workflows

Manual Trigger

Always enabled. Users can run workflows on-demand.

FieldDescription
Require InputsPrompt for variables when running
Input SchemaDefine 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.

FieldRequiredDescription
ScheduleYesCron expression
TimezoneYesSchedule timezone
VariablesNoFixed variables

Cron Format

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

Common Schedules

ScheduleCronDescription
Every hour0 * * * *At minute 0
Daily at 2am0 2 * * *2:00 AM
Every Monday0 0 * * 1Monday midnight
Every 15 min*/15 * * * *Quarter hour
Weekdays 9am0 9 * * 1-5Mon-Fri

Webhook Trigger

Trigger workflows via HTTP POST requests from external systems like GitHub Actions, GitLab CI, monitoring tools, or custom applications.

FieldDescription
URLAuto-created webhook endpoint
SecretAuthentication token for request validation
Payload MappingMap JSON fields to workflow variables
IP WhitelistOptional IP restriction for security

Creating Webhook URL

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.

Secret Rotation

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 PathWorkflow Variable Name
$.versionversion
$.environmentenv
$.commit.shacommit_sha
$.commit.authorauthor
$.build.idbuild_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:

ServiceIP Ranges
GitHub ActionsGitHub Meta API - actions field
GitLab CIGitLab IP ranges
JenkinsYour Jenkins server IP
CircleCICircleCI 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

Secret Storage

Store webhook secret in GitHub Secrets, GitLab CI/CD Variables, or environment variable manager. Never commit secrets to version control.

Use HTTPS Only

ops0 webhooks are HTTPS-only. Never use HTTP webhook endpoints (not supported).

Validate Payload

Use payload mapping to validate required fields. Workflow fails if mapped fields are missing from payload.

IP Whitelist

Enable IP whitelisting for production webhooks to prevent unauthorized trigger attempts.

Webhook Logs

View webhook request history and debug failed requests:

Webhook Log Columns:

ColumnDescription
TimestampWhen request received
Source IPCaller IP address
StatusSuccess, Auth Failed, or Error
Payload SizeRequest body size
Execution IDTriggered 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:

  1. Add webhook secret to GitHub repository secrets as OPS0_WEBHOOK_SECRET
  2. Configure payload mapping in ops0 workflow
  3. Push to main branch triggers deployment

Troubleshooting Webhooks

Webhook Not Triggering

Check: Webhook trigger enabled, correct URL, valid secret, IP not blocked.


Fix: Review webhook logs for error details. Test with curl command.

401 Unauthorized

Cause: Invalid or missing X-Webhook-Secret header.


Fix: Copy current secret from workflow settings. Update calling system.

403 Forbidden

Cause: IP whitelist enabled and caller IP not allowed.


Fix: Add caller IP to whitelist or disable IP restriction.

Workflow Fails After Trigger

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.

FieldRequiredDescription
RepositoryYesGitHub repository
Branch FilterNoBranches to match
Path FilterNoFile paths to match
EventsYespush, pull_request, merge

Branch Filters

PatternMatches
mainOnly main branch
release/*Any release branch
feature/**Nested feature branches

Path Filters

PatternMatches
terraform/**All Terraform files
*.tfRoot .tf files
!*.mdExclude markdown

Available Variables

VariableDescription
${trigger.branch}Branch name
${trigger.commit}Commit SHA
${trigger.author}Commit author
${trigger.message}Commit message

Incident Trigger

Trigger on Kubernetes incidents.

FieldRequiredDescription
ClustersYesWhich clusters
SeverityNoMinimum severity
TypesNoIncident types

Incident Types

TypeDescription
CrashLoopBackOffContainer crashing
OOMKilledOut of memory
ImagePullBackOffImage pull failure
NodeNotReadyNode unhealthy

Available Variables

VariableDescription
${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.

FieldRequiredDescription
Source WorkflowYesWhich workflow
On StatusYessuccess, failed, any

Chain Workflows

Workflow A (Deploy)
    │
    ▼ on success
Workflow B (Test)
    │
    ▼ on success
Workflow C (Notify)

Available Variables

VariableDescription
${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

StepAction
1Get pod details via Script
2Restart deployment via kubectl
3Wait 60 seconds
4Check health via HTTP
5Notify 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