Managing Applications with ArgoCD
ArgoCD applications represent the fundamental unit of deployment, connecting Git repositories to Kubernetes clusters. Effective application management requires understanding configuration options, lifecycle operations, and organizational patterns.
Application Configuration
ArgoCD applications use declarative YAML specifications to define the relationship between Git and Kubernetes.
Basic Application
A minimal application configuration specifies source and destination:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/organization/frontend-manifests
targetRevision: main
path: kubernetes/production
destination:
server: https://kubernetes.default.svc
namespace: production
This application deploys manifests from the kubernetes/production directory to the production namespace in the local cluster.
Source Configuration
Different source types support various manifest formats:
# Plain Kubernetes manifests
source:
repoURL: https://github.com/organization/k8s-manifests
targetRevision: v2.1.0
path: apps/api-service
# Helm chart from Git repository
source:
repoURL: https://github.com/organization/helm-charts
targetRevision: main
path: charts/api-service
helm:
valueFiles:
- values-production.yaml
parameters:
- name: image.tag
value: "v2.1.0"
- name: replicas
value: "5"
# Helm chart from Helm repository
source:
repoURL: https://charts.bitnami.com/bitnami
chart: postgresql
targetRevision: 12.1.2
helm:
values: |
global:
postgresql:
auth:
database: appdb
username: appuser
# Kustomize overlay
source:
repoURL: https://github.com/organization/k8s-manifests
targetRevision: main
path: apps/api-service/overlays/production
Each source type enables ArgoCD to process different manifest formats, from plain YAML to templated Helm charts and Kustomize overlays.
Destination Configuration
Applications deploy to specific clusters and namespaces:
# Deploy to local cluster
destination:
server: https://kubernetes.default.svc
namespace: production
# Deploy to remote cluster by URL
destination:
server: https://prod-cluster.example.com
namespace: production
# Deploy to cluster by name
destination:
name: production-cluster
namespace: production
The destination determines where ArgoCD applies manifests, enabling multi-cluster deployments from a single ArgoCD instance.
graph LR
subgraph Source
G[Git Repository]
H[Helm Repository]
end
subgraph ArgoCD
A[Application Spec]
end
subgraph Destinations
C1[Local Cluster]
C2[Remote Cluster 1]
C3[Remote Cluster 2]
end
G --> A
H --> A
A --> C1
A --> C2
A --> C3
style A fill:#e1f5ff
Sync Policies
Sync policies control how ArgoCD reconciles Git with cluster state.
Manual Sync
Applications require explicit sync actions:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend-app
spec:
project: default
source:
repoURL: https://github.com/organization/frontend-manifests
targetRevision: main
path: kubernetes/production
destination:
server: https://kubernetes.default.svc
namespace: production
# No syncPolicy - manual sync required
Manual sync gives operators full control over when changes deploy. Use this for production environments requiring human approval.
# Trigger manual sync
argocd app sync frontend-app
# Sync with prune (delete removed resources)
argocd app sync frontend-app --prune
# Preview sync without applying
argocd app sync frontend-app --dry-run
Automated Sync
Applications sync automatically when Git changes:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend-app
spec:
project: default
source:
repoURL: https://github.com/organization/frontend-manifests
targetRevision: main
path: kubernetes/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: false # Don't delete resources removed from Git
selfHeal: false # Don't revert manual changes
allowEmpty: false # Prevent syncing when source has no manifests
Automated sync deploys Git changes within minutes, enabling continuous deployment. Configure prune and selfHeal based on environment requirements.
Self-Healing
Automatically revert manual cluster changes:
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Self-healing enforces Git as the source of truth by reverting any manual modifications. When someone scales a deployment manually, ArgoCD restores the replica count from Git.
sequenceDiagram
participant Operator
participant K8s as Kubernetes
participant Argo as ArgoCD
participant Git
Operator->>K8s: kubectl scale deployment --replicas=10
K8s->>K8s: Update replicas to 10
loop Every 3 minutes
Argo->>K8s: Get deployment state
K8s->>Argo: Replicas: 10
Argo->>Git: Get desired state
Git->>Argo: Replicas: 3
Argo->>Argo: Detect drift
Argo->>K8s: Scale deployment to 3
K8s->>K8s: Update replicas to 3
end
Sync Options
Fine-tune sync behavior with sync options.
Common Sync Options
syncPolicy:
syncOptions:
# Create namespace if it doesn't exist
- CreateNamespace=true
# Validate resources before syncing
- Validate=true
# Use server-side apply (better for large resources)
- ServerSideApply=true
# Replace resources instead of applying
- Replace=true
# Skip schema validation
- SkipSchemaValidation=true
# Respect ignore differences
- RespectIgnoreDifferences=true
Sync options customize how ArgoCD applies manifests, handling edge cases like namespace creation or large resource updates.
Selective Sync
Apply only specific resources:
# Sync only deployment resources
argocd app sync frontend-app --resource apps:Deployment:frontend
# Sync multiple specific resources
argocd app sync frontend-app \
--resource apps:Deployment:frontend \
--resource v1:Service:frontend
Selective sync enables surgical updates when full application sync would affect too many resources.
Health Assessment
ArgoCD evaluates application health based on resource status.
Health Status
Applications report overall health:
- Healthy: All resources are healthy and ready
- Progressing: Resources are being created or updated
- Degraded: Some resources are unhealthy
- Suspended: Application is intentionally paused
- Missing: Required resources don't exist
- Unknown: Health cannot be determined
# Check application health
argocd app get frontend-app
# Filter applications by health status
argocd app list --health Degraded
Custom Health Checks
Define health checks for custom resources:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations: |
example.com/MyCustomResource:
health.lua: |
hs = {}
if obj.status ~= nil then
if obj.status.phase == "Ready" then
hs.status = "Healthy"
hs.message = "Resource is ready"
return hs
end
if obj.status.phase == "Failed" then
hs.status = "Degraded"
hs.message = obj.status.message
return hs
end
end
hs.status = "Progressing"
hs.message = "Waiting for resource"
return hs
Custom health checks enable accurate status reporting for CRDs and operators that ArgoCD doesn't understand by default.
Diff Customization
Control how ArgoCD compares Git with cluster state.
Ignore Differences
Exclude specific fields from diff detection:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend-app
spec:
ignoreDifferences:
# Ignore all differences in replicas field
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas
# Ignore webhook configurations (mutated by webhooks)
- group: apps
kind: Deployment
jsonPointers:
- /spec/template/metadata/annotations
# Ignore storage size (can't be decreased)
- group: ""
kind: PersistentVolumeClaim
jsonPointers:
- /spec/resources/requests/storage
Ignoring differences prevents false out-of-sync status for fields that change frequently or are managed by other controllers.
Managed Namespaces
Track additional namespaces beyond the destination:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend-app
spec:
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
managedNamespaceMetadata:
labels:
managed-by: argocd
environment: production
annotations:
description: Production frontend application
Managed namespace metadata ensures ArgoCD tracks namespace-level resources and labels.
Application Operations
Perform various operations on applications.
Rollback
Revert to a previous revision:
# View application history
argocd app history frontend-app
# Rollback to specific revision
argocd app rollback frontend-app 5
# Rollback to previous revision
argocd app rollback frontend-app
Rollback changes the target revision in Git or reverts to a previous sync operation, providing quick recovery from bad deployments.
Refresh
Force ArgoCD to compare Git with cluster state:
# Soft refresh (read cache)
argocd app get frontend-app --refresh
# Hard refresh (bypass cache)
argocd app get frontend-app --hard-refresh
Refresh triggers immediate comparison instead of waiting for the next polling cycle, useful when validating recent Git commits.
Terminate Operation
Cancel an in-progress sync:
# Terminate sync operation
argocd app terminate-op frontend-app
Terminating operations stops a sync that's taking too long or applying incorrect changes.
Application Organization
Structure applications for maintainability and scalability.
Projects
Group applications with Projects:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production-apps
namespace: argocd
spec:
description: Production environment applications
# Allowed source repositories
sourceRepos:
- https://github.com/organization/production-manifests
# Allowed destination clusters
destinations:
- namespace: production
server: https://kubernetes.default.svc
- namespace: production-*
server: https://kubernetes.default.svc
# Allowed resource types
clusterResourceWhitelist:
- group: '*'
kind: '*'
# RBAC policies
roles:
- name: developer
policies:
- p, proj:production-apps:developer, applications, get, production-apps/*, allow
- p, proj:production-apps:developer, applications, sync, production-apps/*, allow
groups:
- dev-team
Projects enforce boundaries, restricting which repositories, namespaces, and resources applications can access, enabling multi-tenant ArgoCD instances.
Application of Applications Pattern
Manage multiple applications with a parent application:
# apps/production.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: production-apps
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/organization/argocd-apps
targetRevision: main
path: applications/production
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
The applications directory contains child applications:
argocd-apps/
└── applications/
└── production/
├── frontend-app.yaml
├── backend-app.yaml
└── database-app.yaml
This pattern simplifies managing many applications by organizing them hierarchically and enabling bulk operations.
graph TD
A[Parent Application: production-apps] --> B[Child: frontend-app]
A --> C[Child: backend-app]
A --> D[Child: database-app]
B --> E[Git: frontend-manifests]
C --> F[Git: backend-manifests]
D --> G[Git: database-manifests]
E --> H[K8s: frontend resources]
F --> I[K8s: backend resources]
G --> J[K8s: database resources]
style A fill:#fff4e6
ApplicationSet
Generate applications dynamically:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-apps
namespace: argocd
spec:
generators:
# Generate from cluster list
- clusters:
selector:
matchLabels:
environment: production
template:
metadata:
name: '{{name}}-frontend'
spec:
project: default
source:
repoURL: https://github.com/organization/frontend-manifests
targetRevision: main
path: kubernetes/production
destination:
server: '{{server}}'
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
ApplicationSet reduces configuration duplication by templating applications across clusters, namespaces, or Git repositories.
Monitoring and Observability
Track application status and performance.
Metrics
ArgoCD exposes Prometheus metrics:
# ServiceMonitor for Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-metrics
namespace: argocd
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-server
endpoints:
- port: metrics
Key metrics include:
argocd_app_info: Application metadataargocd_app_sync_total: Sync operation countargocd_app_health_status: Current health statusargocd_app_sync_status: Current sync status
Logs
Access application controller logs for troubleshooting:
# View application controller logs
kubectl logs -n argocd deployment/argocd-application-controller
# View logs for specific application
kubectl logs -n argocd deployment/argocd-application-controller | grep frontend-app
# View repository server logs
kubectl logs -n argocd deployment/argocd-repo-server
Logs provide detailed information about sync operations, Git fetch errors, and resource application failures.
Common Pitfalls
Excessive Polling: Polling too frequently increases load on Git servers. Default 3-minute interval works for most use cases; avoid reducing below 30 seconds.
No Resource Limits: Large applications without pruning accumulate resources over time. Enable prune: true to delete removed resources automatically.
Ignoring Drift: Disabling self-healing while expecting consistent state creates confusion. Either enforce Git as source of truth with self-healing or accept manual changes.
Flat Application Structure: Managing dozens of applications at the top level becomes unwieldy. Use Projects, App of Apps, or ApplicationSet to organize hierarchically.
Key Takeaways
- Applications connect Git repositories to Kubernetes clusters, supporting plain manifests, Helm charts, and Kustomize overlays
- Configure sync policies for manual approval, automated deployment, or self-healing to revert manual changes
- Use sync options to handle edge cases like namespace creation, server-side apply, or validation
- ArgoCD evaluates application health based on resource status, with custom health checks for CRDs
- Ignore differences in fields that change frequently or are managed by external controllers
- Organize applications using Projects for RBAC boundaries, App of Apps for hierarchical management, or ApplicationSet for dynamic generation
- Monitor applications through Prometheus metrics and controller logs for troubleshooting
- Enable pruning to automatically delete resources removed from Git and avoid resource accumulation