ArgoCD: GitOps Continuous Delivery for Kubernetes
Master ArgoCD for Kubernetes deployments. Learn GitOps principles, application management, sync strategies, and automate your deployment pipeline.
Moshiour Rahman
Advertisement
What is ArgoCD?
ArgoCD is a declarative GitOps continuous delivery tool for Kubernetes. It automates application deployment by continuously monitoring Git repositories and syncing the desired state to your cluster.
GitOps Principles
| Principle | Description |
|---|---|
| Declarative | Define desired state in Git |
| Versioned | All changes tracked |
| Automated | Auto-sync to cluster |
| Auditable | Complete change history |
Getting Started
Installation
# Create namespace
kubectl create namespace argocd
# Install ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Install CLI
# macOS
brew install argocd
# Linux
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
Access ArgoCD
# Port forward to UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Get initial admin password
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# Login via CLI
argocd login localhost:8080 --username admin --password <password> --insecure
# Change password
argocd account update-password
Application Management
Create Application (CLI)
# Create app from Git repository
argocd app create my-app \
--repo https://github.com/org/repo.git \
--path kubernetes \
--dest-server https://kubernetes.default.svc \
--dest-namespace default
# From Helm chart
argocd app create my-helm-app \
--repo https://charts.example.com \
--helm-chart my-chart \
--revision 1.0.0 \
--dest-server https://kubernetes.default.svc \
--dest-namespace default
# With Helm values
argocd app create my-helm-app \
--repo https://github.com/org/repo.git \
--path charts/my-app \
--dest-server https://kubernetes.default.svc \
--dest-namespace production \
--values values-prod.yaml
Application YAML
# application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/repo.git
targetRevision: HEAD
path: kubernetes
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
kubectl apply -f application.yaml
Helm Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prometheus
namespace: argocd
spec:
project: default
source:
repoURL: https://prometheus-community.github.io/helm-charts
chart: prometheus
targetRevision: 15.0.0
helm:
releaseName: prometheus
values: |
server:
persistentVolume:
enabled: true
size: 10Gi
alertmanager:
enabled: false
destination:
server: https://kubernetes.default.svc
namespace: monitoring
Kustomize Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-kustomize-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/repo.git
targetRevision: HEAD
path: overlays/production
kustomize:
images:
- myapp=registry.example.com/myapp:v1.0.0
destination:
server: https://kubernetes.default.svc
namespace: production
Sync Strategies
Manual Sync
# Sync application
argocd app sync my-app
# Sync with prune
argocd app sync my-app --prune
# Dry run
argocd app sync my-app --dry-run
# Force sync
argocd app sync my-app --force
Automated Sync
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
# ... source and destination
syncPolicy:
automated:
prune: true # Delete resources not in Git
selfHeal: true # Revert manual changes
allowEmpty: false # Don't sync empty manifests
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
Sync Waves and Hooks
# Namespace first (wave -1)
apiVersion: v1
kind: Namespace
metadata:
name: my-app
annotations:
argocd.argoproj.io/sync-wave: "-1"
---
# ConfigMap second (wave 0)
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
annotations:
argocd.argoproj.io/sync-wave: "0"
---
# Deployment last (wave 1)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
annotations:
argocd.argoproj.io/sync-wave: "1"
Sync Hooks
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
template:
spec:
containers:
- name: migrate
image: myapp:latest
command: ["./migrate.sh"]
restartPolicy: Never
Projects
Create Project
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: production
namespace: argocd
spec:
description: Production applications
# Source repositories
sourceRepos:
- 'https://github.com/org/*'
- 'https://charts.example.com'
# Destination clusters/namespaces
destinations:
- namespace: 'production-*'
server: https://kubernetes.default.svc
- namespace: production
server: https://kubernetes.default.svc
# Allowed cluster resources
clusterResourceWhitelist:
- group: ''
kind: Namespace
- group: 'rbac.authorization.k8s.io'
kind: ClusterRole
- group: 'rbac.authorization.k8s.io'
kind: ClusterRoleBinding
# Denied namespace resources
namespaceResourceBlacklist:
- group: ''
kind: ResourceQuota
- group: ''
kind: LimitRange
# Role definitions
roles:
- name: developer
description: Developer access
policies:
- p, proj:production:developer, applications, get, production/*, allow
- p, proj:production:developer, applications, sync, production/*, allow
groups:
- developers
Multi-Cluster
Add Cluster
# Add cluster
argocd cluster add my-cluster-context
# List clusters
argocd cluster list
# Remove cluster
argocd cluster rm https://my-cluster-api-server
Multi-Cluster Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/repo.git
targetRevision: HEAD
path: overlays/production
destination:
server: https://production-cluster-api:6443
namespace: my-app
ApplicationSets
Generator Types
# List Generator
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-app
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: staging
url: https://staging-cluster:6443
- cluster: production
url: https://production-cluster:6443
template:
metadata:
name: 'my-app-{{cluster}}'
spec:
project: default
source:
repoURL: https://github.com/org/repo.git
targetRevision: HEAD
path: 'overlays/{{cluster}}'
destination:
server: '{{url}}'
namespace: my-app
# Git Generator (directories)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: apps
namespace: argocd
spec:
generators:
- git:
repoURL: https://github.com/org/apps.git
revision: HEAD
directories:
- path: apps/*
template:
metadata:
name: '{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/org/apps.git
targetRevision: HEAD
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
# Cluster Generator
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
namespace: argocd
spec:
generators:
- clusters:
selector:
matchLabels:
environment: production
template:
metadata:
name: 'addons-{{name}}'
spec:
project: default
source:
repoURL: https://github.com/org/cluster-addons.git
targetRevision: HEAD
path: addons
destination:
server: '{{server}}'
namespace: kube-system
Secrets Management
Sealed Secrets
# Install Sealed Secrets controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
# Install kubeseal CLI
brew install kubeseal
# Create sealed secret
kubectl create secret generic my-secret \
--from-literal=password=mysecret \
--dry-run=client -o yaml | \
kubeseal --format yaml > sealed-secret.yaml
External Secrets
# Install External Secrets Operator
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: external-secrets
namespace: argocd
spec:
project: default
source:
repoURL: https://charts.external-secrets.io
chart: external-secrets
targetRevision: 0.9.0
destination:
server: https://kubernetes.default.svc
namespace: external-secrets
syncPolicy:
automated:
selfHeal: true
# External Secret
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-secret
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: my-secret
data:
- secretKey: password
remoteRef:
key: my-app/credentials
property: password
Notifications
# ConfigMap for notifications
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
template.app-sync-succeeded: |
message: |
Application {{.app.metadata.name}} sync succeeded.
Revision: {{.app.status.sync.revision}}
trigger.on-sync-succeeded: |
- when: app.status.operationState.phase in ['Succeeded']
send: [app-sync-succeeded]
CLI Commands
# App management
argocd app list
argocd app get my-app
argocd app sync my-app
argocd app delete my-app
# History and rollback
argocd app history my-app
argocd app rollback my-app <revision>
# Diff
argocd app diff my-app
# Logs
argocd app logs my-app
# Resource tree
argocd app resources my-app
Summary
| Feature | Description |
|---|---|
| Applications | Define deployments |
| Projects | RBAC and restrictions |
| ApplicationSets | Multi-cluster/app |
| Sync Policies | Auto/manual sync |
| Hooks | Pre/post sync jobs |
| Notifications | Slack, email alerts |
ArgoCD enables declarative, GitOps-based continuous delivery for Kubernetes applications.
Advertisement
Moshiour Rahman
Software Architect & AI Engineer
Enterprise software architect with deep expertise in financial systems, distributed architecture, and AI-powered applications. Building large-scale systems at Fortune 500 companies. Specializing in LLM orchestration, multi-agent systems, and cloud-native solutions. I share battle-tested patterns from real enterprise projects.
Related Articles
Kubernetes Helm Charts: Package and Deploy Applications
Master Helm for Kubernetes deployments. Learn chart creation, templates, values, dependencies, and best practices for production applications.
DevOpsService Mesh with Istio: Complete Kubernetes Guide
Master Istio service mesh for Kubernetes. Learn traffic management, security, observability, and build resilient microservices architectures.
DevOpsGitHub Actions CI/CD: Automate Your Development Workflow
Master GitHub Actions for CI/CD pipelines. Learn workflows, jobs, actions, secrets management, and deploy to any cloud platform automatically.
Comments
Comments are powered by GitHub Discussions.
Configure Giscus at giscus.app to enable comments.