Skip to main content
Argo CD provides flexible strategies for tracking application sources and deployed resources. Understanding these strategies helps you implement effective deployment workflows for different environments.

Git Tracking Strategies

Argo CD supports multiple ways to track your Git repository, each suited for different use cases.

HEAD / Branch Tracking

Track the tip of a branch for continuous deployment:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  source:
    repoURL: https://github.com/example/app.git
    targetRevision: main  # or HEAD
    path: manifests
Use cases:
  • Development environments
  • Continuous deployment pipelines
  • Automatic updates on every commit
How it works: Argo CD continuously monitors the branch and compares live state against the latest commit. Any new commit triggers a comparison (and sync if auto-sync is enabled).
With auto-sync enabled, every push to the tracked branch automatically deploys to your cluster.

Tag Tracking

Track a specific Git tag for more stable deployments:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  source:
    repoURL: https://github.com/example/app.git
    targetRevision: v1.2.3
    path: manifests
Use cases:
  • Staging environments
  • Release-based deployments
  • Controlled updates
How it works: Argo CD uses manifests at the specified tag. To deploy a new version, retag or change the Application’s targetRevision.
If you retag the same tag name to a different commit, Argo CD will detect the change and sync accordingly.

Semantic Version Ranges

Automatically track the latest version within a range:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  source:
    repoURL: https://github.com/example/app.git
    targetRevision: 1.2.*  # Tracks latest 1.2.x version
    path: manifests
Version range examples:
Use CaseRangeExample Matches
Pin to version1.2.3Only 1.2.3
Track patches1.2.* or >=1.2.0 <1.3.01.2.0, 1.2.1, 1.2.5
Track minor releases1.* or >=1.0.0 <2.0.01.0.0, 1.5.2, 1.9.0
Use latest* or >=0.0.0All stable versions
Include prereleases*-0 or >=0.0.0-0All versions including alpha, beta
By default, prerelease versions (alpha, beta, rc) are excluded. Use the -0 suffix to include them.
Examples:
# Production: Pin to specific version
targetRevision: 2.1.0

# Pre-production: Track patch releases
targetRevision: 2.1.*

# QA: Track minor releases
targetRevision: 2.*

# Development: Use latest including prereleases
targetRevision: "*-0"

Commit SHA Pinning

Pin to a specific commit for maximum control:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  source:
    repoURL: https://github.com/example/app.git
    targetRevision: 9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b
    path: manifests
Use cases:
  • Production environments
  • Strict change control
  • Compliance requirements
How it works: Commit SHAs are immutable. The only way to change deployment is to update the Application’s targetRevision to a different commit SHA.
Parameter overrides still apply even with commit pinning.

Handling Ambiguous Git References

When a branch and tag share the same name, use fully-qualified references: Problem scenario:
refs/heads/release-1.0 -> commit B
refs/tags/release-1.0  -> commit A
If targetRevision: release-1.0, Argo CD may resolve to either commit, causing reconciliation loops. Solution: Use fully-qualified references:
# For branch
targetRevision: refs/heads/release-1.0

# For tag
targetRevision: refs/tags/release-1.0
Avoid using the same name for branches and tags to prevent ambiguity.

Helm Chart Tracking

Helm charts use semantic versioning:
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  source:
    repoURL: https://charts.example.com
    chart: my-app
    targetRevision: 1.2.*  # Track patches
    helm:
      releaseName: my-app
Version tracking examples:
# Pin to exact version (production)
targetRevision: 1.2.3

# Track patch updates (staging)
targetRevision: 1.2.*

# Track minor updates (QA)
targetRevision: 1.*

# Use latest stable
targetRevision: "*"

# Include prereleases
targetRevision: "*-0"

Resource Tracking Methods

Argo CD tracks deployed resources using labels or annotations.

Annotation-Based Tracking (Default)

Uses the argocd.argoproj.io/tracking-id annotation:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  namespace: default
  annotations:
    argocd.argoproj.io/tracking-id: my-app:apps/Deployment:default/my-deployment
spec:
  # ...
Advantages:
  • No conflicts with other tools
  • No 63-character truncation limit
  • Clear ownership per Argo CD instance
Configure in argocd-cm:
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  application.resourceTrackingMethod: annotation

Annotation + Label Tracking

Uses annotation for tracking, adds label for compatibility:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  namespace: default
  labels:
    app.kubernetes.io/instance: my-app  # For tool compatibility
  annotations:
    argocd.argoproj.io/tracking-id: my-app:apps/Deployment:default/my-deployment  # For tracking
spec:
  # ...
Configure:
data:
  application.resourceTrackingMethod: annotation+label
The label is informational only and truncated if longer than 63 characters. Tracking uses the annotation.

Label-Based Tracking (Legacy)

Uses the app.kubernetes.io/instance label:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  namespace: default
  labels:
    app.kubernetes.io/instance: my-app
spec:
  # ...
Limitations:
  • 63-character label limit
  • Potential conflicts with other tools
  • Difficult to run multiple Argo CD instances
Configure:
data:
  application.resourceTrackingMethod: label

Custom Label

Use a custom label instead of the default:
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  application.instanceLabelKey: argocd.argoproj.io/instance

Installation ID

Run multiple Argo CD instances on the same cluster:
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  application.resourceTrackingMethod: annotation
  # Unique identifier for this Argo CD instance
  argocd.argoproj.io/installation-id: production-argocd
Benefits:
  • Each resource gets: argocd.argoproj.io/installation-id: production-argocd
  • Prevents conflicts between instances
  • Allows multiple apps with the same name

Non-Self-Referencing Annotations

When using annotation-based tracking, resources can be copied to other namespaces without affecting sync status:
# Original resource in namespace 'default'
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
  namespace: default
  annotations:
    argocd.argoproj.io/tracking-id: my-app:/ConfigMap:default/my-config
data:
  key: value
If a tool copies this to namespace other:
# Copied resource in namespace 'other'
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
  namespace: other  # Different namespace
  annotations:
    argocd.argoproj.io/tracking-id: my-app:/ConfigMap:default/my-config  # Still references 'default'
data:
  key: value
Argo CD won’t track the copied resource because the tracking annotation references a different namespace.

Tracking Strategy Examples

Development Environment

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: app-dev
  namespace: argocd
spec:
  project: default
  
  source:
    repoURL: https://github.com/example/app.git
    targetRevision: HEAD  # Always latest
    path: manifests/dev
  
  destination:
    server: https://kubernetes.default.svc
    namespace: dev
  
  syncPolicy:
    automated:
      enabled: true
      prune: true
      selfHeal: true  # Auto-fix manual changes

Staging Environment

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: app-staging
  namespace: argocd
spec:
  project: default
  
  source:
    repoURL: https://github.com/example/app.git
    targetRevision: 1.2.*  # Track patch releases
    path: manifests/staging
  
  destination:
    server: https://kubernetes.default.svc
    namespace: staging
  
  syncPolicy:
    automated:
      enabled: true
      prune: true

Production Environment

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: app-prod
  namespace: argocd
spec:
  project: default
  
  source:
    repoURL: https://github.com/example/app.git
    targetRevision: v1.2.3  # Pinned version
    path: manifests/prod
  
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  
  # Manual sync only
  syncPolicy: {}

Helm Chart with Version Range

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx-ingress
  namespace: argocd
spec:
  project: default
  
  source:
    repoURL: https://kubernetes.github.io/ingress-nginx
    chart: ingress-nginx
    targetRevision: 4.7.*  # Track patches in 4.7.x
    helm:
      releaseName: nginx-ingress
      parameters:
      - name: controller.service.type
        value: LoadBalancer
  
  destination:
    server: https://kubernetes.default.svc
    namespace: ingress
  
  syncPolicy:
    automated:
      enabled: true

Automatic Sync Behavior

With auto-sync enabled:
syncPolicy:
  automated:
    enabled: true
    prune: true
    selfHeal: true
Sync triggers:
  • New commit to tracked branch
  • Tag update (if tracking a tag)
  • New version matching semantic range
  • Manual changes in cluster (if selfHeal: true)
Sync semantics:
  • Only syncs when OutOfSync
  • Won’t retry if previous sync to same commit failed
  • Retries after self-heal timeout (5s default) if selfHeal: true
Parameter overrides always take precedence over Git state.

Changing Tracking Methods

To switch tracking methods:
  1. Update argocd-cm ConfigMap:
    data:
      application.resourceTrackingMethod: annotation  # or annotation+label, label
    
  2. Sync all applications to apply new tracking method:
    argocd app sync --all
    
  3. Argo CD will add the new tracking identifier to resources
You can safely revert to a previous tracking method by updating the ConfigMap and re-syncing.

Best Practices

Match Strategy to Environment

Use HEAD for dev, ranges for staging, pins for production

Use Annotation Tracking

Avoid label conflicts and truncation issues

Avoid Ambiguous References

Don’t use same name for branches and tags

Semantic Versioning

Use semver tags for predictable version tracking

Troubleshooting

Application Not Detecting Changes

  1. Verify target revision:
    argocd app get my-app
    
  2. Check if tracking a branch:
    git rev-parse origin/main
    
  3. Force refresh:
    argocd app refresh my-app
    

Resources Not Tracked

  1. Check tracking annotation:
    kubectl get deployment my-app -o yaml | grep tracking-id
    
  2. Verify tracking method in ConfigMap:
    kubectl get configmap argocd-cm -n argocd -o yaml | grep resourceTrackingMethod
    
  3. Re-sync application to apply tracking:
    argocd app sync my-app
    

Version Range Not Working

  1. Verify tags exist:
    git ls-remote --tags https://github.com/example/app.git
    
  2. Check if tags are semver:
    # Valid: v1.2.3, 1.2.3
    # Invalid: release-1.2.3
    
  3. Include prereleases if needed:
    targetRevision: "1.2.*-0"
    

Next Steps

Sync Options

Configure how applications sync

Sync Waves

Control deployment order

Creating Apps

Learn how to create applications

Health Checks

Monitor application health

Build docs developers (and LLMs) love