ArgoCD Notificationsを導入しました(導入方法、メリット)

7 min read読了の目安(約6400字

ArgoCD Notifications とは

  • ArgoCDのApplicationリソースを監視し、ステータスの変化時に様々な方法で通知を行うことができる
    • Slackやメール送信などが可能
  • ConfigMapで triggertemplateを管理し、ArgoCDのApplicationリソースにannotationを付与すれば、通知してくれる

https://github.com/argoproj-labs/argocd-notifications

導入方法

詳しい導入方法は公式ドキュメントを参考にしてください。

https://argocd-notifications.readthedocs.io/en/stable/

ここでは僕の行った導入例を紹介します。
僕の環境では以下のような構成で管理しています

  • KubernetesクラスタはGKE(v1.18)
  • KubernetesのリソースはArgoCD(v2.0.0) + Kustomize
  • dockerイメージはGCR
  • GCPリソースはTerraform
  • KubernetesのsercetはGoogle Secret Manager と External Secret

導入手順は主に以下の4ステップです

  • 1, argocd-notificationsのmanifestをapplyする
  • 2, Slackのtokenをsecretに登録
  • 3, ConfigMapでtriggertemplateを登録
  • 4, ArgoCDのapplicationにannotationを追記する

①manifestをapplyする

以下の3つのファイルを作成し、kustomizeで行いました。

  • some_dir/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- github.com/argoproj-labs/argocd-notifications/manifests/controller?ref=v1.1.0
patchesStrategicMerge:
- argocd_notifications_cm.yaml
# secretはExternalSecretsで管理するのでここでは削除しておく
- delete_argocd_notifications_secret.yaml
  • some_dir/argocd_notifications_cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
# dataはあとで追加します
  • some_dir/delete_argocd_notifications_secret.yaml
$patch: delete
apiVersion: v1
kind: Secret
metadata:
  name: argocd-notifications-secret

あとは以下のコマンドを叩けば、kubernetesにインストールされます

kustomize -n argocd build some_dir | kubectl apply -f -

kustomizeのremote targetsという機能を使うことで、外部のGitリポジトリのURLをbaseに指定することができます。
あとは変更したい箇所でpatchを当てればよいので、kubernetesにツールをインストールする時のバージョン管理、パラメータ管理を楽に行うことができます。

argocd-notifications-secretについては、あとでExternalSecretsを使って作成するので、ここではKustomizeのpatchesStrategicMergeを利用することで、secretリソースを消すように上書きしています。

実際はArgoCDのApplicationとして管理していますが、ここでは簡略化しています。

②Slackのtokenをsecretに登録

Slackのtokenの発行方法は公式ドキュメントに詳しく乗っているので参考にしてください。

https://argocd-notifications.readthedocs.io/en/stable/services/slack/

僕のプロジェクトでは、機密情報はGoogleSecretManagerで管理しているので、terraformによって作成します。

resource "google_secret_manager_secret" "slack_token_for_argocd_notifications" {
  secret_id = "slack_token_for_argocd_notifications"

  replication {
    automatic = true
  }
}

GoogleSecretManagerのsecretを作成したら、GCPコンソール上から、新しいバージョンとして上で発行したSlackのtokenを登録します。

GoogleSecretManagerの準備ができたら、ExternalSecretのリソースを作成します。

apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
  name: argocd-notifications-secret
  namespace: argocd
spec:
  backendType: gcpSecretsManager
  projectId: xxxxxxxxx
  data:
  - name: slack-token
    key: slack_token_for_argocd_notifications
    version: latest

最後にConfigMapにslack-tokenの設定を追記します

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
data:
  service.slack: |
    token: $slack-token

③ConfigMapでtriggertemplateを登録

triggerについて

https://argocd-notifications.readthedocs.io/en/stable/triggers/

templateについて

https://argocd-notifications.readthedocs.io/en/stable/templates/

triggerとtemplateの両方を登録しないとNotificationが起動しません。

全部ここに載せると膨大な量になってしまうので、一部抜粋します。

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
data:
  service.slack: # ここでは省略
  # templateに埋め込むためのパラメータを設定する
  config.yaml: |
    context:
      argocdUrl: https://my-apps.com
  # templateを好きに登録する
  template.app-sync-succeeded: |
    message: |
      {{if eq .serviceType "slack"}}:white_check_mark:{{end}} Application {{.app.metadata.name}} has been successfully synced at {{.app.status.operationState.finishedAt}}.
      Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true .
    slack:
      attachments: "[{\n  \"title\": \"{{ .app.metadata.name}}\",\n  \"title_link\":\"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}\",\n  \"color\": \"#18be52\",\n  \"fields\": [\n  {\n    \"title\": \"Sync Status\",\n    \"value\": \"{{.app.status.sync.status}}\",\n    \"short\": true\n  },\n  {\n    \"title\": \"Repository\",\n    \"value\": \"{{.app.spec.source.repoURL}}\",\n    \"short\": true\n  }\n  {{range $index, $c := .app.status.conditions}}\n  {{if not $index}},{{end}}\n  {{if $index}},{{end}}\n  {\n    \"title\": \"{{$c.type}}\",\n    \"value\": \"{{$c.message}}\",\n    \"short\": true\n  }\n  {{end}}\n  ]\n}]    "
  # triggerを好きに登録する
  trigger.on-sync-succeeded: |
    - description: Application syncing has succeeded
      send:
      - app-sync-succeeded
      when: app.status.operationState.phase in ['Succeeded']

podを再起動するとtemplateとtriggerが登録されると思います。
ちゃんと登録されたか確認するには、以下のコマンドを実行すればOKです。

kubectl exec -it argocd-notifications-controller-<pod-hash> \
  /app/argocd-notifications trigger get
kubectl exec -it argocd-notifications-controller-<pod-hash> \
  /app/argocd-notifications template get

トラブルシューティングについて詳しくはこちら

https://argocd-notifications.readthedocs.io/en/stable/troubleshooting/#in-your-cluster

④ArgoCDのapplicationにannotationを追記する

あとはArgoCDのApplciationリソースにannotationを追記するだけでOKです。
triggerがたくさんある場合は、annotationをたくさん書くことになってしまうので、default triggerを設定することにしました。

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
data:
  service.slack: # ここでは省略
  config.yaml: # ここでは省略
  defaultTriggers: |
    - on-deployed
    - on-sync-running
    - on-sync-succeeded
    - on-sync-failed
    - on-sync-status-unknown
    - on-health-degraded
  template.app-deployed: # ここでは省略

このようにしておくと、annotationがずっとシンプルになります。
default triggerを使って、slackに通知する場合は以下のようなAnnotationをArgoCDのApplicationリソースに追記すればOKです

notifications.argoproj.io/subscribe.slack: channel-name

おもった通りに動かない時は

公式のtroubleshootingのドキュメントにのっていますが、argocd-notificationsのCLIを使うと状況を把握しやすいです。
下の方法で行えば、起動してるpodを使ってargocd-notificationsのCLIを使えるので便利です。

kubectl exec -it argocd-notifications-controller-<pod-hash> \
  /app/argocd-notifications trigger get

https://argocd-notifications.readthedocs.io/en/stable/troubleshooting/#in-your-cluster

導入してみて

よかったこと

  • 通知をするのが楽になりました!
  • もともとはArgoCDのHookSucceededを使い、jobを使ってslackに通知を送っていたのですが、それらが不要になりました!
  • 細かくカスタマイズできるので、好きなタイミングに、好きな内容を通知することができます

よくなかったこと

  • 特になし
  • trigger、templateの登録に手間取ったので、導入するのにちょっと苦戦しました

最後に

所詮たかが通知をする機能なのでそんなにインパクトはないですね😅
とはいえ、不要なJobを削除することができたので、僕のプロジェクト的には割とスッキリしました。
また、かなり細かくカスタマイズできるので、用途に合わせて通知を送れるのでどんなプロジェクトでも採用しやすいなと思いました😊