What is ArgoCD?
ArgoCD is a declarative, GitOps-based continuous delivery tool for Kubernetes. It monitors your application definitions stored in a Git repository and automatically synchronizes the desired state with the live state in your Kubernetes cluster. Unlike traditional push-based deployment pipelines, ArgoCD follows a pull-based model where it continuously watches your Git repository and applies changes to the cluster when differences are detected.
At its core, ArgoCD operates as a Kubernetes controller that reconciles the actual state of your cluster against the desired state declared in Git. It supports a wide variety of manifest formats including plain YAML, Helm charts, Kustomize overlays, Ksonnet, and Jsonnet. This flexibility makes it compatible with virtually any Kubernetes configuration management approach you may already be using.
Why Continuous Deployment with ArgoCD Matters
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →Implementing continuous deployment with ArgoCD brings several critical advantages to your development workflow:
- Single source of truth: Your Git repository becomes the authoritative source for all cluster configurations, eliminating configuration drift caused by manual interventions or ad-hoc kubectl commands.
- Audit trail and compliance: Every change to your infrastructure is tracked through Git commits, pull requests, and approvals. You can trace exactly who changed what and when, which is essential for security audits and compliance requirements.
- Automated drift detection: ArgoCD continuously monitors your cluster and detects any divergence between the desired state in Git and the actual state running in the cluster. It can optionally auto-remediate or alert on these discrepancies.
- Disaster recovery: If your entire cluster goes down, you can recreate everything from scratch by simply pointing ArgoCD at your configuration repository.
- Multi-cluster consistency: ArgoCD can manage multiple clusters from a single control plane, ensuring consistent configurations across development, staging, and production environments.
- Built-in rollback capabilities: Rolling back a bad deployment is as simple as reverting a Git commit and letting ArgoCD sync the previous known-good state.
Prerequisites
Before you begin setting up ArgoCD, ensure you have the following:
- A running Kubernetes cluster (version 1.19 or later). You can use a local cluster like Minikube, Kind, or a managed service like GKE, EKS, or AKS.
kubectlinstalled and configured to communicate with your cluster.- A Git repository containing your Kubernetes manifests, Helm charts, or Kustomize overlays.
- Basic familiarity with Kubernetes concepts such as namespaces, deployments, services, and ConfigMaps.
- Network access from your ArgoCD instance to both your Git repository and your target Kubernetes clusters.
Step-by-Step Setup Guide
1. Installing ArgoCD on Your Kubernetes Cluster
The recommended installation method is to apply the official ArgoCD namespace and installation manifests directly to your cluster. First, create the dedicated namespace:
kubectl create namespace argocd
Now apply the ArgoCD installation manifests. The stable release installs the core components including the API server, application controller, repo server, and Redis cache:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
If you prefer a highly available installation with multiple replicas, use the HA manifests instead:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/install.yaml
Wait for all pods to become ready. You can monitor the progress with:
kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s
Verify the installation by listing all ArgoCD pods:
kubectl get pods -n argocd
You should see pods for argocd-application-controller, argocd-repo-server, argocd-server, and argocd-redis, all in a Running state.
2. Accessing the ArgoCD API and UI
By default, the ArgoCD API server is not exposed externally. For local development, you can use port-forwarding to access both the CLI and the web UI:
kubectl port-forward svc/argocd-server -n argocd 8080:443
Alternatively, you can expose the service via a LoadBalancer, Ingress, or NodePort. For an Ingress-based approach with TLS, create an ingress resource:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
ingressClassName: nginx
rules:
- host: argocd.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
Retrieve the initial admin password. The password is stored as a Kubernetes secret in the argocd namespace:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
The default username is admin. You can now log in using the ArgoCD CLI:
argocd login localhost:8080 --username admin --password <PASSWORD> --insecure
Change the admin password immediately after your first login:
argocd account update-password \
--current-password <INITIAL_PASSWORD> \
--new-password <NEW_STRONG_PASSWORD> \
--server localhost:8080
3. Connecting Your Git Repository
ArgoCD needs access to your Git repository to fetch application manifests. You can add repositories via the CLI, UI, or declarative approach. Using the CLI, add a public repository:
argocd repo add https://github.com/your-org/your-config-repo.git --name my-config-repo
For private repositories, provide credentials:
argocd repo add https://github.com/your-org/private-config-repo.git \
--username your-github-username \
--password your-personal-access-token \
--name private-config-repo
You can also store repository credentials as Kubernetes secrets. Create a secret and label it for ArgoCD discovery:
apiVersion: v1
kind: Secret
metadata:
name: private-repo-creds
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
type: Opaque
stringData:
url: https://github.com/your-org/private-config-repo.git
username: your-github-username
password: your-personal-access-token
Apply this secret to your cluster:
kubectl apply -f repo-secret.yaml -n argocd
4. Creating Your First Application
An ArgoCD Application is a custom resource that tells ArgoCD which Git repository to watch, where to find manifests, and which cluster and namespace to deploy to. You can create applications using the CLI, the web UI, or by applying a declarative YAML manifest. The declarative approach is strongly recommended for production setups because it allows you to version-control your application definitions.
Here is a complete example of an Application manifest that deploys a sample guestbook application from a public repository:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: guestbook
destination:
server: https://kubernetes.default.svc
namespace: guestbook
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Let's break down each section of this manifest:
- metadata.name: The unique name for your application within the ArgoCD namespace.
- finalizers: The
resources-finalizerensures that when you delete the Application, ArgoCD also cleans up all deployed resources. - spec.project: ArgoCD organizes applications into projects. The
defaultproject is available out of the box and permits deployments to any cluster. - spec.source: Defines the Git repository URL, the branch or tag (
targetRevision), and the directory path within the repo containing your manifests. - spec.destination: Specifies the target cluster API server URL and the namespace where resources will be created. Use
https://kubernetes.default.svcto refer to the local cluster where ArgoCD itself is running. - spec.syncPolicy: Configures automated synchronization behavior, including automatic pruning of stale resources, self-healing of drift, and namespace creation.
Apply this application manifest to your cluster:
kubectl apply -f guestbook-app.yaml -n argocd
Check the application status using the CLI:
argocd app get guestbook --server localhost:8080
You can also list all applications:
argocd app list --server localhost:8080
5. Understanding Sync Policies and Automation
ArgoCD offers three modes of synchronization. Manual sync requires an operator to explicitly trigger each sync via CLI or UI. Automated sync with self-heal enabled automatically corrects any drift between Git and the cluster. Automated sync without self-heal triggers a sync only when Git changes but does not automatically correct manual cluster modifications.
Here is a configuration example that enables fully automated sync with pruning:
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PruneLast=true
- ApplyOutOfSyncOnly=true
retry:
limit: 10
backoff:
duration: 10s
factor: 2
maxDuration: 10m
The PruneLast option ensures that resources are pruned only after new resources are applied, minimizing downtime. ApplyOutOfSyncOnly tells ArgoCD to only apply resources that are actually out of sync, speeding up large applications. The retry configuration with exponential backoff handles transient errors gracefully.
6. Working with Helm Charts
ArgoCD natively supports Helm charts. You can point to a chart repository or to a directory containing a Helm chart in your Git repository. Here is an application manifest for deploying a Helm chart from a Git repository with custom values:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx-helm
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/helm-charts.git
targetRevision: main
path: charts/nginx
helm:
releaseName: my-nginx
valueFiles:
- values-prod.yaml
values: |
service:
type: ClusterIP
replicaCount: 3
resources:
limits:
cpu: 500m
memory: 512Mi
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
For Helm chart repositories hosted on artifact hubs or private registries, use the chart field instead of path:
source:
repoURL: https://helm.example.com/charts
targetRevision: 2.5.1
chart: nginx-ingress
helm:
values: |
controller:
metrics:
enabled: true
7. Configuring Health Checks and Sync Hooks
ArgoCD evaluates the health of your deployed resources using built-in health checks for standard Kubernetes types and custom health checks defined via Lua scripts. You can define custom health checks in the argocd-cm ConfigMap. For example, to add a custom health check for a CRD:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations.health.mycompany.io_v1_MyResource: |
hs = {}
hs.status = "Healthy"
if obj.status.phase == "Error" then
hs.status = "Degraded"
hs.message = obj.status.errorMessage
end
return hs
Sync hooks allow you to run jobs before, during, or after a sync operation. Annotate your Kubernetes resources with specific hook annotations. Here is an example of a pre-sync hook that runs a database migration job:
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: migration
image: your-db-migration-image:latest
command: ["/bin/sh", "-c", "run-migrations.sh"]
restartPolicy: Never
backoffLimit: 2
Common hook types include PreSync (runs before the sync), Sync (runs during the sync), PostSync (runs after a successful sync), and SyncFail (runs when a sync fails). The hook-delete-policy annotation controls cleanup of the hook resource after execution.
8. Multi-Cluster Management
One of ArgoCD's most powerful features is its ability to manage multiple Kubernetes clusters from a single control plane. To add an external cluster, first register it with ArgoCD:
argocd cluster add my-cluster-context-name --name production-cluster
This command uses your local kubeconfig context to authenticate and register the cluster. You can also add clusters declaratively by creating a secret in the argocd namespace:
apiVersion: v1
kind: Secret
metadata:
name: production-cluster-secret
namespace: argocd
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
name: production-cluster
server: https://prod-cluster-api.example.com
config: |
{
"tlsClientConfig": {
"insecure": false,
"caData": "<BASE64_ENCODED_CA_CERT>",
"certData": "<BASE64_ENCODED_CLIENT_CERT>",
"keyData": "<BASE64_ENCODED_CLIENT_KEY>"
}
}
Once registered, you can target deployments to the remote cluster by specifying its server URL in your Application manifest's destination.server field.
Best Practices for ArgoCD Continuous Deployment
Keep Configuration Separate from Application Code
Maintain a dedicated Git repository for your Kubernetes manifests and ArgoCD application definitions, separate from your application source code. This separation ensures that code changes and infrastructure changes follow independent release cycles and approval workflows. It also prevents accidental deployment of untested infrastructure changes when application code is merged.
Implement Git Branching and Promotion Strategies
Use Git branches to model environment promotion. For example, maintain a staging branch and a production branch in your config repository. Point your staging ArgoCD application at the staging branch and your production application at the production branch. Promote changes by merging from staging to production after validation. This creates a clear, auditable promotion pipeline.
Secure Secrets Properly
Never store plain-text secrets in your Git repository. Use tools like Sealed Secrets, External Secrets Operator, or HashiCorp Vault with the ArgoCD Vault plugin. Here is an example of using Sealed Secrets with ArgoCD:
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: database-credentials
namespace: production
spec:
encryptedData:
username: AgA8bB...encrypted-base64...
password: AgCBdD...encrypted-base64...
ArgoCD syncs the SealedSecret resource, and the Sealed Secrets controller decrypts it into a standard Kubernetes Secret inside the cluster.
Use Projects for Logical Isolation
Create separate ArgoCD projects for different teams or business units. Projects allow you to restrict which Git repositories, clusters, and resource types a team can deploy. Here is an example project definition with tight restrictions:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: team-frontend
namespace: argocd
spec:
description: Frontend team project
sourceRepos:
- https://github.com/my-org/frontend-configs.git
destinations:
- namespace: frontend-*
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: ""
kind: Namespace
namespaceResourceWhitelist:
- group: ""
kind: ConfigMap
- group: apps
kind: Deployment
- group: networking.k8s.io
kind: Ingress
roles:
- name: developer
description: Standard developer role
policies:
- p, proj:team-frontend:developer, applications, sync, team-frontend/*, allow
groups:
- my-org:frontend-developers
Enable SSO and RBAC for Enterprise Deployments
Integrate ArgoCD with your organization's identity provider using OIDC or SAML. Configure the argocd-cm ConfigMap for OIDC integration with providers like Okta, Azure AD, or Google Workspace:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: Okta
issuer: https://your-org.okta.com
clientID: 0oa8abc123...
clientSecret: $oidc.okta.clientSecret
requestedScopes:
- openid
- profile
- groups
logoutURL: https://your-org.okta.com/login/signout
Combine SSO with fine-grained RBAC policies in the argocd-rbac-cm ConfigMap to map group memberships to ArgoCD roles.
Implement Progressive Delivery with Argo Rollouts
For advanced deployment strategies like blue-green and canary deployments, integrate ArgoCD with Argo Rollouts. Define a Rollout resource instead of a standard Deployment:
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-app-rollout
namespace: production
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 20
- pause: {duration: 10m}
- setWeight: 40
- pause: {duration: 10m}
- setWeight: 100
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:2.0.0
ArgoCD syncs the Rollout resource, and Argo Rollouts handles the gradual traffic shifting and automated metric analysis.
Monitor Sync Status and Set Up Notifications
Configure ArgoCD notifications to alert your team about sync failures, degraded health, or successful deployments. Define notification triggers and templates in the argocd-notifications-cm ConfigMap. Here is a Slack notification configuration:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
triggers.trigger-on-sync-failed: |
- when: app.status.operationState.phase == 'Error'
send: [slack-channel]
templates.template-slack: |
message: |
Application *{{.app.metadata.name}}* sync failed.
Error: {{.app.status.operationState.message}}
slack:
channel: "#deployment-alerts"
Regularly Prune Stale Resources
Enable automated pruning in your sync policies to remove resources that exist in the cluster but are no longer defined in Git. This keeps your cluster clean and prevents resource sprawl. Always combine pruning with the PruneLast sync option to avoid service interruptions during configuration refactoring.
Version Your ArgoCD Configuration Itself
Treat your ArgoCD Application manifests, project definitions, and cluster configurations as code. Store them in a Git repository and apply them via a bootstrapping process. This ensures your entire continuous deployment pipeline is reproducible and recoverable.
Conclusion
ArgoCD transforms Kubernetes deployment from a manual, error-prone process into an automated, auditable, and reliable GitOps pipeline. By making Git the single source of truth for your cluster state, you gain continuous drift detection, automated synchronization, and a complete audit trail of every change. The setup process is straightforward: install ArgoCD on your cluster, connect your Git repositories, define your applications declaratively, and let the controller handle the rest. By following the best practices outlined here—separating config from code, securing secrets, using projects for isolation, enabling SSO, and implementing progressive delivery with Argo Rollouts—you will build a robust continuous deployment system that scales across teams and clusters. ArgoCD's active community, extensive documentation, and enterprise-grade features make it a cornerstone of modern Kubernetes delivery workflows.