> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ahmadraza.in/llms.txt
> Use this file to discover all available pages before exploring further.

# ArgoSlackNotification

# Argo CD to Slack Notifications: The Complete Setup Guide

This document outlines the step-by-step process to configure Argo CD to send rich, detailed notifications to Slack whenever an application syncs, fails, or degrades.

## ✅ Prerequisites

* **Argo CD** installed on your Kubernetes cluster.
* **Admin access** to a Slack Workspace.
* `kubectl` access to your cluster.

***

## 1. Configure Slack App & Bot Token

We need to create a "Bot" user that Argo CD can use to post messages.

1. Go to **[Slack API: Your Apps](https://api.slack.com/apps)**.
2. Click **Create New App** > **From Scratch**.
3. Name it **"ArgoCD"** and select your workspace.
4. In the left sidebar, go to **OAuth & Permissions**.
5. Scroll down to **Scopes** > **Bot Token Scopes** and add the following permission:

* `chat:write` (Required to send messages)
* `chat:write.customize` (Optional: Allows changing username/icon dynamically)

6. Scroll up to the top of the page and click **Install to Workspace**.
7. **Copy the Bot User OAuth Token** (starts with `xoxb-...`).

### ⚠️ Important: Invite the Bot

For the bot to post in a channel, it must be a member of that channel.

* Go to your target Slack channel (e.g., `#jenkins-ntfy`).
* Type `/invite @ArgoCD` and hit Enter.

***

## 2. Create the Kubernetes Secret (Safely)

We must store the Slack token in a Kubernetes Secret.
**CRITICAL:** We use `echo -n` to prevent hidden newline characters (`\n`) from breaking the configuration.

Run this command in your terminal (replace `xoxb-YOUR-TOKEN` with your actual token):

```bash theme={null}
kubectl create secret generic argocd-notifications-secret \
  -n argocd \
  --from-literal=slack-token=$(echo -n "xoxb-YOUR-REAL-TOKEN-HERE") \
  --dry-run=client -o yaml | kubectl apply -f -

```

***

## 3. Configure Argo CD Notifications

We will configure the `argocd-notifications-cm` ConfigMap. This defines **Service**, **Triggers**, **Subscriptions**, and the **Message Templates**.

### Features of this Configuration:

* **Rich Formatting:** Uses Slack Attachments for a professional "CloudWatch" look.
* **Detailed Info:** Lists Repo URL, Commit SHA, and Sync Status.
* **Resource List:** loops through changed objects (e.g., `Service my-svc -> configured`) so developers see exactly what changed.
* **Deep Links:** Clickable titles take you directly to the Argo CD dashboard.

### 📄 `argocd-notifications-cm.yaml`

Save the following content to a file named `argocd-notifications-cm.yaml`.
\*\*Update the `argocdUrl**` at the top with your actual Argo CD domain.

````yaml theme={null}
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  # ---------------------------------------------------------------------------
  # 1. CONTEXT (Replace with your actual Argo CD URL for clickable links)
  # ---------------------------------------------------------------------------
  context: |
    argocdUrl: https://argocd.your-domain.com

  # ---------------------------------------------------------------------------
  # 2. SLACK SERVICE CONFIGURATION
  # ---------------------------------------------------------------------------
  service.slack: |
    token: $slack-token
    username: ArgoCD
    # icon: :rocket:  <-- Do not use this line, it causes YAML parsing errors.

  # ---------------------------------------------------------------------------
  # 3. GLOBAL SUBSCRIPTION (Applies to ALL Applications)
  # ---------------------------------------------------------------------------
  subscriptions: |
    - recipients:
      - slack:jenkins-ntfy   # <--- Change to your Slack Channel name
      triggers:
      - on-sync-succeeded
      - on-sync-failed
      - on-health-degraded
      - on-deployed

  # ---------------------------------------------------------------------------
  # 4. TRIGGERS (Logic for when to fire alerts)
  # ---------------------------------------------------------------------------
  trigger.on-sync-succeeded: |
    - description: Application syncing has succeeded
      send: [app-sync-succeeded]
      when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'

  trigger.on-sync-failed: |
    - description: Application syncing has failed
      send: [app-sync-failed]
      when: app.status.operationState.phase in ['Error', 'Failed']

  trigger.on-health-degraded: |
    - description: Application has degraded
      send: [app-health-degraded]
      when: app.status.health.status == 'Degraded'

  trigger.on-deployed: |
    - description: Application is synced and healthy. Triggered once per commit.
      oncePer: app.status.operationState.syncResult.revision
      send: [app-deployed]
      when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'

  # ---------------------------------------------------------------------------
  # 5. TEMPLATES (The "CloudWatch-Style" Message Design)
  # ---------------------------------------------------------------------------

  # ✅ SYNC SUCCEEDED
  template.app-sync-succeeded: |
    message: |
      ✅ Application {{.app.metadata.name}} Synced.
    slack:
      attachments: |
        [{
          "color": "#18be52",
          "title": "✅ Sync Succeeded: {{.app.metadata.name}}",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "fields": [
            {
              "title": "Application",
              "value": "<{{.context.argocdUrl}}/applications/{{.app.metadata.name}}|{{.app.metadata.name}}>",
              "short": true
            },
            {
              "title": "Repo URL",
              "value": "{{.app.spec.source.repoURL}}",
              "short": true
            },
            {
              "title": "Commit",
              "value": "`{{.app.status.operationState.syncResult.revision}}`",
              "short": true
            },
            {
              "title": "Status",
              "value": "Sync: {{.app.status.operationState.phase}}\nHealth: {{.app.status.health.status}}",
              "short": true
            },
            {
              "title": "📦 Changed Objects",
              "value": "```{{range .app.status.operationState.syncResult.resources}}• {{.kind}} {{.name}}: {{.message}}\n{{end}}```",
              "short": false
            }
          ],
          "footer": "Argo CD"
        }]

  # ❌ SYNC FAILED
  template.app-sync-failed: |
    message: |
      ❌ Application {{.app.metadata.name}} Failed to Sync.
    slack:
      attachments: |
        [{
          "color": "#ff0000",
          "title": "❌ Sync Failed: {{.app.metadata.name}}",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "fields": [
            {
              "title": "Application",
              "value": "<{{.context.argocdUrl}}/applications/{{.app.metadata.name}}|{{.app.metadata.name}}>",
              "short": true
            },
            {
              "title": "Error Message",
              "value": "```{{.app.status.operationState.message}}```",
              "short": false
            },
            {
              "title": "Commit",
              "value": "`{{.app.status.operationState.syncResult.revision}}`",
              "short": true
            }
          ],
          "footer": "Argo CD"
        }]

  # ⚠️ HEALTH DEGRADED
  template.app-health-degraded: |
    message: |
      ⚠️ Application {{.app.metadata.name}} is Degraded.
    slack:
      attachments: |
        [{
          "color": "#ffca00",
          "title": "⚠️ Health Degraded: {{.app.metadata.name}}",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "fields": [
            {
              "title": "Application",
              "value": "<{{.context.argocdUrl}}/applications/{{.app.metadata.name}}|{{.app.metadata.name}}>",
              "short": true
            },
            {
              "title": "Health Status",
              "value": "{{.app.status.health.status}}",
              "short": true
            }
          ],
          "footer": "Argo CD"
        }]

  # 🚀 DEPLOYED (Triggered on new commit syncs)
  template.app-deployed: |
    message: |
      🚀 New Version Deployed: {{.app.metadata.name}}
    slack:
      attachments: |
        [{
          "color": "#2eb886",
          "title": "🚀 Deployed: {{.app.metadata.name}}",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "fields": [
            {
              "title": "Application",
              "value": "<{{.context.argocdUrl}}/applications/{{.app.metadata.name}}|{{.app.metadata.name}}>",
              "short": true
            },
            {
              "title": "New Commit",
              "value": "`{{.app.status.operationState.syncResult.revision}}`",
              "short": true
            },
            {
              "title": "📦 Affected Objects",
              "value": "```{{range .app.status.operationState.syncResult.resources}}• {{.kind}} {{.name}} -> {{.message}}\n{{end}}```",
              "short": false
            }
          ],
          "footer": "Argo CD"
        }]

````

***

## 4. Apply and Restart

Apply the configuration and restart the controller to force it to reload the settings.

```bash theme={null}
# 1. Apply the ConfigMap
kubectl apply -f argocd-notifications-cm.yaml

# 2. Restart the Controller
kubectl rollout restart deployment argocd-notifications-controller -n argocd

# Note: If using Argo CD v2.3+ bundled controller, restart the application-controller instead:
# kubectl rollout restart deployment argocd-application-controller -n argocd

```

***

## 5. Verification

1. Check the logs to ensure no YAML errors:

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

```

2. Go to the Argo CD UI.
3. Click **Sync** on any application.
4. Check your Slack channel. You should see a detailed card listing the sync status and the specific objects (Pods/Services) that were updated.

***

## 🔧 Troubleshooting Guide (Common Issues)

| Issue                                                     | Cause                                                                                            | Fix                                                                         |                                                            |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------- | ---------------------------------------------------------- |
| **Error:** `yaml: line 2: mapping values are not allowed` | **Hidden Newline in Secret.** The Slack token has a `\n` at the end.                             | Delete secret and recreate using `echo -n "token"`.                         |                                                            |
| **Error:** `template: unexpected ".0" in operand`         | **Invalid Go Template Syntax.** Accessing arrays like `.history.0` is not allowed.               | Use `index .history 0` or remove the field (as we did in the final config). |                                                            |
| **Slack:** `<<no value>/applications/...>`                | **Missing Context URL.** The template cannot generate links because it doesn't know your domain. | Add \`context:                                                              | argocdUrl: [https://...\`](https://...`) to the ConfigMap. |
| **Boot Loop / Crash**                                     | **YAML Formatting.** Using colons inside values without quotes (e.g., `icon: :rocket:`).         | Remove the icon line or quote it properly `"icon": ":rocket:"`.             |                                                            |

***

***

ArgoSecret.yaml

```yaml theme={null}
apiVersion: v1
kind: Secret
metadata:
  name: argocd-notifications-secret
  namespace: argocd
stringData:
  slack-token: xoxb-xxxxxxxxxxxxxxxxxxxx
type: Opaque
```

ArgoCM.yaml

````yaml theme={null}
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  # ---------------------------------------------------------------------------
  # 1. CONTEXT (Fixes the <no value> link issue)
  # ---------------------------------------------------------------------------
  context: |
    argocdUrl: http://argo-uat.internal.domain.co.in

  # ---------------------------------------------------------------------------
  # 2. SLACK TOKEN & SETTINGS
  # ---------------------------------------------------------------------------
  service.slack: |
    token: xoxb-xxxxxxxxxxxxxxxxxxxx
    username: ArgoCD

  # ---------------------------------------------------------------------------
  # 3. SUBSCRIPTIONS
  # ---------------------------------------------------------------------------
  subscriptions: |
    - recipients:
      - slack:jenkins-ntfy
      triggers:
      - on-sync-succeeded
      - on-sync-failed
      - on-health-degraded
      - on-deployed

  # ---------------------------------------------------------------------------
  # 4. TRIGGERS
  # ---------------------------------------------------------------------------
  trigger.on-sync-succeeded: |
    - description: Application syncing has succeeded
      send: [app-sync-succeeded]
      when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'

  trigger.on-sync-failed: |
    - description: Application syncing has failed
      send: [app-sync-failed]
      when: app.status.operationState.phase in ['Error', 'Failed']

  trigger.on-health-degraded: |
    - description: Application has degraded
      send: [app-health-degraded]
      when: app.status.health.status == 'Degraded'

  # trigger.on-deployed: |
  #   - description: Application is synced and healthy. Triggered once per commit.
  #     oncePer: app.status.operationState.syncResult.revision
  #     send: [app-deployed]
  #     when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'

  # ---------------------------------------------------------------------------
  # 5. TEMPLATES (With Action Details: Configured/Created)
  # ---------------------------------------------------------------------------

  # ✅ SYNC SUCCEEDED
  template.app-sync-succeeded: |
    message: |
      🚀 Application {{.app.metadata.name}} Synced.
    slack:
      attachments: |
        [{
          "color": "#18be52",
          "title": "✅ Sync Succeeded: {{.app.metadata.name}}",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "fields": [
            {
              "title": "Application",
              "value": "<{{.context.argocdUrl}}/applications/{{.app.metadata.name}}|{{.app.metadata.name}}>",
              "short": true
            },
            {
              "title": "Repo URL",
              "value": "{{.app.spec.source.repoURL}}",
              "short": true
            },
            {
              "title": "Commit",
              "value": "`{{.app.status.operationState.syncResult.revision}}`",
              "short": true
            },
            {
              "title": "Status",
              "value": "Sync: {{.app.status.operationState.phase}}\nHealth: {{.app.status.health.status}}",
              "short": true
            },
            {
              "title": "📦 Changed Objects",
              "value": "```{{range .app.status.operationState.syncResult.resources}}• {{.kind}} {{.name}}: {{.message}}\n{{end}}```",
              "short": false
            }
          ],
          "footer": "Argo CD"
        }]

  # ❌ SYNC FAILED
  template.app-sync-failed: |
    message: |
      ❌ Application {{.app.metadata.name}} Failed to Sync.
    slack:
      attachments: |
        [{
          "color": "#ff0000",
          "title": "❌ Sync Failed: {{.app.metadata.name}}",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "fields": [
            {
              "title": "Application",
              "value": "<{{.context.argocdUrl}}/applications/{{.app.metadata.name}}|{{.app.metadata.name}}>",
              "short": true
            },
            {
              "title": "Error Message",
              "value": "```{{.app.status.operationState.message}}```",
              "short": false
            },
            {
              "title": "Commit",
              "value": "`{{.app.status.operationState.syncResult.revision}}`",
              "short": true
            }
          ],
          "footer": "Argo CD"
        }]

  # ⚠️ HEALTH DEGRADED
  template.app-health-degraded: |
    message: |
      ⚠️ Application {{.app.metadata.name}} is Degraded.
    slack:
      attachments: |
        [{
          "color": "#ffca00",
          "title": "⚠️ Health Degraded: {{.app.metadata.name}}",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
          "fields": [
            {
              "title": "Application",
              "value": "<{{.context.argocdUrl}}/applications/{{.app.metadata.name}}|{{.app.metadata.name}}>",
              "short": true
            },
            {
              "title": "Health Status",
              "value": "{{.app.status.health.status}}",
              "short": true
            }
          ],
          "footer": "Argo CD"
        }]

  # # 🚀 DEPLOYED
  # template.app-deployed: |
  #   message: |
  #     🚀 New Version Deployed: {{.app.metadata.name}}
  #   slack:
  #     attachments: |
  #       [{
  #         "color": "#2eb886",
  #         "title": "🚀 Deployed: {{.app.metadata.name}}",
  #         "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
  #         "fields": [
  #           {
  #             "title": "Application",
  #             "value": "<{{.context.argocdUrl}}/applications/{{.app.metadata.name}}|{{.app.metadata.name}}>",
  #             "short": true
  #           },
  #           {
  #             "title": "New Commit",
  #             "value": "`{{.app.status.operationState.syncResult.revision}}`",
  #             "short": true
  #           },
  #           {
  #             "title": "📦 Affected Objects",
  #             "value": "```{{range .app.status.operationState.syncResult.resources}}• {{.kind}} {{.name}} -> {{.message}}\n{{end}}```",
  #             "short": false
  #           }
  #         ],
  #         "footer": "Argo CD"
  #       }]

````

> Restart Services

```bash theme={null}
kubectl rollout restart deployment argocd-notifications-controller -n argocd
```
