Stage 4 · Provision
GitOps Workflows
ArgoCD Deep Dive
Applications, projects, app-of-apps, and progressive delivery — GitOps for Kubernetes.
What Is ArgoCD?
ArgoCD is a declarative GitOps continuous delivery tool for Kubernetes. It monitors Git repositories for changes and automatically syncs the desired state to Kubernetes clusters. ArgoCD is deployed as a set of containers in the target cluster.
ArgoCD supports Helm charts, Kustomize applications, plain YAML manifests, and Jsonnet. It provides a web UI, CLI, and API for managing deployments. It is a CNCF graduated project.
Architecture
ArgoCD has three main components: the API server (web UI and API), the repo server (fetches Git repos), and the application controller (manages sync operations). All run inside the Kubernetes cluster.
$ kubectl create namespace argocd
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Get the initial admin password
$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -dThe install command creates all ArgoCD resources in the argocd namespace. The initial admin password is stored in a Kubernetes secret. Change it after first login.
Applications
An ArgoCD Application defines a Git repository, a target revision (branch, tag, or commit), a path within the repo, and a destination cluster and namespace. ArgoCD continuously monitors the repo and syncs changes to the cluster.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/k8s-manifests.git
targetRevision: main
path: apps/my-app
destination:
server: https://kubernetes.default.svc
namespace: my-app
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueThe Application resource tells ArgoCD to watch the apps/my-app path in the k8s-manifests repo. The automated sync policy enables automatic deployment when changes are detected. prune deletes resources removed from Git. selfHeal reverts manual changes.
$ argocd app create my-app \
--repo https://github.com/org/k8s-manifests.git \
--path apps/my-app \
--dest-server https://kubernetes.default.svc \
--dest-namespace my-app \
--sync-policy automated \
--auto-prune \
--self-healThe CLI provides a shorthand for creating applications. The flags mirror the YAML properties. Use --sync-policy automated for automatic deployments and --auto-prune to remove orphaned resources.
Projects
ArgoCD Projects scope applications to specific repositories, clusters, and namespaces. They provide RBAC boundaries — each project can have its own permissions, source repos, and destination clusters.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production
namespace: argocd
spec:
description: Production applications
sourceRepos:
- 'https://github.com/org/k8s-manifests.git'
destinations:
- namespace: 'prod-*'
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: ''
kind: Namespace
roles:
- name: deployer
policies:
- p, proj:production:deployer, applications, sync, production/*, allowThe project restricts which repos, destinations, and resources are allowed. Applications in the production project can only deploy to prod-* namespaces. The role defines who can sync applications.
App of Apps
The App of Apps pattern uses a root Application to manage child Applications. The root Application points to a directory containing Application manifests. ArgoCD creates and syncs the child Applications automatically.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/k8s-manifests.git
targetRevision: main
path: apps
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: trueThe root-app points to the apps directory. Any Application manifest in that directory is created by ArgoCD. Adding a new Application file to the directory creates a new deployment. Removing the file prunes the Application.
Sync Options
- CreateNamespace=true — Creates the target namespace if it does not exist.
- Prune=true — Removes resources deleted from Git.
- SelfHeal=true — Reverts manual changes to match Git.
- Force=true — Force applies resources even if ownership conflicts exist.
- SkipDryRunOnMissingCluster=true — Skips dry-run if the cluster is unreachable.
- RespectIgnoreDifferences=true — Preserves fields specified in ignoreDifferences.
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicasThe ignoreDifferences block tells ArgoCD to ignore changes to specific fields. This is essential for fields managed by HPA (replicas) or other controllers. Without this, ArgoCD would fight the HPA over replica count.
Webhooks and Notifications
ArgoCD can receive webhooks from GitHub, GitLab, or Bitbucket to trigger immediate syncs instead of polling. The notification service sends alerts to Slack, email, or other channels on sync events.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
trigger.on-sync-succeeded: |
- when: app.status.operationState.phase in ['Succeeded']
send: [slack-success]
template.slack-success: |
message: |
Application {{.app.metadata.name}} synced successfully.
Revision: {{.app.status.sync.revision}}The notification configuration defines triggers and templates. The trigger fires when the sync phase matches. The template formats the notification message. Multiple notification services (Slack, email, webhook) can be configured.
ArgoCD sync waves control the order of resource deployment. Add the argocd.argoproj.io/sync-wave annotation with a negative number for resources that should deploy first (like namespaces and CRDs).
Automated sync with selfHeal means every Git commit deploys automatically. For production, consider manual sync with automated pruning. This gives you the safety of Git without automatic deployment.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.