ArgoCD Applications & Projects
Applications are the core resource in ArgoCD. An Application represents a set of Kubernetes resources that should be deployed from a Git repository, Helm chart, or other source to a destination cluster and namespace.
What is an Application?
An Application is a Custom Resource Definition (CRD) that tells ArgoCD:
- Source - Where to get the manifests (Git repo, Helm chart, etc.)
- Destination - Where to deploy (cluster and namespace)
- Sync Policy - How to sync (automated or manual)
- Health - How to determine if the application is healthy
Creating Applications
Method 1: Declarative (YAML)
The recommended approach is to define Applications as YAML manifests:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: web-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/kubernetes-manifests
targetRevision: main
path: apps/web-app
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Apply the Application:
kubectl apply -f application.yaml
Method 2: Using ArgoCD CLI
argocd app create web-app \
--repo https://github.com/your-org/kubernetes-manifests \
--path apps/web-app \
--dest-server https://kubernetes.default.svc \
--dest-namespace production \
--sync-policy automated \
--auto-prune \
--self-heal
Method 3: Using ArgoCD UI
- Click “New App” button
- Fill in application details:
- Application Name
- Project
- Source (Repository URL, Path, Revision)
- Destination (Cluster, Namespace)
- Click “Create”
Application Spec Structure
Basic Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/user/repo
targetRevision: HEAD
path: manifests
destination:
server: https://kubernetes.default.svc
namespace: default
Application with Helm Chart
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx
namespace: argocd
spec:
project: default
source:
repoURL: https://charts.bitnami.com/bitnami
chart: nginx
targetRevision: 13.2.20
helm:
values: |
service:
type: LoadBalancer
replicaCount: 3
destination:
server: https://kubernetes.default.svc
namespace: default
Application with Kustomize
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: kustomize-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/user/repo
targetRevision: main
path: kustomize/base
kustomize:
images:
- nginx:1.21.0
commonAnnotations:
app.kubernetes.io/managed-by: argocd
destination:
server: https://kubernetes.default.svc
namespace: default
Application with Multiple Sources
ArgoCD supports applications with multiple sources (e.g., Helm chart + additional manifests):
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: multi-source-app
namespace: argocd
spec:
project: default
sources:
- repoURL: https://charts.bitnami.com/bitnami
chart: nginx
targetRevision: 13.2.20
helm:
values: |
service:
type: ClusterIP
- repoURL: https://github.com/user/repo
targetRevision: main
path: additional-configs
destination:
server: https://kubernetes.default.svc
namespace: default
Application Lifecycle
Application States
- Unknown - Initial state, not yet synced
- Syncing - Currently applying changes
- Progressing - Resources being created/updated
- Healthy - All resources are healthy and in sync
- Degraded - Some resources are unhealthy
- Suspended - Application sync is paused
- OutOfSync - Desired state differs from actual state
Application Health
ArgoCD determines application health based on resource health:
Built-in Health Checks
ArgoCD has built-in health checks for:
- Deployment - Checks if replicas match desired count
- StatefulSet - Checks if replicas match desired count
- DaemonSet - Checks if pods are scheduled
- Service - Always healthy (no runtime health)
- Pod - Checks phase (Running, Pending, Failed)
- Job - Checks completion status
- PersistentVolumeClaim - Checks if bound
Custom Health Checks
Define custom health checks using Lua scripts:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations.health.argoproj.io_Application: |
hs = {}
if obj.status ~= nil then
if obj.status.health ~= nil then
hs.status = obj.status.health.status
hs.message = obj.status.health.message
else
hs.status = "Progressing"
hs.message = "Waiting for health status"
end
else
hs.status = "Unknown"
hs.message = "No status available"
end
return hs
Application Sync
Manual Sync
Sync an application manually:
# Sync application
argocd app sync web-app
# Sync with specific revision
argocd app sync web-app --revision <COMMIT_HASH>
# Sync with prune (delete resources not in Git)
argocd app sync web-app --prune
# Sync with force (bypass hooks)
argocd app sync web-app --force
Automated Sync
Enable automated sync in the Application spec:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: web-app
namespace: argocd
spec:
syncPolicy:
automated:
prune: true # Delete resources removed from Git
selfHeal: true # Automatically sync on cluster drift
allowEmpty: false # Allow apps with no resources
Sync Options
Configure sync behavior:
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true # Create namespace if missing
- PruneLast=true # Prune resources last
- PrunePropagationPolicy=foreground
- RespectIgnoreDifferences=true
- ApplyOutOfSyncOnly=true # Only sync out-of-sync resources
ApplicationSets
ApplicationSets manage multiple Applications from a single definition. Useful for:
- Multiple environments (dev, staging, prod)
- Multiple clusters
- Multiple applications with similar configs
List ApplicationSet
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: web-apps
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: production
url: https://prod.example.com
namespace: prod
- cluster: staging
url: https://staging.example.com
namespace: staging
template:
metadata:
name: '{{cluster}}-web-app'
spec:
project: default
source:
repoURL: https://github.com/user/repo
targetRevision: main
path: apps/web-app
destination:
server: '{{url}}'
namespace: '{{namespace}}'
syncPolicy:
automated:
prune: true
selfHeal: true
Cluster Generator
Generate applications for multiple clusters:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: multi-cluster-app
namespace: argocd
spec:
generators:
- clusters:
selector:
matchLabels:
environment: production
template:
metadata:
name: '{{name}}-app'
spec:
project: default
source:
repoURL: https://github.com/user/repo
targetRevision: main
path: apps/my-app
destination:
server: '{{server}}'
namespace: default
Git Directory Generator
Generate applications from Git directory structure:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: git-directory-apps
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/user/repo
revision: main
directories:
- path: apps/*
template:
metadata:
name: '{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/user/repo
targetRevision: main
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
Projects
Projects provide a way to group Applications and enforce policies.
Project Structure
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production
namespace: argocd
spec:
description: Production applications
sourceRepos:
- 'https://github.com/your-org/*'
- 'https://charts.bitnami.com/bitnami'
destinations:
- namespace: production
server: https://kubernetes.default.svc
- namespace: '*'
server: https://prod-cluster.example.com
clusterResourceWhitelist:
- group: '*'
kind: '*'
namespaceResourceWhitelist:
- group: '*'
kind: '*'
Project Restrictions
Projects can restrict:
- Source Repositories - Which Git repos can be used
- Destinations - Which clusters/namespaces can be targeted
- Resources - Which Kubernetes resources can be deployed
- Sync Windows - When syncs are allowed
Example: Restricted Project
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: restricted
namespace: argocd
spec:
description: Restricted project with limited permissions
sourceRepos:
- 'https://github.com/your-org/approved-repo'
destinations:
- namespace: staging
server: https://kubernetes.default.svc
namespaceResourceWhitelist:
- group: apps
kind: Deployment
- group: v1
kind: Service
- group: v1
kind: ConfigMap
# Deny all cluster-scoped resources
clusterResourceWhitelist: []
Sync Windows
Define when Applications can be synced:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production
namespace: argocd
spec:
syncWindows:
- kind: allow
schedule: '0 9 * * 1-5' # Weekdays 9 AM
duration: 8h
applications:
- 'production-*'
- kind: deny
schedule: '* * * * *' # All other times
applications:
- 'production-*'
Managing Applications
View Application Status
# List all applications
argocd app list
# Get application details
argocd app get web-app
# Watch application status
argocd app get web-app --watch
# Get application resources
argocd app resources web-app
Application Operations
# Sync application
argocd app sync web-app
# Delete application (keeps resources in cluster)
argocd app delete web-app
# Delete application and resources
argocd app delete web-app --cascade
# Suspend application (pause sync)
argocd app suspend web-app
# Resume application
argocd app resume web-app
# Rollback to previous version
argocd app rollback web-app <REVISION>
Application History
# View sync history
argocd app history web-app
# View specific revision
argocd app get web-app --revision <REVISION>
Best Practices
1. Use Declarative Applications
Store Application definitions in Git:
# apps/web-app/application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: web-app
namespace: argocd
spec:
# ...
2. Organize with Projects
Use Projects to:
- Group related applications
- Enforce policies
- Limit access
- Define sync windows
3. Use ApplicationSets for Multiple Environments
Instead of creating multiple Applications manually, use ApplicationSets:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: web-app-environments
namespace: argocd
spec:
generators:
- list:
elements:
- env: dev
namespace: dev
- env: staging
namespace: staging
- env: prod
namespace: production
template:
metadata:
name: web-app-{{env}}
spec:
project: default
source:
repoURL: https://github.com/user/repo
targetRevision: main
path: apps/web-app/overlays/{{env}}
destination:
server: https://kubernetes.default.svc
namespace: {{namespace}}
4. Pin Revisions
For production, pin to specific revisions:
spec:
source:
targetRevision: v1.2.3 # Tag
# or
targetRevision: abc123f # Commit hash
5. Use Sync Policies Appropriately
- Automated sync - For development/staging
- Manual sync - For production (with approvals)
- Self-heal - Enable to prevent drift
6. Monitor Application Health
Set up alerts for:
- Application health status
- Sync failures
- OutOfSync state
- Degraded resources
Troubleshooting
Application Stuck in Syncing
# Check application status
argocd app get web-app
# Check application controller logs
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller
# Force sync
argocd app sync web-app --force
Application OutOfSync
# Check what's different
argocd app diff web-app
# View resources
argocd app resources web-app
# Sync to fix
argocd app sync web-app
Health Check Failures
# Get detailed health status
argocd app get web-app --show-operation
# Check resource health
argocd app resources web-app
# Check Kubernetes resources directly
kubectl get all -n <NAMESPACE>
Summary
Applications are the core of ArgoCD, defining what to deploy and where. Key points:
- Applications define source, destination, and sync policy
- Projects group applications and enforce policies
- ApplicationSets manage multiple applications from one definition
- Use declarative Application definitions stored in Git
- Configure sync policies based on environment needs
- Monitor application health and status
Next, learn about Sync Policies to configure automated sync, hooks, and sync windows.