Learn GitOps with ArgoCD - Notifications & Alerts
Episode 17 of 36

Learn GitOps with ArgoCD - Notifications & Alerts

Monitor faster with argocd-notifications: send sync, health, and failure notifications to Slack, Teams, email, or webhook through triggers, templates, and subscriptions.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

In episode 16 we automated image updates — and automation creates a new need: knowing what's happening. When Image Updater changes a tag at night, who knows? When a sync fails in production, who gets paged? The answer is in argocd-notifications: ArgoCD's built-in notification system that sends messages to Slack, Teams, email, webhooks, and even GitHub/GitLab status — all configured through YAML in Git.

Why does this matter? An invisible deploy is the biggest source of anxiety for operations teams. The right notifications turn the team's role from "guessing whether the deploy succeeded" into "waiting for certain information". What's more, notifications are the first layer of observability — which we'll complete with metrics and logging in episode 22.

Installation & Configuration

Since ArgoCD v2.4, notifications are integrated into the application controller — no separate binary needed. All configuration lives in two objects:

  • The argocd-notifications-cm ConfigMap — contains triggers, templates, services, and subscriptions.
  • The argocd-notifications-secret Secret — contains channel tokens/credentials.

The architecture is three core concepts:

ConceptFunction
TriggerThe condition that determines when a notification is sent
TemplateThe message format that determines what is sent
SubscriptionThe binding of trigger + template to a specific channel

Triggers

A trigger is a condition (evaluated from the Application status) that fires a notification. Built-in examples: on-sync-succeeded, on-sync-failed, on-health-degraded. Trigger definition:

Custom trigger
trigger.on-sync-succeeded: |
  - when: app.status.sync.status in ('Synced')
    send: [app-sync-succeeded]
trigger.on-deploy-failed: |
  - when: app.status.health.status in ('Degraded') and app.status.sync.status in ('OutOfSync')
    send: [deploy-failed]

The when field uses expressions (can contain AND/OR logic), and send refers to the template name to use.

Note

Trigger conditions are read from the Application status — to test complex expressions, use argocd app get <name> first to see the actual status.sync.status and status.health.status values.

Templates

Templates define the message content. They can use Application variables and conditionals:

Message template
template.app-sync-succeeded: |
  message: |
    ✅ Application {{.app.metadata.name}} berhasil di-sync.
    Environment: {{.app.spec.destination.namespace}}
  slack:
    attachments: |
      [{ "color": "#2eb886", "title": "Deploy sukses" }]
template.deploy-failed: |
  message: |
    ⚠️ Deploy {{.app.metadata.name}} GAGAL!
    Sync: {{.app.status.sync.status}} | Health: {{.app.status.health.status}}

Variables like app.metadata.name are filled in from the Application object; if/else blocks let the message change based on conditions (e.g. showing the namespace only if present). Messages can be plain text or rich attachments for Slack/Teams.

Warning

Templates use Go template syntax with double curly braces — and are only valid inside a ConfigMap (YAML). Never write expressions like app.metadata.name wrapped in double curly braces in normal narrative text because it will be interpolated incorrectly.

Subscriptions

A subscription determines who receives which notification. Two ways:

Global Subscription in the ConfigMap

Global subscription
subscriptions: |
  - recipients:
      - slack:deployments
    triggers:
      - on-sync-succeeded
      - on-sync-failed
  - recipients:
      - email:ops@company.com
    triggers:
      - on-health-degraded

Per-Application via Annotation

ArgoCDPer-application subscription
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: billing-api
  namespace: argocd
  annotations:
    notifications.argoproj.io/subscribe.on-sync-succeeded.slack: deployments
    notifications.argoproj.io/subscribe.on-sync-failed.email: ops@company.com

The annotation pattern is: notifications.argoproj.io/subscribe.<trigger>.<service>: <recipient>. This gives granular control — critical applications can send to a different channel.

Channels: Services

Connections to channels are configured as a service in the ConfigMap, and tokens are stored in the Secret:

Slack service
service.slack: |
  token: $slack-token
service.webhook: |
  url: https://hooks.example.com/gitops
KubernetesSecret for notifications
apiVersion: v1
kind: Secret
metadata:
  name: argocd-notifications-secret
  namespace: argocd
stringData:
  slack-token: xoxb-XXXX-YYYY

Channels supported out of the box:

ServiceRecipientBenefits
Slackslack:<channel>Team notifications, fast and richly formatted
Microsoft Teamsteams:<webhook>Enterprise integration
Email (SMTP)email:<address>Formal archive, audit
Webhookwebhook:<url>Custom/internal API integration
GitHub/GitLabCommit statusDeploy status on the PR page

The GitHub/GitLab service (service.github-commit-status) sets a status on the commit — very useful: PR reviewers immediately see a deploy success/failure marker without opening ArgoCD.

Use Cases

  • Deploy notifications — the on-sync-succeeded trigger gives the team certainty that a change is live.
  • Failure alerts — the on-sync-failed/on-health-degraded triggers direct on-call to the problem application earlier than waiting for user reports.
  • Approval requests — for production environments, the combination of sync windows (episode 14) + notifications tells reviewers there's a change waiting for approval.
  • Audit trail — because every event is recorded in a channel/email, the team has an operational trail outside Git — a complement to the commit trail for compliance.

Testing Notifications

Before rolling out to many channels, test with the CLI:

Testing a notification trigger
argocd notify trigger billing-api on-sync-succeeded
argocd notify trigger billing-api on-deploy-failed
argocd notify broadcast "Test broadcast"

argocd notify trigger forcibly runs a trigger for a specific application — the fastest way to verify templates and channel connections without waiting for a real event.

Common Pitfalls

  1. Tokens in the ConfigMap, not the Secret. Channel tokens must be in the Secret (argocd-notifications-secret); the ConfigMap only holds references like $slack-token.
  2. A global subscription that's too noisy. Every application sending to one channel = noise. Use per-application annotations to control volume.
  3. Wrong variable in a template. ArgoCD field names (e.g. status.health.status) must be exact; a small mistake produces an empty message. Test with argocd notify trigger.
  4. Forgetting to restart the controller. After changing the ConfigMap, the controller needs a reload so the new configuration is read.
  5. Not filtering triggers. Triggers that are too broad (e.g. every sync including dev) flood the channel; limit them with specific when conditions.

Closing

This episode closed the GitOps automation loop with human observability: the trigger/template/subscription architecture, configuration in the ConfigMap and Secret, Slack/Teams/email/webhook/commit-status channels, triggers based on sync and health, templates with variables and conditionals, and use cases from deploy notifications to audit trails.

The points you should take with you:

  • Notifications are integrated into the application controller since ArgoCD v2.4.
  • A trigger determines when, a template determines what, a subscription determines to whom.
  • Per-application subscriptions via annotations give granular control.
  • Store tokens in the Secret, not the ConfigMap.
  • Always test with argocd notify trigger before rolling out configuration.

Notifications tell us that something happened — but how is that event born in CI/CD? In the next episode 18 we assemble everything in CI/CD Pipeline Integration: GitHub Actions, GitLab CI/CD, and Jenkins that build images, update manifests, and hand the rest over to ArgoCD. See you in episode 18!

Learn GitOps with ArgoCD - Notifications & Alerts | Learn GitOps with ArgoCD