Flux CD Flux CD

Send Alerts and Receive Webhooks with Flux Notifications

Get Slack alerts for reconciliation events and trigger instant syncs from Git pushes.

12 min Intermediate

Flux reports what it does through Kubernetes events, and the notification controller turns those into alerts and also receives webhooks. This guide sets up two things: outbound alerts to a chat tool when something fails or succeeds, and an inbound webhook that makes Flux reconcile right after a push instead of waiting for the next poll. Slack is the example, but the same objects work with Microsoft Teams, PagerDuty, Discord, generic webhooks, and others, and Git providers such as GitHub and GitLab for commit status.

Send alerts to Slack

Three objects are involved: a Secret with the webhook address, a Provider describing where to send, and an Alert describing what to send.

Create the Secret (the key must be address):

kubectl create secret generic slack-url \
  --namespace=flux-system \
  --from-literal=address=https://hooks.slack.com/services/XXX/YYY/ZZZ

apps/notifications/provider.yaml:

apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
  name: slack
  namespace: flux-system
spec:
  type: slack
  channel: deployments
  secretRef:
    name: slack-url

apps/notifications/alert.yaml:

apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
  name: on-call
  namespace: flux-system
spec:
  providerRef:
    name: slack
  eventSeverity: error
  eventSources:
    - kind: GitRepository
      name: "*"
    - kind: Kustomization
      name: "*"
    - kind: HelmRelease
      name: "*"
      namespace: podinfo

The parts that matter:

  • providerRef picks the destination.
  • eventSeverity is info (everything, including successful applies) or error. Use error for a quiet on-call channel and info for a deployment log.
  • eventSources lists which objects to watch. A name of "*" matches all objects of that kind in the namespace, so use namespace: to watch other namespaces.

The notification API versions are changing. v1beta2 was removed in Flux 2.9, so use v1beta3 as shown if you run Flux 2.9, and the v1 API is planned for Flux 2.10. Check what your cluster supports with:

kubectl get crd alerts.notification.toolkit.fluxcd.io \
  -o jsonpath='{.spec.versions[*].name}'; echo

Commit these files, and when something fails in a Kustomization, a message appears in the channel with the object, the revision, and the error. Test it by breaking a manifest path in Git on purpose.

Report commit status back to GitHub

A second Provider can post the result of a deployment as a commit status, so a pull request or commit shows whether Flux applied it:

apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
  name: github-status
  namespace: flux-system
spec:
  type: github
  address: https://github.com/your-org/fleet-infra
  secretRef:
    name: github-token   # a Secret with a "token" key

Pair it with an Alert that lists the Kustomization as its source. The token needs permission to write commit statuses.

Receive webhooks for instant sync

By default Flux polls Git on the GitRepository interval. A Receiver accepts webhooks from your Git host and triggers a reconcile immediately, so you can lengthen the polling interval and still get near-instant deployments.

Create a shared secret token (the key must be token):

TOKEN=$(head -c 12 /dev/urandom | shasum | cut -d ' ' -f1)
echo $TOKEN
kubectl create secret generic webhook-token \
  --namespace=flux-system --from-literal=token=$TOKEN

Then the Receiver, using the stable v1 API:

apiVersion: notification.toolkit.fluxcd.io/v1
kind: Receiver
metadata:
  name: github-receiver
  namespace: flux-system
spec:
  type: github
  events:
    - ping
    - push
  secretRef:
    name: webhook-token
  resources:
    - apiVersion: source.toolkit.fluxcd.io/v1
      kind: GitRepository
      name: flux-system

Once it’s applied, ask Flux for the path it generated:

flux get receivers

The path looks like /hook/<hash>. The notification controller exposes it through a Service named webhook-receiver in flux-system, which you publish to the internet through an Ingress or LoadBalancer. Then, in your repository’s settings, add a webhook with that URL, content type application/json, your token as the secret, and the push event. A push now triggers a reconcile of the GitRepository and everything that depends on it. Flux 2.9 also supports OIDC-secured generic Receivers that don’t need a shared secret, for platforms that can present an OIDC token.

Troubleshooting

  • No messages arrive: check kubectl describe alert on-call -n flux-system and the controller logs with flux logs --level=error, and verify the Secret key is named address.
  • Webhook doesn’t trigger: look at the delivery log in your Git host. A 404 usually means the path is wrong, and a 401 or 403 means the token doesn’t match.
  • Too noisy: tighten eventSeverity and list specific eventSources instead of "*".

Popular Guides