Icinga 2
Configure Icinga 2 notification objects with exact OpsKnight lifecycle, correlation, and security behavior
Send Icinga 2 host and service notifications to an OpsKnight service. The adapter handles problem, recovery, acknowledgment, downtime, flapping, and custom types using stable host/service correlation.
Create the OpsKnight integration
- Open Services, select the service, and open Integrations.
- Add Icinga and copy the complete URL:
https://OPSKNIGHT_HOST/api/integrations/icinga?integrationId=INTEGRATION_ID&integrationKey=INTEGRATION_KEY
Treat the URL as a credential. Prefer a restricted constants/zone file or a root-owned notification wrapper over duplicating it in broadly readable configuration.
Define the notification command
This service-notification command generates JSON with Icinga's encoder rather than interpolating check output into raw JSON:
object NotificationCommand "opsknight-service-notification" {
command = [
"/usr/bin/curl",
"--fail-with-body",
"--silent",
"--show-error",
"--request", "POST",
"--header", "Content-Type: application/json",
"--data-binary", "$opsknight_payload$",
"$opsknight_url$"
]
vars.opsknight_url = "https://OPSKNIGHT_HOST/api/integrations/icinga?integrationId=INTEGRATION_ID&integrationKey=INTEGRATION_KEY"
vars.opsknight_payload = {{
return Json.encode({
notification_type = macro("$notification.type$")
host_name = macro("$host.name$")
host_state = macro("$host.state$")
service_name = macro("$service.name$")
service_state = macro("$service.state$")
service_output = macro("$service.output$")
check_command = macro("$service.check_command$")
author = macro("$notification.author$")
comment = macro("$notification.comment$")
})
}}
}
Use the corresponding host macros in a separate host NotificationCommand and omit service fields. A host and one of its services intentionally use different keys.
Apply notifications
Example service assignment:
apply Notification "opsknight-service" to Service {
command = "opsknight-service-notification"
period = "24x7"
states = [ OK, Warning, Critical, Unknown ]
types = [ Problem, Recovery, Acknowledgement, Custom ]
users = [ "opsknight-notification-user" ]
assign where service.vars.opsknight == true
}
Use your existing user/group and notification-zone conventions. Restrict the assignment with an explicit custom variable or group; do not accidentally forward every test and development service to a production OpsKnight service.
Validate before reloading:
sudo icinga2 daemon --validate
sudo systemctl reload icinga2
Action and severity contract
| Icinga notification/state | OpsKnight action |
|---|---|
Type contains RECOVERY |
Resolve |
Type contains ACK, ACKNOWLEDGEMENT, DOWNTIME, FLAPPING, or CUSTOM |
Acknowledge an existing match |
Service state OK |
Resolve |
Host state UP with no service state |
Resolve |
| Every other problem state | Trigger |
Critical service or down host maps to critical; warning service maps to warning; unknown service or unreachable host maps to error; recovery maps to info. Service urgency rules still control final incident urgency.
Downtime/flapping messages acknowledge rather than suppress or create. If no matching incident exists, no new incident is opened by the acknowledge event.
Correlation
- Service key:
icinga-<normalized-host>-<normalized-service> - Host key:
icinga-<normalized-host>
Whitespace becomes hyphens, values are lowercased, and each part is capped at 100 characters. Use stable object names; display-name or object-name changes between problem and recovery can leave the old incident open.
Request security
OpsKnight validates the integration key. An optional signing secret requires an unprefixed HMAC-SHA256 of the exact raw body in X-Signature or X-Webhook-Signature.
The command above does not sign. Leave the signing secret unset for that direct configuration, or call a restricted wrapper that signs the encoded body before sending. Require HTTPS and limit who can read or edit the URL.
Validate end to end
- Validate and reload the Icinga configuration.
- Force a disposable service into a hard critical state and confirm the command receives HTTP
202. - Confirm one incident appears with the expected host/service key.
- Acknowledge in Icinga and confirm the same OpsKnight incident acknowledges.
- Restore the service and confirm recovery resolves it.
- Test an actual OpsKnight page through the intended escalation and notification provider.
Troubleshooting
Configuration validation fails
Resolve syntax, zone, object, and variable-scope errors before reload. Compare the command shape with the Icinga version deployed in your environment.
The incident uses unknown-host
Inspect the rendered payload. Use one of the supported host fields: host_name, hostName, host, or host_display_name.
Recovery does not match
Confirm trigger/recovery render the same host and service names, and recovery type/state is present. A missing service name changes the key to host-only.
Curl returns a non-2xx response
Inspect --fail-with-body output: 401 means key/signature failure, 400 means invalid JSON/schema, and 429 means the integration limit was exceeded.
Related topics
Last updated for v1.4
Edit this page on GitHub