ArgoCD Notificationsを利用する

# はじめに
Amazon EKSで[ArgoCD Notifications](https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/)を利用する方法をまとめます。

Mac環境を想定しています。
今回はSlackに通知をするようにします。

# 実行環境の準備
1.  AWS CLIの設定
[AWS CloudFormationを動かすためのAWS CLIの設定](https://qiita.com/miyabiz/items/fed11796f0ea2b7608f4)を参考にしてください。

1.  EKSクラスタの構築
[Macでeksctlを利用してAmazon EKSのクラスターを構築する](https://qiita.com/miyabiz/items/75f83237795b0b7d52bd)を参考にしてください。

1.  EKSのコンテキストの設定
[MacにてAmazon EKSの設定をする](https://qiita.com/miyabiz/items/b98d145cedb35dab9524)を参考にしてください。

1.  Helmの設定
[Amazon EKSでHelmを利用する](https://qiita.com/miyabiz/items/453361e6af64b324443c)を参考にしてください。

1.  ArgoCDの設定
[Amazon EKSでArgoCDを利用する](https://qiita.com/miyabiz/items/4022b0aba372a8f2c292)を参考にしてください。

# Slack Appの作成

1.  Slack Appを作成する
    [Slack api](https://api.slack.com/apps?new_app=1)にアクセスし、Slack Appを作成し、ワークスペーにインストールする。
    また、OAuthトークンを発行する。

    ※作成方法[Slack Configuration](https://argocd-notifications.readthedocs.io/en/stable/services/slack/)を参考にしてください。
    ※OAuthトークン例: `xoxb-0000000000000-0000000000000-XXXXXXXXXXXXXXXXXXXXXXXX`

1.  インストールしたアプリを利用するSlackチェンネルに登録する

1.  Slack通知のテスト
    ※`OAuthトークン`と`Slackチェンネル名`を設定する
    ※[chat.postMessage](https://api.slack.com/methods/chat.postMessage)を参考にしてください。

    ```sh
    curl -X POST 'https://slack.com/api/chat.postMessage' \
      -d 'token=xoxb-0000000000000-0000000000000-XXXXXXXXXXXXXXXXXXXXXXXX' \
      -d 'channel=#${Slackチャンネル名}' \
      -d 'text=*Test*'
    ```

# 環境設定
※事前にKubernetesクラスターのコンテキストの設定をします。
※ArgoCDのインストールが必要です。

1.  トリガーとテンプレートをクラスターに適用する

    ```sh
    kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/notifications_catalog/install.yaml
    ```

1.  `argocd-notifications-secret.yaml`を作成する
    ※Slackの`OAuthトークン`を設定する

    ```yaml:argocd-notifications-secret.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: argocd-notifications-secret
      namespace: argocd
    stringData:
      notifiers.yaml: |
        slack:
          token: xoxb-0000000000000-0000000000000-XXXXXXXXXXXXXXXXXXXXXXXX
    type: Opaque
    ```
1.  クラスターに適用する

    ```sh
    kubectl apply -f argocd-notifications-secret.yaml
    ```

# [サンプル] guestbook-goのマニフェスト
[guestbook-go](https://github.com/kubernetes/examples/tree/master/guestbook-go)を構築する。

1.  `guestbook-go.yaml` を作成する
    ※`Slackチェンネル名`を設定する

    ```yaml:guestbook-go.yaml
    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: guestbook
      namespace: argocd
      finalizers:
        - resources-finalizer.argocd.argoproj.io
      annotations:
        notifications.argoproj.io/subscribe.on-sync-succeeded.slack: ${Slackのチャンネル名}
    spec:
      project: default
      source:
        repoURL: https://github.com/kubernetes/examples.git
        path: guestbook-go
      destination:
        server: 'https://kubernetes.default.svc'
        namespace: guestbook
      syncPolicy:
        syncOptions:
        - CreateNamespace=true
        automated:
          prune: true
          selfHeal: true
    ```

1.  クラスターに適用する

    ```sh
    kubectl apply -f guestbook-go.yaml
    ```

# クリーンアップ

1.  クラスターから削除する

    ```sh
    kubectl delete -f guestbook-go.yaml

    kubectl delete -f argocd-notifications-secret.yaml

    kubectl delete -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/notifications_catalog/install.yaml
    ```

# デフォルトトリガーを利用する
[Default Triggers](https://argocd-notifications.readthedocs.io/en/stable/triggers/#default-triggers)を参考にしてください。

1.  ConfigMapの`defaultTriggers`にトリガーをまとめる。

    ```yaml:argocd-notifications-cm.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: argocd-notifications-cm
    data:
      # Holds list of triggers that are used by default if trigger is not specified explicitly in the subscription
      defaultTriggers: |
        - on-sync-status-unknown
        - on-sync-running
        - on-sync-failed
        - on-sync-succeeded
        - on-deployed
    ```

1.  ArgoCDのApplicationマニフェストのアノテーションにはトリガーを記載しなくてすみます。
    ```yaml:argocd.yaml
    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      annotations:
        notifications.argoproj.io/subscribe.slack: ${Slackのチャンネル名}
    ```