Two corrections on top of the naming pass, both found by checking the live cluster rather than the source. The rename had silently changed the user-facing annotation key from argocd.argoproj.io/sync-wave to cd.argoproj.io/sync-wave — 63 live Applications carry the old key, so deploying that would have ignored every sync-wave and broken fleet deploy ordering. The key is now cd.hanzo.ai/*, and universe 575650286 moves the ApplicationSet template that stamps it, so the controller regenerates all 63 consistently. The API group in code said argoproj.io/v1alpha1 in 157 places while the cluster has served apps.hanzo.ai/v1alpha1 since 2026-07-23 (the CRDs are applications.apps.hanzo.ai). Code now matches what is actually served. The legacy applications.argoproj.io/app-name label had ZERO live users, so it went with the rest. foo.argoproj.io test fixtures became foo.example.com — arbitrary test domains should not carry a vendor name. go build ./... exit 0. Co-authored-by: Hanzo Dev <[email protected]>
4.7 KiB
The notification template is used to generate the notification content and is configured in the cd-notifications-cm ConfigMap. The template is leveraging
the html/template golang package and allows customization of the notification message.
Templates are meant to be reusable and can be referenced by multiple triggers.
The following template is used to notify the user about application sync status.
apiVersion: v1
kind: ConfigMap
metadata:
name: cd-notifications-cm
data:
template.my-custom-template-slack-template: |
message: |
Application {{.app.metadata.name}} sync is {{.app.status.sync.status}}.
Application details: {{.context.cdUrl}}/applications/{{.app.metadata.name}}.
Each template has access to the following fields:
appholds the application object.appProjectholds the AppProject object associated with the application. This provides access to project-level details like RBAC roles, policies, source repository restrictions, and destination cluster restrictions.contextis a user-defined string map and might include any string keys and values.secretsprovides access to sensitive data stored incd-notifications-secretserviceTypeholds the notification service type name (such as "slack" or "email"). The field can be used to conditionally render service-specific fields.recipientholds the recipient name.
Defining user-defined context
It is possible to define some shared context between all notification templates by setting a top-level YAML document of key-value pairs, which can then be used within templates, like so:
apiVersion: v1
kind: ConfigMap
metadata:
name: cd-notifications-cm
data:
context: |
region: east
environmentName: staging
template.a-slack-template-with-context: |
message: "Something happened in {{ .context.environmentName }} in the {{ .context.region }} data center!"
Using AppProject information in templates
Templates can access the AppProject associated with an Application using the appProject variable. This is useful for including project-level information such as RBAC policies, source repositories, and destination clusters in notifications.
apiVersion: v1
kind: ConfigMap
metadata:
name: cd-notifications-cm
data:
template.app-project-info: |
message: |
Application {{.app.metadata.name}} belongs to project {{.appProject.metadata.name}}.
Project description: {{.appProject.spec.description}}
Allowed source repositories: {{range .appProject.spec.sourceRepos}}{{.}} {{end}}
template.app-rbac-policies: |
message: |
Application: {{.app.metadata.name}}
Project: {{.appProject.metadata.name}}
RBAC Roles:
{{range .appProject.spec.roles}}
- Role: {{.name}}
Policies: {{range .policies}}{{.}} {{end}}
{{end}}
Defining and using secrets within notification templates
Some notification service use cases will require the use of secrets within templates. This can be achieved with the use of
the secrets data variable available within the templates.
Given that we have the following cd-notifications-secret:
apiVersion: v1
kind: Secret
metadata:
name: cd-notifications-secret
stringData:
sampleWebhookToken: secret-token
type: Opaque
We can use the defined sampleWebhookToken in a template as such:
apiVersion: v1
kind: ConfigMap
metadata:
name: cd-notifications-cm
data:
template.trigger-webhook: |
webhook:
sample-webhook:
method: POST
path: 'webhook/endpoint/with/auth'
body: 'token={{ .secrets.sampleWebhookToken }}&variables[APP_SOURCE_PATH]={{ .app.spec.source.path }}
Notification Service Specific Fields
The message field of the template definition allows creating a basic notification for any notification service. You can leverage notification service-specific
fields to create complex notifications. For example, using service-specific fields you can add blocks and attachments for Slack, subject for Email or URL path, and body for Webhook.
See corresponding service documentation for more information.
Change the timezone
To change the timezone used when formatting time values in notifications, see Configuring the local timezone.
Functions
Templates have access to the set of built-in functions such as the functions of the Sprig package
apiVersion: v1
kind: ConfigMap
metadata:
name: cd-notifications-cm
data:
template.my-custom-template-slack-template: |
message: "Author: {{(call .repo.GetCommitMetadata .app.status.sync.revision).Author}}"
{!docs/operator-manual/notifications/functions.md!}