> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/argoproj/argo-cd/llms.txt
> Use this file to discover all available pages before exploring further.

# Notifications

> Configure triggers, templates, and services for Argo CD notifications

Argo CD Notifications continuously monitors applications and provides a flexible way to notify users about important changes in application state through configurable triggers and templates.

## Overview

The notification system consists of three main components:

* **Triggers** - Define when notifications should be sent
* **Templates** - Define the content and format of notifications
* **Services** - Define where notifications are delivered (Slack, email, etc.)

## Getting Started

<Steps>
  <Step title="Install notification catalog">
    ```bash theme={null}
    kubectl apply -n argocd --server-side --force-conflicts \
      -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/notifications_catalog/install.yaml
    ```
  </Step>

  <Step title="Configure notification service">
    For email notifications:

    ```bash theme={null}
    kubectl apply -n argocd -f - << EOF
    apiVersion: v1
    kind: Secret
    metadata:
      name: argocd-notifications-secret
    stringData:
      email-username: $EMAIL_USER
      email-password: $PASSWORD
    type: Opaque
    EOF
    ```
  </Step>

  <Step title="Register service in ConfigMap">
    ```bash theme={null}
    kubectl patch cm argocd-notifications-cm -n argocd --type merge -p '{
      "data": {
        "service.email.gmail": "{ username: $email-username, password: $email-password, host: smtp.gmail.com, port: 465, from: $email-username }"
      }
    }'
    ```
  </Step>

  <Step title="Subscribe to notifications">
    ```bash theme={null}
    kubectl patch app myapp -n argocd -p '{
      "metadata": {
        "annotations": {
          "notifications.argoproj.io/subscribe.on-sync-succeeded.slack": "my-channel"
        }
      }
    }' --type merge
    ```
  </Step>
</Steps>

## Triggers

Triggers define conditions for sending notifications using predicate expressions.

### Basic Trigger

```yaml theme={null}
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
data:
  trigger.on-sync-status-unknown: |
    - when: app.status.sync.status == 'Unknown'
      send: [app-sync-status, github-commit-status]
```

### Condition Bundles

Multiple conditions with different templates:

```yaml theme={null}
data:
  trigger.sync-operation-change: |
    - when: app.status?.operationState.phase in ['Succeeded']
      send: [github-commit-status]
    - when: app.status?.operationState.phase in ['Running']
      send: [github-commit-status]
    - when: app.status?.operationState.phase in ['Error', 'Failed']
      send: [app-sync-failed, github-commit-status]
```

<Note>
  Use the `?.` operator for optional fields. For example, `app.status?.operationState.phase` won't fail if `operationState` is nil.
</Note>

### Avoid Duplicate Notifications

Use `oncePer` to send notifications only when a field changes:

```yaml theme={null}
data:
  trigger.on-deployed: |
    when: app.status?.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
    oncePer: app.status.sync.revision
    send: [app-sync-succeeded]
```

For monorepos, use:

```yaml theme={null}
oncePer: app.status?.operationState.syncResult.revision
```

### Common Triggers

<Tabs>
  <Tab title="Sync Success">
    ```yaml theme={null}
    trigger.on-sync-succeeded: |
      - when: app.status?.operationState.phase in ['Succeeded']
        oncePer: app.status.sync.revision
        send: [app-sync-succeeded]
    ```
  </Tab>

  <Tab title="Sync Failure">
    ```yaml theme={null}
    trigger.on-sync-failed: |
      - when: app.status?.operationState.phase in ['Error', 'Failed']
        send: [app-sync-failed]
    ```
  </Tab>

  <Tab title="Health Degraded">
    ```yaml theme={null}
    trigger.on-health-degraded: |
      - when: app.status.health.status == 'Degraded'
        send: [app-health-degraded]
    ```
  </Tab>

  <Tab title="Deployment Running">
    ```yaml theme={null}
    trigger.on-sync-running: |
      - when: app.status?.operationState.phase in ['Running']
        oncePer: app.status?.operationState.startedAt
        send: [app-sync-running]
    ```
  </Tab>
</Tabs>

### Default Triggers

Set default triggers for services:

```yaml theme={null}
data:
  defaultTriggers: |
    - on-sync-status-unknown
  
  defaultTriggers.slack: |
    - on-sync-running
    - on-sync-succeeded
    - on-sync-failed
```

Subscribe using defaults:

```yaml theme={null}
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  annotations:
    notifications.argoproj.io/subscribe.slack: my-channel
```

## Templates

Templates define notification content for different services.

### Basic Template

```yaml theme={null}
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
data:
  template.app-sync-succeeded: |
    message: |
      Application {{.app.metadata.name}} has been successfully synced.
    email:
      subject: Application {{.app.metadata.name}} synced
    slack:
      attachments: |
        [{
          "title": "{{.app.metadata.name}}",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "color": "good",
          "fields": [{
            "title": "Sync Status",
            "value": "{{.app.status.sync.status}}",
            "short": true
          }]
        }]
```

### Available Variables

<ResponseField name="app" type="object">
  The Application object containing metadata, spec, and status
</ResponseField>

<ResponseField name="context" type="object">
  Context information including:

  * `argocdUrl` - Argo CD server URL
  * `notificationsUrl` - Notifications controller URL
</ResponseField>

<ResponseField name="repo" type="object">
  Repository metadata
</ResponseField>

<ResponseField name="serviceType" type="string">
  The notification service type (slack, email, etc.)
</ResponseField>

<ResponseField name="recipient" type="string">
  The notification recipient
</ResponseField>

### Template Functions

Use built-in functions in templates:

```yaml theme={null}
template.app-deployed: |
  message: |
    Application {{.app.metadata.name}} is now running version {{.app.status.sync.revision}}.
    Deployed at: {{time.Now.Format "2006-01-02 15:04:05"}}
    Time since last deployment: {{time.Now.Sub (time.Parse .app.status.operationState.finishedAt).Minutes}} minutes
```

## Notification Services

Configure delivery channels for notifications.

### Slack

```yaml theme={null}
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
data:
  service.slack: |
    token: $slack-token
```

```yaml theme={null}
apiVersion: v1
kind: Secret
metadata:
  name: argocd-notifications-secret
stringData:
  slack-token: xoxb-your-token-here
```

Subscribe:

```yaml theme={null}
annotations:
  notifications.argoproj.io/subscribe.on-sync-succeeded.slack: my-channel
```

### Email

<Tabs>
  <Tab title="Gmail">
    ```yaml theme={null}
    service.email.gmail: |
      username: $email-username
      password: $email-password
      host: smtp.gmail.com
      port: 465
      from: $email-username
    ```
  </Tab>

  <Tab title="AWS SES">
    ```yaml theme={null}
    service.email.aws-ses: |
      region: us-east-1
      from: notifications@example.com
    ```
  </Tab>

  <Tab title="Generic SMTP">
    ```yaml theme={null}
    service.email.custom: |
      username: $smtp-username
      password: $smtp-password
      host: smtp.example.com
      port: 587
      from: argocd@example.com
      insecure_skip_verify: false
    ```
  </Tab>
</Tabs>

Subscribe:

```yaml theme={null}
annotations:
  notifications.argoproj.io/subscribe.on-sync-failed.email: team@example.com
```

### Microsoft Teams

```yaml theme={null}
service.teams: |
  recipientUrls:
    channel1: https://outlook.office.com/webhook/...
```

### Webhook

```yaml theme={null}
service.webhook.github: |
  url: https://api.github.com/repos/myorg/myrepo/statuses/{{.app.status.sync.revision}}
  headers:
    - name: Authorization
      value: token $github-token
```

### PagerDuty

```yaml theme={null}
service.pagerdutyv2: |
  serviceKeys:
    my-service: $pagerduty-key
```

### Opsgenie

```yaml theme={null}
service.opsgenie: |
  apiUrl: https://api.opsgenie.com
  apiKeys:
    team1: $opsgenie-api-key
```

## Subscriptions

Subscribe applications or projects to notifications:

### Application Subscriptions

```yaml theme={null}
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  annotations:
    # Subscribe to specific trigger
    notifications.argoproj.io/subscribe.on-sync-succeeded.slack: my-channel
    
    # Subscribe to multiple services
    notifications.argoproj.io/subscribe.on-sync-failed.slack: alerts
    notifications.argoproj.io/subscribe.on-sync-failed.email: team@example.com
    
    # Use default triggers
    notifications.argoproj.io/subscribe.slack: general
```

### Project Subscriptions

```yaml theme={null}
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  annotations:
    notifications.argoproj.io/subscribe.on-sync-succeeded.slack: project-updates
```

All applications in the project will inherit these subscriptions.

## Namespace-Based Configuration

Allow teams to configure notifications in their own namespaces:

### Enable Self-Service Notifications

```yaml theme={null}
# In argocd-cmd-params-cm ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cmd-params-cm
data:
  application.namespaces: team-one, team-two
  notificationscontroller.selfservice.enabled: "true"
```

### Team Namespace Configuration

```yaml theme={null}
# In team's namespace
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: team-one
data:
  service.pagerdutyv2: |
    serviceKeys:
      my-service: $pagerduty-key
---
apiVersion: v1
kind: Secret
metadata:
  name: argocd-notifications-secret
  namespace: team-one
type: Opaque
stringData:
  pagerduty-key: <integration-key>
```

<Warning>
  When the same service and trigger are defined at both controller and application level, both notifications will be sent.
</Warning>

## Advanced Features

### Conditional Subscriptions

Use annotations to conditionally enable notifications:

```yaml theme={null}
metadata:
  annotations:
    # Only notify on production
    notifications.argoproj.io/subscribe.on-sync-succeeded.slack: |
      {{- if eq .app.metadata.labels.environment "production" }}
      prod-alerts
      {{- end }}
```

### Custom Annotations in Triggers

```yaml theme={null}
data:
  trigger.on-version-change: |
    - when: app.metadata.annotations["example.com/version"] != ""
      oncePer: app.metadata.annotations["example.com/version"]
      send: [version-changed]
```

### Grafana Annotations

Automatically create Grafana annotations:

```yaml theme={null}
service.grafana: |
  apiUrl: https://grafana.example.com/api
  apiKey: $grafana-api-key
```

## Troubleshooting

### Check Notification Controller Logs

```bash theme={null}
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-notifications-controller
```

### Test Notifications

```bash theme={null}
# Test notification configuration
argocd admin notifications trigger get on-sync-succeeded

# Send test notification
argocd admin notifications template notify \
  app-sync-succeeded myapp \
  --recipient slack:my-channel
```

### Common Issues

<AccordionGroup>
  <Accordion title="Notifications not being sent">
    * Verify trigger condition matches application state
    * Check service configuration and credentials
    * Ensure subscription annotation is correct
    * Review controller logs for errors
  </Accordion>

  <Accordion title="Duplicate notifications">
    * Use `oncePer` field in trigger configuration
    * Check for overlapping trigger conditions
    * Verify both global and namespace configs
  </Accordion>

  <Accordion title="Template rendering errors">
    * Validate template syntax
    * Use `?.` for optional fields
    * Test templates with argocd admin command
  </Accordion>
</AccordionGroup>

## Best Practices

<CardGroup cols={2}>
  <Card title="Use the catalog" icon="book-open">
    Start with built-in triggers and templates from the catalog
  </Card>

  <Card title="Avoid notification spam" icon="volume-xmark">
    Use `oncePer` to prevent duplicate notifications
  </Card>

  <Card title="Secure credentials" icon="lock">
    Store service credentials in Kubernetes Secrets
  </Card>

  <Card title="Test before deploying" icon="flask">
    Use `argocd admin notifications` to test configuration
  </Card>

  <Card title="Enable self-service" icon="users">
    Allow teams to configure their own notifications
  </Card>

  <Card title="Monitor the controller" icon="chart-line">
    Set up alerts for notification controller errors
  </Card>
</CardGroup>

<Card title="Related Resources" icon="book">
  * [Notification Catalog](https://github.com/argoproj/argo-cd/tree/master/notifications_catalog)
  * [Trigger Functions](https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/functions/)
  * [Service Configuration](https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/services/overview/)
</Card>
