ArgoCD Notifications で Application の状態変化を通知する

ArgoCD Application の異常に気付ける仕組みが欲しいと思い、ArgoCD Notifications を導入してみました。

（最近、仕事で記事を書く機会があり、その際、この記事をストックしたままだったことを思い出したので、これを機に公開）

# ArgoCD Notifications とは
- ArgoCD Application を継続的に監視
- ArgoCD Application の状態変化をユーザーに通知
- 通知サービスとして、メールや Slack、 Teams などがある（Webhook も使える）

今回は Webhook を使って、Slack に通知させます。

# 手順
1. ArgoCD Notifications のインストール
2. ArgoCD Notifications のコンフィグ定義
3. Secret の定義（Webhook URL 保管用）
4. デプロイ

前提として、 ArgoCD の導入・設定は完了している想定で進めます。

# ArgoCD Notifications のインストール
~~~sh
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/release-1.0/manifests/install.yaml
~~~

# ArgoCD Notifications のコンフィグ定義
## 全体
~~~yaml
# argocd-notifications-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  trigger.<TRIGGER_NAME>: |
    - description: Application sync status is unknown
      send:
      - <TEMPLATE_NAME>
      when: app.status.sync.status == 'Unknown'
      oncePer: app.status.sync.revision
  template.<TEMPLATE_NAME>: |
    webhook:
      slack:
        method: POST
        body: |
          {
            "attachments": [
              {
                "title": "Title",
                "title_link": "<ARGOCD_DOMAIN_URL>/applications/{{.app.metadata.name}}",
                "color": "#ff0000",
                "fields": [
                  {
                    "title": "Status",
                    "value": "{{.app.status.sync.status}}",
                    "short": true
                  }
                ]
              }
            ]
          }
  service.webhook.<WEBHOOK_NAME>: |
    url: $webhook-url
  subscriptions: |
    - recipients:
      - <WEBHOOK_NAME>
      triggers:
      - <TRIGGER_NAME>
~~~

## 解説：Triggers
通知条件を定義します。  
今回は Application の `Status=Unknown` 時に発火させる定義です。  
`when` は条件を指定。`oncePer` で指定フィールドが変更された場合に限り、通知させます。今回のケースは、Git リビジョンごとに1回のみ通知します。  
条件は他にも、「アプリケーションが作成された時」「同期に成功した時」「同期に失敗した時」などがあります。
~~~yaml
trigger.<TRIGGER_NAME>: |
  - description: Application sync status is unknown
    send:
    - <TEMPLATE_NAME>
    when: app.status.sync.status == 'Unknown'
    oncePer: app.status.sync.revision
~~~


## 解説：Templates
通知メッセージを定義します。  
今回は Webhook を使って Slack に通知する定義です。スキーマは [Slack API](https://api.slack.com/messaging/webhooks) を参照。
~~~yaml
template.<TEMPLATE_NAME>: |
  webhook:
    slack:
      method: POST
      body: |
        {
          "attachments": [
            {
              "title": "Title",
              "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
              "color": "#ff0000",
              "fields": [
                {
                  "title": "Status",
                  "value": "{{.app.status.sync.status}}",
                  "short": true
                },
                {
                  "title": "Repository",
                  "value": "{{.app.spec.source.repoURL}}",
                  "short": true
                }
              ]
            }
          ]
        }
~~~

## 解説：Notification
通知サービスを定義します。  
今回は Webhook の定義です。
~~~yaml
service.webhook.<WEBHOOK_NAME>: |
  url: $webhook-url
~~~

## 解説：Subscriptions
トリガーと通知サービスの連携を定義します。
~~~yaml
subscriptions: |
  - recipients:
    - <WEBHOOK_NAME>
    triggers:
    - <TRIGGER_NAME>
~~~

# Secret の定義（Webhook URL 保管用）
stringData の key は、Notification の定義と揃えます。
~~~yaml
# argocd-notifications-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: argocd-notifications-secret
stringData:
  webhook-url: <WEBHOOK_URL>
~~~

# デプロイ
~~~sh
kubectl apply -n argocd -f argocd-notifications-secret.yaml
kubectl apply -n argocd -f argocd-notifications-cm.yaml
~~~
Pod(argocd-notifications-controller) の restart を忘れずに。

# Ref
- [ArgoCD Notifications](https://argocd-notifications.readthedocs.io/en/stable/)