GitOpsで簡単に通知設定したいのでArgoCD Notificationsを導入しました
ArgoCD Notifications とは
- ArgoCDのApplicationリソースを監視し、ステータスの変化時に様々な方法で通知を行うことができる
- Slackやメール送信などが可能
- ConfigMapで
trigger
とtemplate
を管理し、ArgoCDのApplicationリソースにannotationを付与すれば、通知してくれる
今までの辛み
- 今までも通知は送っていて、ArgoCDの
HookSucceeded
を使って通知をするだけのjobをキックしていました - 通知を送りたい全てのアプリケーションにjobを作成する必要があるので、めんどくさい、メンテコスト高い、本当に必要なリソースがどれかわかりづらくなってしまう、などの辛みがありました
- 様々な状態を通知するためには、それぞれの状態のHookを利用する必要があるので、細かいカスタマイズをするほどリソースが増えて複雑になってしまいました
導入すると何が嬉しいの?
- 余計なリソースを作らなくてもよくなったので、各アプリケーションに本当に必要なリソースだけを定義できるようになりました。
- 細かくカスタマイズできるようになったので、好きなタイミングに、好きな内容を通知することができます。
導入してよくなかったこと
- 特になし
- trigger、templateの登録に手間取ったので、導入するのにちょっと苦戦しました
導入方法
詳しい導入方法は公式ドキュメントを参考にしてください。
ここでは僕の行った導入例を紹介します。
僕の環境では以下のような構成で管理しています
- 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で
trigger
とtemplate
を登録 - 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の発行方法は公式ドキュメントに詳しく乗っているので参考にしてください。
僕のプロジェクトでは、機密情報は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
trigger
とtemplate
を登録
③ConfigMapでtriggerについて
templateについて
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
トラブルシューティングについて詳しくはこちら
④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
最後に
所詮たかが通知をする機能なのでそんなにインパクトはないですね😅
とはいえ、不要なJobを削除することができたので、僕のプロジェクト的には割とスッキリしました。
また、かなり細かくカスタマイズできるので、用途に合わせて通知を送れるのでどんなプロジェクトでも採用しやすいなと思いました😊
Discussion