generic, which posts each event to Flashduty as JSON. Each Flux object maps to one Flashduty alert: it triggers when reconciliation fails (an error event) and closes automatically when the object later sends a success info event.
In Flashduty On-call
You can get the integration push URL in either of the following ways.
Use a dedicated integration
- In the Flashduty console, select Channel and open a channel
- Select Configuration → Integrations → Private integration, then click Add an integration
- Select Flux CD and click Save
- Open the new integration card and copy the Push URL
Use a shared integration
- In the Flashduty console, select Integration Center → Alert Events
- Select Flux CD and enter an integration name
- Configure the default route and select a channel. You can add more rules under Routes after creation
- Click Save and copy the generated Push URL
Configure Flux
You need
kubectl permissions to create a Secret and the Flux Provider and Alert objects in the cluster. The examples use the notification.toolkit.fluxcd.io/v1beta3 API and the flux-system namespace; the Provider, Alert, and Secret must be in the same namespace. The cluster must be able to reach the domain of the Flashduty push URL.
1
Store the push URL in a Secret
The When the Secret has an
integration_key in the push URL works like a password, so keep the URL under the address key of a Secret instead of writing it into the Provider:address key, Flux uses it as the Provider’s address.2
Create the Provider
type must be generic. Do not use the pagerduty type: it keeps only the scheme and host of the address and drops the integration_key parameter.3
Create the Alert
- Set
eventSeveritytoinfo(or leave it out): Flux then forwards botherrorandinfoevents, and Flashduty uses theinfoevents to close alerts. Witherror, alerts do not recover automatically; see Alert lifecycle - An
eventSourcesentry withoutnamespacematches only objects in the Alert’s namespace. For Flux objects in other namespaces, add a set of entries withnamespacefor each namespace, or create an Alert in that namespace - Keys in
eventMetadataappear as alert labels. Set at least the cluster name so you can tell alerts from different clusters apart
kubectl apply -f, then run kubectl -n flux-system get providers,alerts to confirm both exist.4
Verify the lifecycle
Flux has no button that sends a test message. Use a temporary Kustomization instead:
- Create a Kustomization whose
spec.pathpoints to a directory that does not exist in the Git repository (use an existing GitRepository as its source). Wait for reconciliation to fail, and confirm that Flashduty receives an alert with a title likeKustomization flux-system/<name>: ArtifactFailedand a description starting withkustomization path not found: ... - Change
spec.pathto a directory that exists and runflux reconcile kustomization <name>. Confirm the alert closes once reconciliation succeeds - Delete the temporary Kustomization
Alert Key
Flashduty uses
involvedObject.uid, the Kubernetes UID of the Flux object, as the Alert Key. Flux’s own pagerduty Provider uses the same UID as the deduplication key for both trigger and resolve. All failure events of one Flux object land on the same Flashduty alert; changes to the failure reason (reason), message, or revision do not change the Alert Key.
- An object deleted and recreated with the same name gets a new UID and a new alert
- Deleting a Flux object does not always send a success event; close any alert still active after the object is deleted by hand
involvedObject.uid.
Alert lifecycle
Flashduty handles each event by its
severity and reason fields:
These are the rules of Flux’s
pagerduty Provider: error triggers, other events resolve, Progressing is skipped. Flux forwards only info and error events; any other severity value is rejected.
By default, Flux pushes an event for the same object with the same message and metadata at most once every 5 minutes.
When only error events are forwarded: if the Alert’s eventSeverity is error, or its exclusionList filters out success events, Flashduty receives no recovery events and alerts never close on their own. In that case, turn on the channel’s auto-resolve timeout with Incident trigger as the timing start. A timeout of 12 hours is a reasonable default: if the object is still failing, the next failed reconciliation triggers the alert again.
Severity
Flux failure events have a single level,
error, so all alerts default to Critical. For a different severity, append &severity=Warning (or Info) to the push URL. A recovery event keeps the severity of the original alert.
Alert content
- Title:
<Kind> <namespace>/<name>: <reason>, for exampleKustomization apps/webapp: ValidationFailed - Description: the event
message - Labels:
resource(<Kind>/<namespace>/<name>),kind,namespace,name,uid,api_version,reason,vendor_severity(errororinfo),reporting_controller(the controller that sent the event, for examplekustomize-controller), plus the keys in the eventmetadata(for examplerevision, andclusterfrom the Alert’seventMetadata)
metadata key names, characters other than a-z, A-Z, 0-9, and _ are replaced with _ (for example, kustomize.toolkit.fluxcd.io/revision sent by older Flux versions becomes kustomize_toolkit_fluxcd_io_revision). A key with the same name as a built-in label does not overwrite it. Empty values are not written as labels.
Troubleshooting
- No alerts arrive: run
kubectl -n flux-system logs deploy/notification-controllerand look for errors such asfailed to dispatch notification; runkubectl -n flux-system get events --field-selector involvedObject.kind=Alertto see warnings recorded on the Alert - Alerts arrive for only some objects: check that the object’s
kindis listed ineventSources, and that the object is in the Alert’s namespace or the entry setsnamespace - Alerts do not recover: check that the Alert’s
eventSeverityisinfoor unset, and thatexclusionListdoes not filter out success events - Requests are rejected: check that the Provider’s
typeisgenericand thataddressin the Secret is the full push URL, including theintegration_keyparameter