Skip to content

Argo CD Commit Status Controller

The Argo CD Commit Status controller is a controller that enables environment gating based on Argo CD's concept of a healthy application. The controller listens for updates on Applications based on a common label on the Application resources managed by a particular PromotionStrategy.

Note

The controller supports both Argo CD Applications that use the Source Hydrator and standard Applications that use spec.source. For standard Applications, the spec.source.targetRevision field is used as the environment identifier (equivalent to spec.sourceHydrator.syncSource.targetBranch for hydrated applications).

Important

Currently the repo URL configured in the PromotionStrategy must be exactly the same as the repo URL configured in the Argo CD Application.

Note

GitOps Promoter provides several opt-in Argo CD integrations that improve the user experience. Check out the Argo CD Integrations page for more information.

Example Configurations

In this example we see an ArgoCDCommitStatus resource that is configured to select all Argo CD Applications that have the label app: webservice-tier-1. These Applications must also be associated with the PromotionStrategy named webservice-tier-1. Once this is configured, the controller will create a CommitStatus resource for each application that matches the selector.

apiVersion: promoter.argoproj.io/v1alpha1
kind: ArgoCDCommitStatus
metadata:
  name: webservice-tier-1
spec:
  key: argocd-health
  promotionStrategyRef:
    name: webservice-tier-1
  applicationSelector:
    matchLabels:
      app: webservice-tier-1

spec.key

spec.key is the gate name your PromotionStrategy checks in activeCommitStatuses. When omitted, the CRD default is argocd-health. We recommend setting spec.key explicitly (including argocd-health when that is your gate name) so it matches your PromotionStrategy and your manifests are ready if the field becomes required in v1.0; see Roadmap.

Reference the same key in the PromotionStrategy:

apiVersion: promoter.argoproj.io/v1alpha1
kind: PromotionStrategy
metadata:
  name: argocon-demo
spec:
  activeCommitStatuses:
    - key: argocd-health  # same as ArgoCDCommitStatus.spec.key
  environments:
    - branch: environments/development
    - branch: environments/staging
    - branch: environments/production
  gitRepositoryRef:
    name: webservice-tier-1

Commit Status URL Template

To configure setting the url of a commit status, for example, a link to an Argo CD instance, set the url.template field. The template uses Go templates syntax and most Sprig functions (excluding env, expandenv and getHostByName) are supported as well as an additional urlQueryEscape function for escaping url query parameters. The template receives .Environment and .ArgoCDCommitStatus variables.

Important

The rendered URL must use a scheme of either 'http' or 'https'

Template Variables

The following variables are available in the template:

  • .Environment - string holding the environment name (i.e. environment branch name) for the group of Applications the URL is being generated for.
  • .ArgoCDCommitStatus - holds the whole CR in its current state

Template Options

Template options can be configured for how missing variables are handled. Can be one of:

  • missingkey=default or missingkey=invalid - The default behavior: Do nothing and continue execution. If printed, the result of the index operation is the string "".
  • missingkey=zero - The operation returns the zero value for the map type's element.
  • missingkey=error - Execution stops immediately with an error.
apiVersion: promoter.argoproj.io/v1alpha1
kind: ArgoCDCommitStatus
metadata:
  name: webservice-tier-1
spec:
  url: 
    template: ...
    options:
      - missingkey=zero

Examples

Simple url

apiVersion: promoter.argoproj.io/v1alpha1
kind: ArgoCDCommitStatus
metadata:
  name: argocdcommitstatus-sample
spec:
  applicationSelector:
    matchLabels:
      app: demo
  promotionStrategyRef:
    name: argocon-demo
  url:
    template: https://argocd.local

Single environment that filters applications by label selector.

apiVersion: promoter.argoproj.io/v1alpha1
kind: ArgoCDCommitStatus
metadata:
  name: argocdcommitstatus-sample
spec:
  key: argocd-health
  applicationSelector:
    matchLabels:
      app: demo
  promotionStrategyRef:
    name: argocon-demo
  url:
    template: |
      {{- $baseURL := "https://argocd.local" -}}
      {{- $labels := "" -}}
      {{- range $key, $value := .ArgoCDCommitStatus.Spec.ApplicationSelector.MatchLabels -}}
      {{- $labels = printf "%s%s=%s," $labels $key $value -}}
      {{- end -}}
      {{- printf "%s/applications?labels=%s" $baseURL (urlQueryEscape $labels) -}}

Multi-cluster environment that filters applications by label selector and environment.

apiVersion: promoter.argoproj.io/v1alpha1
kind: ArgoCDCommitStatus
metadata:
  name: argocdcommitstatus-sample
spec:
  # Gate key for PromotionStrategy; default argocd-health
  key: argocd-health
  applicationSelector:
    matchLabels:
      app: demo
  promotionStrategyRef:
    name: argocon-demo
  url:
    template: |
      {{- $baseURL := "https://dev.argocd.local" -}}
      {{- if eq .Environment "environment/development" -}}
      {{- $baseURL = "https://dev.argocd.local" -}}
      {{- else if eq .Environment "environment/staging" -}}
      {{- $baseURL = "https://staging.argocd.local" -}}
      {{- else if eq .Environment "environment/production" -}}
      {{- $baseURL = "https://prod.argocd.local" -}}
      {{- end -}}
      {{- $labels := "" -}}
      {{- range $key, $value := .ArgoCDCommitStatus.Spec.ApplicationSelector.MatchLabels -}}
      {{- $labels = printf "%s%s=%s," $labels $key $value -}}
      {{- end -}}
      {{- printf "%s/applications?labels=%s" $baseURL (urlQueryEscape $labels) -}}
    options:
      - missingkey=zero
status:
  observedGeneration: 123 # compare with metadata.generation to detect stale status
  conditions:
    # The Ready condition indicates that the resource has been successfully reconciled, when there is an error during
    # reconciliation, the condition will be False with a reason of ReconciliationError. When we successfully reconcile the resource,
    # the condition will be True with a reason of ReconciliationSuccess. The Ready condition is essentially a way to show reconciliation
    # errors to the user. This condition exists on all resources that have reconciliation logic.
    - type: Ready
      lastTransitionTime: 2023-10-01T00:00:00Z
      message: Reconciliation succeeded
      reason: ReconciliationSuccess # ReconciliationSuccess, ReconciliationError, or CommitStatusesNotReady
      status: "True" # "True," "False," or "Unknown"
      observedGeneration: 123
  # applicationsSelected is a list of applications that match the applicationSelector.
  applicationsSelected:
    - environment: environments/dev
      name: example-app-name
      namespace: example-app-namespace
      phase: success # pending, success, or failure
      sha: abcdef1234567890abcdef1234567890abcdef12
      lastTransitionTime: 2023-10-01T00:00:00Z
      clusterName: "" # an empty cluster name means "local cluster"
    - environment: environments/prod
      name: example-app-name
      namespace: example-app-namespace
      phase: success # pending, success, or failure
      sha: abcdef1234567890abcdef1234567890abcdef12
      lastTransitionTime: 2023-10-01T00:00:00Z
      clusterName: "prod"

Using Standard Argo CD Applications (without Source Hydrator)

The controller also supports standard Argo CD Applications that don't use the Source Hydrator. In this case, the spec.source.targetRevision field is used as the environment identifier:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-staging
  labels:
    app: my-app
spec:
  source:
    repoURL: https://github.com/myorg/myrepo
    targetRevision: environments/staging  # This becomes the environment identifier
    path: manifests
    helm:
      valueFiles:
        - values.yaml
  destination:
    server: https://kubernetes.default.svc
    namespace: my-app
  syncPolicy:
    automated:
      selfHeal: true
      prune: true

The ArgoCDCommitStatus configuration remains the same:

apiVersion: promoter.argoproj.io/v1alpha1
kind: ArgoCDCommitStatus
metadata:
  name: my-app
spec:
  promotionStrategyRef:
    name: my-app-strategy
  applicationSelector:
    matchLabels:
      app: my-app
  # Optional. Defaults to argocd-health.
  key: argocd-health-my-app

Multi-Cluster Support

GitOps promoter can monitor Argo CD Applications across multiple Kubernetes clusters. This is particularly useful when managing promotions across environments that use different Argo CD instances.

Multi-Cluster Prerequisites

To enable multi-cluster support, you need to configure two components:

Kubeconfig Secret

  • Create a secret with key kubeconfig containing a standard ~/.kube/config file as its value and label sigs.k8s.io/multicluster-runtime-kubeconfig: "true"
  • The secret must be created in the same namespace where gitops-promoter runs
  • The controller uses the current context from the kubeconfig to determine which cluster to use
  • Remove any additional clusters from the kubeconfig as they will be ignored

RBAC Configuration

  • Create a ClusterRole and binding in the external cluster for the service account associated with the kubeconfig
  • The service account requires the following permissions:
rules:
- apiGroups:
  - argoproj.io
  resources:
  - applications
  verbs:
  - get
  - list
  - watch

Helper Script

Use this helper script to automate the secret creation and RBAC setup process

  Usage: ./create-kubeconfig-secret-rbac.sh [options]
  --secret-name NAME      Name for the secret (defaults to target context name)
  --secret-context CONTEXT Context where the secret should be created (defaults to target context)
  --secret-namespace NS    Namespace where the secret should be created (defaults to target namespace)
  --target-context CONTEXT  Kubeconfig context to use for service account (required)
  --target-namespace NS    Namespace to create the service account in (default namespace: default)
  --service-account NAME  Name of the service account to create (default: argocd-app-viewer)
  -h, --help              Show this help message

  Example: ./create-kubeconfig-secret-rbac.sh --target-context remote-cluster --target-namespace argocd --secret-context promoter-cluster --secret-namespace promoter