Send Alerts to ServiceNow
5 minute read
Overview
This guide demonstrates how to create incidents in ServiceNow automatically when EdgeDelta alerts are triggered. ServiceNow is a popular IT Service Management (ITSM) platform used for incident management and workflow automation.
Prerequisites
- ServiceNow Instance: Access to a ServiceNow instance (e.g.,
instance.service-now.com) - ServiceNow Credentials: A user account with permissions to create incidents via the REST API
- Basic Authentication: Encode your credentials in Base64 format:
username:password - EdgeDelta Pipeline: A configured threshold node or monitor generating signals
Pipeline Flow
Configuration
Step 1: Set up Environment Variables
Configure your ServiceNow credentials as environment variables on the EdgeDelta agent:
export SERVICENOW_INSTANCE="your-instance"
export SERVICENOW_CREDENTIALS="base64_encoded_username:password"
To encode credentials in Base64:
echo -n "username:password" | base64
Step 2: Create the Webhook Node
Configure a webhook node that sends alerts to ServiceNow’s Table API:
- name: servicenow_incidents
type: webhook_output
endpoint: https://${SERVICENOW_INSTANCE}.service-now.com/api/now/table/incident
headers:
- header: Content-Type
value: "application/json"
- header: Accept
value: "application/json"
- header: Authorization
value: "Basic ${SERVICENOW_CREDENTIALS}"
suppression_window: 30m
payload: |
{
"short_description": "{{ .item.signal.title }}",
"description": "EdgeDelta Alert Details:\n\nAlert: {{ .item.signal.description }}\n\nAffected System:\n- Host: {{ index .item.resource \"host.name\" }}\n- Source: {{ index .item.resource \"ed.source_name\" }}\n- Source Type: {{ index .item.resource \"ed.source_type\" }}\n\nMetric Information:\n- Metric Name: {{ .item.signal.name }}\n- Current Value: {{ .item.signal.value }}\n- Threshold: {{ .item.signal.threshold_value }}\n- Threshold Type: {{ .item.signal.threshold_type }}\n\nSignal ID: {{ .item.signal.signal_id }}\nTimestamp: {{ .item.timestamp }}",
"urgency": "{{ if gt .item.signal.value .item.signal.threshold_value }}2{{ else }}3{{ end }}",
"impact": "2",
"category": "Infrastructure",
"subcategory": "Monitoring",
"assignment_group": "Infrastructure Team",
"cmdb_ci": "{{ index .item.resource \"host.name\" }}",
"correlation_id": "edgedelta-{{ .item.signal.signal_id }}",
"work_notes": "Automated incident created by EdgeDelta monitoring at {{ .item.timestamp }}. Agent tag: {{ index .item.resource \"ed.tag\" }}"
}
Step 3: Connect to a Threshold Node
Connect this webhook node to a threshold node that triggers based on your monitoring criteria:
nodes:
- name: error_rate_threshold
type: threshold
filter: item.name == "error_rate"
condition: value > 0.05
- name: servicenow_incidents
type: webhook_output
# ... configuration from above ...
links:
- from: error_rate_threshold
to: servicenow_incidents
Incident Payload Reference
The ServiceNow incident payload uses the following key fields:
| Field | Description | EdgeDelta Variable |
|---|---|---|
short_description | Brief incident summary (required) | Alert title |
description | Detailed incident information | Combines multiple alert fields |
urgency | How quickly the incident needs attention (1-3) | Dynamically set based on threshold |
impact | Business impact (1-3) | Fixed or can be dynamic |
category | Incident category | Fixed as “Infrastructure” |
subcategory | More specific categorization | Fixed as “Monitoring” |
assignment_group | Team responsible for resolution | Configure per your organization |
cmdb_ci | Configuration item (affected server/service) | Uses host name |
correlation_id | Unique identifier for deduplication | Uses signal ID with prefix |
work_notes | Internal notes visible to IT staff | Automated creation context |
Dynamic Priority Mapping
Map EdgeDelta alert severity to ServiceNow priority based on how far the metric exceeds its threshold:
payload: |
{
"priority": "{{ if gt .item.signal.value (mul .item.signal.threshold_value 2) }}1{{ else if gt .item.signal.value .item.signal.threshold_value }}2{{ else }}3{{ end }}",
...
}
Priority mapping:
- 1 (Critical): Value exceeds 2x the threshold
- 2 (High): Value exceeds the threshold
- 3 (Moderate): Standard priority
Including Custom Attributes
Include custom attributes from EdgeDelta in the incident. Custom fields in ServiceNow typically start with u_:
payload: |
{
"u_environment": "{{ index .item.attributes \"environment\" | default \"production\" }}",
"u_application": "{{ index .item.attributes \"application\" | default \"unknown\" }}",
"u_region": "{{ index .item.attributes \"region\" | default \"us-east-1\" }}",
...
}
Auto-Resolution
Create a separate webhook to automatically resolve incidents when metrics return to normal. This requires a monitor or threshold configuration that can detect recovery.
- name: servicenow_resolve
type: webhook_output
endpoint: https://${SERVICENOW_INSTANCE}.service-now.com/api/now/table/incident
headers:
- header: Content-Type
value: "application/json"
- header: Authorization
value: "Basic ${SERVICENOW_CREDENTIALS}"
payload: |
{
"correlation_id": "edgedelta-{{ .item.signal.signal_id }}",
"state": "6",
"close_code": "Solved (Permanently)",
"close_notes": "Alert condition resolved automatically at {{ .item.timestamp }}"
}
Note: Auto-resolution requires matching the
correlation_idfrom the original incident. The incident must exist and be in an open state for the update to succeed.
Assignment Routing
Route incidents to different teams based on the alert source:
payload: |
{
"assignment_group": "{{ if contains (index .item.resource \"ed.source_name\") \"database\" }}Database Team{{ else if contains (index .item.resource \"ed.source_name\") \"network\" }}Network Team{{ else }}Infrastructure Team{{ end }}",
...
}
Testing
Test with a Local Endpoint
Before connecting to ServiceNow, test your payload using a local HTTP server:
endpoint: http://localhost:8080/webhook-test
Verify JSON Syntax
Use the EdgeDelta UI to validate your configuration before deployment.
Check ServiceNow Response
Successful incident creation returns the created incident details:
{
"result": {
"sys_id": "abcd1234efgh5678ijkl9012mnop3456",
"number": "INC0001234",
"short_description": "High CPU Usage on prod-server-01",
"state": "1",
"correlation_id": "edgedelta-signal-abc123"
}
}
Troubleshooting
| Issue | Solution |
|---|---|
401 Unauthorized | Verify Base64 encoded credentials and check user permissions |
400 Bad Request | Check JSON syntax and required fields for your ServiceNow instance |
403 Forbidden | User lacks permission to create incidents via API |
| Field not found errors | Custom fields vary by ServiceNow configuration - check your instance’s incident table schema |
| No incident created | Verify suppression window isn’t preventing notifications |
| Duplicate incidents | Use consistent correlation_id values for deduplication |
Common Field Validation Issues
ServiceNow validates field values against configured choices. Common issues include:
- Invalid category/subcategory: Check available values in your instance
- Unknown assignment_group: Verify the group name exists exactly as specified
- Invalid urgency/impact values: Must be 1, 2, or 3
Best Practices
- Use correlation IDs: Prevent duplicate incidents with unique, prefixed signal IDs
- Set appropriate suppression: 30 minutes is typically good for infrastructure alerts
- Include context: Provide enough detail in descriptions for effective troubleshooting
- Test thoroughly: Always test with non-production endpoints first
- Monitor API limits: ServiceNow has rate limits - ensure your alert volume is appropriate
- Use environment variables: Never hardcode credentials in configurations
- Map to CMDB: Use
cmdb_cito link incidents to configuration items for better tracking
See Also
- Webhook Destination - Full webhook reference
- Trigger a Metric Threshold - Configure threshold alerts
- ServiceNow Table API Documentation