An ArgoCD "Application" connects a Git path to a K8s namespace. Sync policies control WHETHER and HOW changes are applied. This lesson teaches you to configure both — the core of GitOps operations.
What Is an ArgoCD Application?
🏋️ Step 1: Populate the GitOps Repo
In your cicd-mastery-gitops repo, create Kustomize-based manifests:
base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: cicd-mastery-api
spec:
replicas: 2
selector:
matchLabels: { app: cicd-mastery-api }
template:
metadata:
labels: { app: cicd-mastery-api }
spec:
containers:
- name: api
image: acrcicdmastery.azurecr.io/cicd-mastery-api:latest
ports: [{ containerPort: 3000 }]
readinessProbe:
httpGet: { path: /health, port: 3000 }
initialDelaySeconds: 5
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 256Mi }
---
apiVersion: v1
kind: Service
metadata:
name: cicd-mastery-api
spec:
selector: { app: cicd-mastery-api }
ports: [{ port: 80, targetPort: 3000 }]
base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
environments/staging/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: staging
resources:
- ../../base
patches:
- patch: |-
- op: replace
path: /spec/replicas
value: 1
target:
kind: Deployment
name: cicd-mastery-api
images:
- name: acrcicdmastery.azurecr.io/cicd-mastery-api
newTag: sha-abc1234 # CI will update this
Commit and push everything.
🏋️ Step 2: Create the ArgoCD Application
Create apps/staging.yaml in the GitOps repo:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cicd-mastery-staging
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
# WHERE to get manifests
source:
repoURL: https://github.com/YOUR_USER/cicd-mastery-gitops.git
targetRevision: main
path: environments/staging
# WHERE to deploy
destination:
server: https://kubernetes.default.svc
namespace: staging
# HOW to sync
syncPolicy:
automated:
prune: true # Delete resources removed from Git
selfHeal: true # Revert manual kubectl changes
syncOptions:
- CreateNamespace=true
retry:
limit: 3
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Apply it:
kubectl apply -f apps/staging.yaml
# Or via CLI:
argocd app get cicd-mastery-staging
Open the ArgoCD UI — you should see your app appear and start syncing! 🎉
Sync Policies: The Decision Matrix
Recommended Policies Per Environment
| Environment | automated | selfHeal | prune | Why |
|---|---|---|---|---|
| Dev / Preview | ✅ | ✅ | ✅ | Fast iteration, auto-cleanup |
| Staging | ✅ | ✅ | ✅ | Mirror prod behavior, auto-deploy |
| Production | ❌ | ✅ | ⚠️ | Human approval required, but prevent drift |
Architect pattern: Staging auto-syncs (see changes immediately). Production shows "OutOfSync" and waits for manual sync — OR you use a PR-based promotion flow where merging a PR IS the approval (covered in a later lesson).
🏋️ Step 3: Test the GitOps Loop
- In the GitOps repo, change the image tag in
environments/staging/kustomization.yaml - Commit and push
- Watch ArgoCD UI — within 3 minutes (or instantly with webhook) it detects "OutOfSync"
- With
automated: true, it auto-syncs. Watch pods update!
Test self-heal:
# Manually scale down (simulating someone "fixing" something)
kubectl scale deployment/cicd-mastery-api --replicas=0 -n staging
# Watch ArgoCD UI — it detects "OutOfSync" immediately
# Within seconds, self-heal kicks in and restores replicas=1
kubectl get pods -n staging -w # Watch pods come back!
🎉 Git always wins. That's GitOps in action.
🧠 Recall Check
- What three things does an ArgoCD Application define?
- What's the difference between
automated: trueand manual sync for production? - What does
selfHeal: truedo when someone runskubectl delete pod? - What does
prune: truedo?
Reveal answers
- Source (Git repo + path + branch), Destination (cluster + namespace), Sync Policy (auto/manual, selfHeal, prune).
automateddeploys immediately when Git changes. Manual shows "OutOfSync" and waits for someone to click Sync or runargocd app sync— giving humans a checkpoint before production changes.- Kubernetes will restart the pod (that's K8s self-healing). ArgoCD won't intervene because the Deployment spec hasn't changed. But if someone
kubectl edit deploymentto change replicas, ArgoCD reverts it. - If you delete a resource from Git (e.g., remove a Service YAML),
prune: truemeans ArgoCD will also delete it from the cluster. Without prune, orphaned resources remain.
You now have a working GitOps loop: change Git → ArgoCD syncs → cluster updates. Manual cluster changes are self-healed. Next lesson: the complete CI→GitOps flow — how your CI pipeline triggers this loop by updating the image tag.