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 Case Range Example Matches Pin to version 1.2.3Only 1.2.3 Track patches 1.2.* or >=1.2.0 <1.3.01.2.0, 1.2.1, 1.2.5 Track minor releases 1.* 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.
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:
Update argocd-cm ConfigMap:
data :
application.resourceTrackingMethod : annotation # or annotation+label, label
Sync all applications to apply new tracking method:
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
Verify target revision:
Check if tracking a branch:
git rev-parse origin/main
Force refresh:
argocd app refresh my-app
Resources Not Tracked
Check tracking annotation:
kubectl get deployment my-app -o yaml | grep tracking-id
Verify tracking method in ConfigMap:
kubectl get configmap argocd-cm -n argocd -o yaml | grep resourceTrackingMethod
Re-sync application to apply tracking:
Version Range Not Working
Verify tags exist:
git ls-remote --tags https://github.com/example/app.git
Check if tags are semver:
# Valid: v1.2.3, 1.2.3
# Invalid: release-1.2.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