Files
attune/docs/examples/rule-parameter-examples.md

14 KiB

Rule Parameter Mapping Examples

This document provides practical, copy-paste ready examples of rule parameter mapping.


Example 1: Static Parameters Only

Use Case: Simple echo with fixed message (included in seed data as core.rule.timer_10s_echo)

Rule:

{
  "ref": "core.rule.timer_10s_echo",
  "pack_ref": "core",
  "trigger_ref": "core.intervaltimer",
  "action_ref": "core.echo",
  "action_params": {
    "message": "hello, world"
  },
  "enabled": true
}

How it works:

  • The rule references the generic core.intervaltimer trigger type
  • A sensor (core.timer_10s_sensor) is configured with {"unit": "seconds", "interval": 10} to fire this trigger every 10 seconds
  • When the sensor fires the trigger, the rule evaluates and executes the core.echo action with the message "hello, world"

Result: Every 10 seconds, the timer sensor fires and the echo action receives the message "hello, world" to print to stdout.

When to use: Fixed notifications, health checks, scheduled tasks with constant parameters.

Note: This example is included in the core pack seed data (scripts/seed_core_pack.sql) and serves as a basic demonstration of rule functionality. The seed script creates both the sensor instance and the rule.


Example 2: Dynamic from Event Payload

Use Case: Alert with error details from event

Event Payload:

{
  "service": "payment-api",
  "error": "Database connection timeout",
  "severity": "critical",
  "timestamp": "2026-01-17T15:30:00Z"
}

Rule:

{
  "ref": "alerts.error_notification",
  "pack_ref": "alerts",
  "trigger_ref": "core.error_event",
  "action_ref": "slack.post_message",
  "action_params": {
    "channel": "#incidents",
    "message": "🚨 Error in {{ event.payload.service }}: {{ event.payload.error }}",
    "severity": "{{ event.payload.severity }}",
    "timestamp": "{{ event.payload.timestamp }}"
  },
  "enabled": true
}

Resolved Parameters:

{
  "channel": "#incidents",
  "message": "🚨 Error in payment-api: Database connection timeout",
  "severity": "critical",
  "timestamp": "2026-01-17T15:30:00Z"
}

When to use: Alerts, notifications, any scenario where event data drives the action.


Example 3: Dynamic from Pack Config

Use Case: API integration with credentials from config

Pack Config:

{
  "ref": "slack",
  "config": {
    "api_token": "xoxb-1234567890-abcdefghijk",
    "default_channel": "#general",
    "bot_name": "Attune Bot"
  }
}

Rule:

{
  "ref": "slack.auto_notify",
  "pack_ref": "slack",
  "trigger_ref": "core.notification_event",
  "action_ref": "slack.post_message",
  "action_params": {
    "token": "{{ pack.config.api_token }}",
    "channel": "{{ pack.config.default_channel }}",
    "username": "{{ pack.config.bot_name }}",
    "message": "Notification triggered"
  },
  "enabled": true
}

Resolved Parameters:

{
  "token": "xoxb-1234567890-abcdefghijk",
  "channel": "#general",
  "username": "Attune Bot",
  "message": "Notification triggered"
}

When to use: API integrations, any action requiring credentials or configuration.


Example 4: Mixed Static and Dynamic

Use Case: GitHub issue creation with mixed parameters

Event Payload:

{
  "error_message": "Memory leak detected",
  "severity": "high",
  "service": "worker-pool",
  "stack_trace": "Error at line 42..."
}

Pack Config:

{
  "ref": "github",
  "config": {
    "token": "ghp_xxxxxxxxxxxx",
    "repo_owner": "myorg",
    "repo_name": "myrepo"
  }
}

Rule:

{
  "ref": "github.create_issue_on_error",
  "pack_ref": "github",
  "trigger_ref": "core.error_event",
  "action_ref": "github.create_issue",
  "action_params": {
    "token": "{{ pack.config.token }}",
    "repo": "{{ pack.config.repo_owner }}/{{ pack.config.repo_name }}",
    "title": "[{{ event.payload.severity }}] {{ event.payload.service }}: {{ event.payload.error_message }}",
    "body": "Error Details:\n\nService: {{ event.payload.service }}\nSeverity: {{ event.payload.severity }}\n\nStack Trace:\n{{ event.payload.stack_trace }}",
    "labels": ["bug", "automated"],
    "assignees": ["oncall"]
  },
  "enabled": true
}

Resolved Parameters:

{
  "token": "ghp_xxxxxxxxxxxx",
  "repo": "myorg/myrepo",
  "title": "[high] worker-pool: Memory leak detected",
  "body": "Error Details:\n\nService: worker-pool\nSeverity: high\n\nStack Trace:\nError at line 42...",
  "labels": ["bug", "automated"],
  "assignees": ["oncall"]
}

When to use: Complex integrations requiring both configuration and event data.


Example 5: Nested Object Access

Use Case: Extract deeply nested values

Event Payload:

{
  "user": {
    "id": 12345,
    "profile": {
      "name": "Alice Smith",
      "email": "alice@example.com",
      "department": "Engineering"
    }
  },
  "action": "login",
  "metadata": {
    "ip": "192.168.1.100",
    "user_agent": "Mozilla/5.0..."
  }
}

Rule:

{
  "ref": "audit.log_user_action",
  "pack_ref": "audit",
  "trigger_ref": "core.user_event",
  "action_ref": "audit.log",
  "action_params": {
    "user_id": "{{ event.payload.user.id }}",
    "user_name": "{{ event.payload.user.profile.name }}",
    "user_email": "{{ event.payload.user.profile.email }}",
    "department": "{{ event.payload.user.profile.department }}",
    "action": "{{ event.payload.action }}",
    "ip_address": "{{ event.payload.metadata.ip }}"
  },
  "enabled": true
}

Resolved Parameters:

{
  "user_id": 12345,
  "user_name": "Alice Smith",
  "user_email": "alice@example.com",
  "department": "Engineering",
  "action": "login",
  "ip_address": "192.168.1.100"
}

When to use: Complex event structures, deeply nested data.


Example 6: Array Access

Use Case: Extract specific array elements

Event Payload:

{
  "errors": [
    "Connection timeout",
    "Retry failed",
    "Circuit breaker open"
  ],
  "tags": ["production", "critical", "api-gateway"]
}

Rule:

{
  "ref": "alerts.first_error",
  "pack_ref": "alerts",
  "trigger_ref": "core.error_event",
  "action_ref": "slack.post_message",
  "action_params": {
    "channel": "#alerts",
    "message": "Primary error: {{ event.payload.errors.0 }}",
    "secondary_error": "{{ event.payload.errors.1 }}",
    "environment": "{{ event.payload.tags.0 }}",
    "severity": "{{ event.payload.tags.1 }}"
  },
  "enabled": true
}

Resolved Parameters:

{
  "channel": "#alerts",
  "message": "Primary error: Connection timeout",
  "secondary_error": "Retry failed",
  "environment": "production",
  "severity": "critical"
}

When to use: Event payloads with arrays where you need specific elements.


Example 7: System Variables

Use Case: Include system-provided metadata

Rule:

{
  "ref": "monitoring.heartbeat",
  "pack_ref": "monitoring",
  "trigger_ref": "core.timer_5m",
  "action_ref": "http.post",
  "action_params": {
    "url": "{{ pack.config.monitoring_url }}",
    "body": {
      "source": "attune",
      "timestamp": "{{ system.timestamp }}",
      "rule_id": "{{ system.rule.id }}",
      "rule_ref": "{{ system.rule.ref }}",
      "event_id": "{{ system.event.id }}",
      "status": "healthy"
    }
  },
  "enabled": true
}

Resolved Parameters (example):

{
  "url": "https://monitoring.example.com/heartbeat",
  "body": {
    "source": "attune",
    "timestamp": "2026-01-17T15:30:00Z",
    "rule_id": 42,
    "rule_ref": "monitoring.heartbeat",
    "event_id": 123,
    "status": "healthy"
  }
}

When to use: Audit trails, logging, debugging, tracking execution context.


Example 8: PagerDuty Integration

Use Case: Trigger PagerDuty incident from metrics

Event Payload:

{
  "metric_name": "cpu_usage",
  "current_value": 95.3,
  "threshold": 80,
  "host": "web-server-01",
  "duration_seconds": 300
}

Pack Config:

{
  "ref": "pagerduty",
  "config": {
    "routing_key": "R123ABC456DEF789",
    "default_severity": "error"
  }
}

Rule:

{
  "ref": "pagerduty.critical_metric",
  "pack_ref": "pagerduty",
  "trigger_ref": "metrics.threshold_exceeded",
  "action_ref": "pagerduty.trigger_incident",
  "action_params": {
    "routing_key": "{{ pack.config.routing_key }}",
    "event_action": "trigger",
    "payload": {
      "summary": "{{ event.payload.metric_name }} exceeded threshold on {{ event.payload.host }}",
      "severity": "critical",
      "source": "{{ event.payload.host }}",
      "custom_details": {
        "metric": "{{ event.payload.metric_name }}",
        "current_value": "{{ event.payload.current_value }}",
        "threshold": "{{ event.payload.threshold }}",
        "duration": "{{ event.payload.duration_seconds }}s"
      }
    },
    "dedup_key": "{{ event.payload.host }}_{{ event.payload.metric_name }}"
  },
  "enabled": true
}

Resolved Parameters:

{
  "routing_key": "R123ABC456DEF789",
  "event_action": "trigger",
  "payload": {
    "summary": "cpu_usage exceeded threshold on web-server-01",
    "severity": "critical",
    "source": "web-server-01",
    "custom_details": {
      "metric": "cpu_usage",
      "current_value": 95.3,
      "threshold": 80,
      "duration": "300s"
    }
  },
  "dedup_key": "web-server-01_cpu_usage"
}

When to use: Incident management, alerting, on-call notifications.


Example 9: Webhook to Multiple Services

Use Case: Fan-out webhook data to multiple channels

Event Payload:

{
  "event_type": "deployment",
  "service": "api-gateway",
  "version": "v2.3.1",
  "environment": "production",
  "deployed_by": "alice@example.com",
  "timestamp": "2026-01-17T15:30:00Z"
}

Pack Config:

{
  "ref": "notifications",
  "config": {
    "slack_channel": "#deployments",
    "slack_token": "xoxb-...",
    "teams_webhook": "https://outlook.office.com/webhook/...",
    "email_recipients": ["team@example.com"]
  }
}

Rule (Slack):

{
  "ref": "notifications.deployment_slack",
  "pack_ref": "notifications",
  "trigger_ref": "webhooks.deployment",
  "action_ref": "slack.post_message",
  "action_params": {
    "token": "{{ pack.config.slack_token }}",
    "channel": "{{ pack.config.slack_channel }}",
    "message": "✅ Deployment Complete",
    "attachments": [
      {
        "color": "good",
        "fields": [
          {
            "title": "Service",
            "value": "{{ event.payload.service }}",
            "short": true
          },
          {
            "title": "Version",
            "value": "{{ event.payload.version }}",
            "short": true
          },
          {
            "title": "Environment",
            "value": "{{ event.payload.environment }}",
            "short": true
          },
          {
            "title": "Deployed By",
            "value": "{{ event.payload.deployed_by }}",
            "short": true
          }
        ],
        "footer": "Attune Automation",
        "ts": "{{ event.payload.timestamp }}"
      }
    ]
  },
  "enabled": true
}

When to use: Multi-channel notifications, deployment tracking, audit trails.


Example 10: Conditional Channels (Future with Filters)

Use Case: Route to different channels based on severity

Event Payload:

{
  "severity": "critical",
  "message": "Database unreachable"
}

Rule (Future Enhancement with Filters):

{
  "ref": "alerts.smart_routing",
  "pack_ref": "alerts",
  "trigger_ref": "core.alert_event",
  "action_ref": "slack.post_message",
  "action_params": {
    "channel": "{{ event.payload.severity | default: 'info' | map: {'critical': '#incidents', 'high': '#alerts', 'medium': '#monitoring', 'low': '#logs'} }}",
    "message": "{{ event.payload.message }}",
    "color": "{{ event.payload.severity | map: {'critical': 'danger', 'high': 'warning', 'medium': 'good', 'low': '#cccccc'} }}"
  },
  "enabled": true
}

Note: This uses advanced filter syntax not yet implemented (Phase 2).


Testing Your Rules

1. Create a Test Event

curl -X POST http://localhost:8080/api/v1/events \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "trigger_ref": "core.error_event",
    "payload": {
      "service": "test-service",
      "error": "Test error message",
      "severity": "info"
    }
  }'

2. Check Enforcement

curl -X GET http://localhost:8080/api/v1/enforcements?limit=1 \
  -H "Authorization: Bearer $TOKEN"

Look at the config field to verify parameters were resolved correctly.

3. Check Execution

curl -X GET http://localhost:8080/api/v1/executions?limit=1 \
  -H "Authorization: Bearer $TOKEN"

The config field should contain the same resolved parameters.


Common Patterns

API Authentication

{
  "action_params": {
    "url": "{{ pack.config.api_url }}",
    "headers": {
      "Authorization": "Bearer {{ pack.config.api_token }}",
      "Content-Type": "application/json"
    }
  }
}

Error Context

{
  "action_params": {
    "summary": "Error: {{ event.payload.message }}",
    "details": {
      "service": "{{ event.payload.service }}",
      "host": "{{ event.payload.host }}",
      "timestamp": "{{ event.payload.timestamp }}",
      "stack_trace": "{{ event.payload.stack_trace }}"
    }
  }
}

User Information

{
  "action_params": {
    "user": {
      "id": "{{ event.payload.user.id }}",
      "name": "{{ event.payload.user.name }}",
      "email": "{{ event.payload.user.email }}"
    },
    "action": "{{ event.payload.action_type }}"
  }
}

Tips and Best Practices

  1. Use pack config for secrets - Never hardcode API keys in rules
  2. Provide context - Include relevant fields from event payload
  3. Keep templates simple - Deeply nested access can be fragile
  4. Test with sample events - Verify your templates work before production
  5. Use descriptive field names - Make it clear what each parameter is for
  6. Document your rules - Use clear labels and descriptions


Need Help?

If your templates aren't resolving correctly:

  1. Check the event payload structure in the database
  2. Verify the pack config exists and has the expected fields
  3. Review sensor service logs for template resolution warnings
  4. Test with a simple template first, then add complexity
  5. Ensure field names match exactly (case-sensitive)