Application
ApplicationCRD is an ArgoCD construct that contains a logical collection of kubernetes resources.- the
Applicationis the smallest unit of work in ArgoCD and is where Argo interfaces with kubernetes in order to deploy objects - the most significant parts of the
Applicationresource are thespec.sourceandspec.destinationspec: destination: namespace: snake server: https://kubernetes.default.svc source: helm: valueFiles: - values.yaml path: helm-charts/snake repoURL: https://github.com/rnemeth90/homelab.git targetRevision: HEAD - ArgoCD also supports a
sources(plural) field where you can specify multiple sources
Sync Policy
spec:
syncPolicy:
syncOptions:
- Validate=true
- CreateNamespace=true
- Replace=false ##... etc
- ApplyOutOfSyncOnly=true # only update resources in the app that have changed
automated:
prune: true
selfHeal: true
allowEmpty: false
- Sync policy options can be applied to individual resources, not just the entire
Application-
You just need to add an annotation to the resource with the sync policy
metadata: annotations: argocd.argoproj.io/sync-options: Validate=false -
the options available via the sync policy annotations are:
ValidatePruneLastReplaceServerSideApply
-
Sync Order and Hooks
-
https://argo-cd.readthedocs.io/en/stable/user-guide/sync-waves/
-
ArgoCD has the ability to setup different sync phases by allowing the user to utilize hooks.
-
Imagine you have a directory full of kubernetes manifest files. If you run
kubectl apply, k8s will try to create everything at once. This may be bad. Maybe you have a deployment that is dependent on a database or cache running in a statefulset. Maybe the deployment has health probes, and those probes reach out to the statefulset at some point in their execution path. What happens? The application pods will continually restart until the until statefulset comes up. -
Sync Hooks allow you to create an ArgoCD deployment playbook. You can define how your resources are created, updated, and deleted.
-
Stages of a Sync Hook
- Presync - Database migrations, backups, etc. Anything you want to run BEFORE the main sync
- Sync - The main sync process. ArgoCD waits here until resources are healthy for a configurable amount of time.
- PostSync - Runs after the
syncsucceeds and all resources are healthy - SyncFail - Runs only if a syncoperation has failed. Normally used for alerting or garbage collection.
- PostDelete - Used for any cleanup tasks after all other resources have been deleted
-
every stage of a sync hook relies on the success of the previous stage (with the exception of the SyncFail phase)
-
Sync hooks are defined within your existing kubernetes manifests. You just add a single annotation:
metadata: annotations: argocd.argoproj.io/hook: PreSync -
You also need to define a cleanup policy for the sync hook:
metadata: annotations: argocd.argoproj.io/hook: PreSync argocd.argoproj.io/hook-delete-policy: HookSucceeded- There are several policies you can use.
HookFailedwill only delete the resources if the hook fails.
- There are several policies you can use.
Sync Waves
- Sync waves are used to define an order of operations to your kubernetes deployed.
- Sync waves are defined in the
annotationssection of your manifests. - Sync waves work best when proper health checks are created for the application
- Lower number go first
- “0” is the default value
- You can even combine sync hooks and waves. This example would run in the 3rd wave of the PreSync hook:
metadata: annotations: argocd.argoproj.io/hook: PreSync argocd.argoproj.io/sync-wave: 3
Example Application (the important bits are source and destination)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
creationTimestamp: "2026-08-17T20:21:14Z"
finalizers:
- resources-finalizer.argocd.argoproj.io
generation: 21183
name: snake
namespace: argocd
ownerReferences:
- apiVersion: argoproj.io/v1alpha1
blockOwnerDeletion: true
controller: true
kind: ApplicationSet
name: helm-charts
uid: fb81928e-bce5-4efc-be70-380e17069785
resourceVersion: "328662005"
uid: 1eb74018-b72e-4492-95b5-e4f18e921a06
spec:
destination:
namespace: snake
server: https://kubernetes.default.svc
ignoreDifferences:
- group: apps
jqPathExpressions:
- .spec.template.spec.hostUsers
kind: Deployment
name: headlamp
namespace: headlamp
project: default
source:
helm:
valueFiles:
- values.yaml
path: helm-charts/snake
repoURL: https://github.com/rnemeth90/homelab.git
targetRevision: HEAD
syncPolicy:
automated:
prune: true
selfHeal: true
retry:
backoff:
duration: 5s
factor: 2
maxDuration: 3m
limit: 5
syncOptions:
- CreateNamespace=true
Application Health
-
ArgoCD continuously monitors
Application’s. AnApplicationcan be in one of the following health states: -
Health statuses:
- Healthy - the resource is healthy
- Progressing - the resource is attempting to become healthy by syncing
- Degraded - the resource has failed or otherwise become unhealthy
- Missing - the resource is not installed in the cluster
- Suspended - the resource is suspended or ‘paused’
- Unknown - WTF?
-
You can also create custom health checks by editing the
argocd-cmconfig map. You can useLuato specify the custom health check:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
resource.customizations.health.argoproj.io_Application: |
hs = {}
hs.status = "Progressing"
hs.message = ""
if obj.status ~= nil then
if obj.status.health ~= nil then
hs.status = obj.status.health.status
if obj.status.health.message ~= nil then
hs.message = obj.status.health.message
end
end
end
return hs
Behavior of ArgCD Applications when Source is a helm chart
- When argo deploys a helm chart, the helm chart itself is not actually deployed to the cluster. Meaning, you cannot connect to the cluster and expect to see the chart listed in the output of
helm ls. Argo prefers to manage theYAMLof all applications. So before deploying the helm chart, it runshelm templateagainst the chart to generate the Kubernetes manifests, and then deploys those manifests.
Deleting Applications
- When you delete an
Applicationin Argo, you will find that the resources running in Kubernetes are not deleted. Argo takes the stance (like PersistentVolumes) that certain resources should be cleaned up manually to prevent data loss. If you choose, you can tell Argo to automatically delete the resources when the associatedApplicationis deleted by adding afinalizersfield to theApplication:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
creationTimestamp: "2026-08-17T20:21:14Z"
finalizers:
- resources-finalizer.argocd.argoproj.io
generation: 21183
name: snake
namespace: argocd
ownerReferences:
- apiVersion: argoproj.io/v1alpha1
blockOwnerDeletion: true
controller: true
kind: ApplicationSet
name: helm-charts
uid: fb81928e-bce5-4efc-be70-380e17069785
resourceVersion: "328662005"
uid: 1eb74018-b72e-4492-95b5-e4f18e921a06
spec:
destination:
namespace: snake
server: https://kubernetes.default.svc
source:
helm:
valueFiles:
- values.yaml
path: helm-charts/snake
repoURL: https://github.com/rnemeth90/homelab.git
targetRevision: HEAD
finalizers:
- resources-finalizer.argocd.argoproj.io/background #OR Foreground (see the next line below)
- resources-finalizer.argocd.argoproj.io/foreground
App Project
- With an ArgoCD Project, administrators can:
- Manage RBAC on a per-project basis
- restrict the sources of content (github, helm, etc.)
- Restrict where ArgoCD apps can be deployed to
- Restrict which kubernetes objects can be deployed
- ArgoCD includes a project named
default, which allows deployment of any resource to any cluster by anyone. You cannot delete thedefaultproject, but you can lock it down. - An ArgoCD
Applicationcan only ever belong to one project