Cloud Architecture

GitOps with ArgoCD: Managing Kubernetes Deployments

Master GitOps for Kubernetes deployments using ArgoCD. Learn core principles, architecture, setup, and advanced features for robust, automated, and auditable infrastructure.

Khader Vali August 18, 2026 16 min read

Mastering GitOps with ArgoCD: A Comprehensive Guide to Managing Kubernetes Deployments

In the rapidly evolving landscape of cloud-native development, managing Kubernetes deployments efficiently, reliably, and securely is paramount. As applications grow in complexity and clusters scale, traditional CI/CD approaches often struggle to keep pace, leading to configuration drift, manual errors, and a lack of transparency. Enter GitOps – a revolutionary paradigm that brings the best practices of software development to infrastructure management.

This article dives deep into the world of GitOps, specifically focusing on how ArgoCD, a declarative GitOps continuous delivery tool for Kubernetes, can transform your deployment workflows. As a senior engineer at Khadervali.com, I’ve witnessed firsthand the power of adopting GitOps, and I’m here to share the insights, architecture, practical steps, and best practices to help you implement a robust, automated, and auditable system for your Kubernetes applications.

The Evolving Challenge of Kubernetes Deployments

Kubernetes, while incredibly powerful, introduces its own set of operational complexities. Manifest files (YAMLs) define everything from deployments and services to ingresses and persistent volumes. Managing these manifests across multiple environments (dev, staging, production), ensuring consistency, and tracking changes can quickly become a daunting task.

Consider a typical scenario: A new feature requires updating a deployment, creating a new service, and adjusting an ingress. In a traditional setup, a developer might push code to a repository, a CI pipeline builds a Docker image, and then a CD pipeline pushes these new Kubernetes manifests directly to the cluster. This “push-based” model has several inherent challenges:

  • Lack of Auditability: It’s often hard to definitively know *who* deployed *what* and *when* without meticulously combing through CI/CD logs.
  • Configuration Drift: Manual changes applied directly to a cluster (e.g., via kubectl edit) can diverge from the desired state defined in source control, leading to inconsistencies and hard-to-debug issues.
  • Security Concerns: CI/CD systems often require elevated permissions to directly interact with Kubernetes clusters, posing a security risk if compromised.
  • Complexity at Scale: Managing multiple clusters, namespaces, and hundreds of applications becomes a logistical nightmare without a centralized, automated approach.

These challenges highlight the need for a more structured, auditable, and automated approach to Kubernetes deployment management. This is where GitOps shines.

Understanding GitOps: The Source of Truth

At its core, GitOps is an operational framework that takes DevOps best practices used for application development, like version control, collaboration, compliance, and CI/CD, and applies them to infrastructure automation. It treats Git as the single source of truth for declarative infrastructure and applications.

Core Principles of GitOps

The GitOps model revolves around four fundamental principles:

  1. Declarative Configuration: Everything that can be described as a desired state, including infrastructure, applications, and their configurations, must be declared. For Kubernetes, this means all your deployments, services, ingresses, etc., are defined in YAML manifests.

    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-webapp
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: my-webapp
      template:
        metadata:
          labels:
            app: my-webapp
        spec:
          containers:
          - name: my-webapp-container
            image: myregistry/my-webapp:v1.0.0 # Desired image version
            ports:
            - containerPort: 80
            env:
            - name: ENV_VAR_NAME
              value: "production"
            resources:
              limits:
                cpu: "200m"
                memory: "256Mi"
              requests:
                cpu: "100m"
                memory: "128Mi"
            
  2. Version-Controlled in Git: The desired state of the entire system (infrastructure and applications) is stored in a Git repository. Every change, every revision, every commit to this repository is treated as an authoritative update to the system’s state. This provides a complete audit trail, easy rollbacks, and collaboration features inherent to Git.

  3. Automated Pull-Based Reconciliation: Instead of a CI/CD pipeline “pushing” changes to the cluster, a specialized agent (like ArgoCD) continuously “pulls” the desired state from Git and compares it with the actual state of the cluster. If a discrepancy is detected (configuration drift), the agent automatically reconciles the cluster’s state to match the Git repository’s declared state.

  4. Continuously Reconciled: The reconciliation process is continuous. This means the system is always striving to match the desired state defined in Git. If someone manually changes a resource on the cluster, the GitOps agent will detect this drift and automatically revert it, or at least flag it for attention, depending on the configuration.

Benefits of Adopting GitOps

Embracing GitOps offers a multitude of advantages for managing complex cloud-native environments:

  • Enhanced Productivity: Developers can focus on writing application code and defining its desired state in Git, rather than worrying about the intricacies of deployment mechanisms.
  • Improved Reliability: The pull-based, declarative nature ensures that the cluster state always converges to the desired state in Git, reducing human error and configuration drift. Rollbacks are as simple as reverting a Git commit.
  • Faster Mean Time To Recovery (MTTR): If a deployment goes wrong, reverting to a previous working state is quick and straightforward by simply rolling back the Git commit.
  • Stronger Security: GitOps agents run within the cluster and pull changes from Git. This eliminates the need for external CI/CD systems to have direct write access to the Kubernetes API, reducing the attack surface. Git repository access controls become the primary security boundary.
  • Comprehensive Auditability: Every change to your infrastructure and applications is a commit in Git, complete with author, timestamp, and commit message. This provides an unparalleled audit trail, crucial for compliance and debugging.
  • Consistency Across Environments: By using the same Git repository and GitOps principles for all environments (dev, staging, prod), you ensure consistency and minimize “it worked on my machine” type issues.
  • Self-Healing Capabilities: The continuous reconciliation loop means that if a resource is accidentally deleted or modified on the cluster, the GitOps agent will automatically restore it to its desired state.

Why Kubernetes Needs GitOps

Kubernetes’ inherent declarative nature makes it an ideal candidate for GitOps. You define what you want (e.g., three replicas of an Nginx pod), not how to achieve it. This aligns perfectly with GitOps’ principle of a declarative source of truth.

However, managing Kubernetes manifests manually or with traditional push-based CI/CD pipelines can quickly become cumbersome:

  • YAML Fatigue: As applications grow, the number of YAML files and their complexity can become overwhelming.
  • Drift Detection: Kubernetes itself doesn’t inherently prevent configuration drift. A manual kubectl edit deployment/my-app can diverge from your source code without any immediate warning.
  • State Management: In a dynamic environment, ensuring the actual state of your cluster matches your intended state is a constant battle. GitOps provides a robust mechanism to manage this state.

GitOps, particularly with a tool like ArgoCD, provides the missing link for robust Kubernetes management, bridging the gap between desired state in Git and actual state in the cluster, ensuring consistency and automation.

Introducing ArgoCD: Your GitOps Enabler

ArgoCD is a declarative, GitOps continuous delivery tool for Kubernetes. It is implemented as a Kubernetes controller that continuously monitors running applications and compares their live state against the desired state defined in a Git repository. If the live state deviates from the desired state, ArgoCD reports and visualizes the differences, and can automatically or manually synchronize the live state back to the desired state.

Key Features of ArgoCD

  • Automated Deployment and Synchronization: ArgoCD automatically deploys applications to specified target environments and ensures they are always synchronized with the latest version in Git.
  • Web UI and CLI: Provides a rich web user interface to visualize applications, their states, and deployment history. A powerful CLI is also available for scripting and automation.
  • Multi-Cluster Management: Can manage applications across multiple Kubernetes clusters from a single ArgoCD instance.
  • Support for Various Manifest Formats: Natively supports Kustomize, Helm charts, Ksonnet, JSONnet, and plain YAML manifests.
  • Rollback and History: Easily roll back to any previous application version committed to Git. Maintains a history of all deployments.
  • Health Status and Drift Detection: Provides real-time health checks for applications and detects configuration drift, highlighting any discrepancies between Git and the live cluster.
  • Authentication and Authorization: Integrates with existing identity providers (LDAP, SAML, OIDC, GitHub, GitLab, etc.) and offers robust RBAC for fine-grained access control.
  • Webhooks: Supports webhooks from Git providers (GitHub, GitLab, BitBucket) for instant synchronization upon new commits.

ArgoCD acts as the “pull operator” in the GitOps model. It lives within your Kubernetes cluster, has the necessary permissions to apply resources, and constantly observes your Git repository for changes, making it a secure and efficient way to manage deployments.

GitOps with ArgoCD: Managing Kubernetes Deployments
Generated Image

Architectural Overview of GitOps with ArgoCD

Let’s visualize the core components and the workflow involved when implementing GitOps with ArgoCD. Understanding this architecture is crucial for setting up and troubleshooting your deployments.

Key Components:

  1. Git Repository (Source of Truth): This is the central hub where all your Kubernetes manifests (Deployments, Services, Ingresses, etc.), Helm charts, Kustomize configurations, and other declarative infrastructure definitions reside. It’s where developers and operations engineers collaborate, review changes, and trigger deployments through commits and pull requests.

  2. CI Pipeline (Optional but Recommended): While not strictly part of the GitOps “pull” mechanism, a CI pipeline is typically used to build application code, run tests, and produce immutable Docker images. Crucially, in a GitOps workflow, the CI pipeline’s responsibility often ends with pushing the new Docker image to a container registry and then *updating the image tag in the Kubernetes manifests within the Git repository* (e.g., via a commit, or a separate tool like Renovate/Dependabot). It does NOT directly deploy to Kubernetes.

  3. ArgoCD Controller (In-Cluster Agent): This is the heart of your GitOps system. It runs as a set of deployments within your Kubernetes cluster. Its primary functions are:

    • Application Controller: Monitors the registered Git repositories for changes to application manifests.
    • API Server: Exposes the gRPC and REST API, used by the UI and CLI. Manages applications and provides cluster access.
    • Repo Server: An internal service that holds the Git repository cache and renders Kubernetes manifests (e.g., processes Helm charts, Kustomize overlays).
    • ApplicationSet Controller (Optional): Manages the creation of ArgoCD applications across multiple clusters, repositories, or paths.
  4. Kubernetes Cluster: The target environment where your applications are deployed and managed by ArgoCD.

  5. ArgoCD UI/CLI: Provides an interface for users to observe the state of their applications, trigger manual syncs (if automatic sync is not enabled), view deployment history, and perform administrative tasks.

The GitOps Workflow with ArgoCD (Diagram in Words):

Imagine the flow of changes and reconciliation as follows:


+-------------------+       Pull Request/Commit       +--------------------+
| Developer/DevOps  | <-----------------------------> | Git Repository     |
| Engineer          |                                 | (App Manifests,    |
+-------------------+                                 | Infrastructure Config)
        |                                             +--------------------+
        | (1. Creates/Updates K8s Manifests)                    ^
        |                                                       |
        V                                                       | (4. ArgoCD Pulls Desired State)
+------------------------------------------------------------------------------------------------------------------+
| CI Pipeline (Optional, for Application Code)                                                                     |
|   - Builds Application Image                                                                                     |
|   - Pushes Image to Registry                                                                                     |
|   - (Optional) Updates Image Tag in Git Repository K8s Manifests (e.g., via `kustomize edit set image` or script)|
+------------------------------------------------------------------------------------------------------------------+
                                                                  |
                                                                  V
+--------------------+      (Monitors Git)       +--------------------+      (Applies Changes)      +-------------------+
| ArgoCD Controller  | <------------------------ | Git Repository     | --------------------------> | Kubernetes Cluster|
| (Running in K8s)   |                           | (Desired State)    | (Reconciles Actual State) | (Live State)      |
+--------------------+                           +--------------------+                             +-------------------+
        ^                                                                                                   ^
        | (Reports Status)                                                                                  | (Actual State)
        +---------------------------------------------------------------------------------------------------+
        |
        | (Provides Visuals/Controls)
        V
+-----------------+
| ArgoCD UI/CLI   |
+-----------------+
  1. Developer Commits Changes: A developer or DevOps engineer makes changes to the application’s Kubernetes manifests (e.g., a new image tag, replica count, or environment variable) in the Git repository. These changes are typically reviewed via pull requests.

  2. CI Pipeline (If applicable): If this is an application code change, the CI pipeline builds a new Docker image, pushes it to a container registry, and then updates the corresponding Kubernetes manifest in the Git repository with the new image tag. This commit triggers the subsequent steps.

  3. ArgoCD Monitors Git: The ArgoCD Application Controller continuously monitors the specified Git repository (or repositories) for new commits or changes to the configured paths.

  4. Drift Detection: Upon detecting changes in Git, or during its regular sync interval, ArgoCD compares the desired state (defined in Git) with the actual live state of the resources in the Kubernetes cluster.

  5. Synchronization/Reconciliation:

    • If there’s a difference, ArgoCD marks the application as OutOfSync in its UI.
    • Depending on the configured synchronization policy (manual or automatic), ArgoCD will either wait for a manual trigger or automatically apply the changes from Git to the Kubernetes cluster.
    • ArgoCD pulls the updated manifests, renders them (if using Helm/Kustomize), and then uses the Kubernetes API to apply these changes, reconciling the cluster’s actual state with the desired state from Git.
  6. Status Reporting: ArgoCD continuously monitors the health and status of the deployed resources within the cluster and reports this back through its UI and API, providing real-time visibility into your application’s state.

This pull-based model ensures that the Kubernetes cluster always reflects the state declared in Git, providing immense benefits in terms of auditability, reliability, and automation.

Setting Up Your GitOps Workflow with ArgoCD

Let’s get practical. Here’s a step-by-step guide to setting up ArgoCD and deploying your first application using GitOps.

Prerequisites:

  • A running Kubernetes cluster (local like Minikube/Kind, or cloud-based).
  • kubectl installed and configured to connect to your cluster.
  • git installed.
  • A Git repository (e.g., GitHub, GitLab, Bitbucket) to store your Kubernetes manifests.

Step 1: Install ArgoCD on Your Kubernetes Cluster

ArgoCD components are deployed into their own namespace (typically argocd). You can install it using kubectl:


# Create a dedicated namespace for ArgoCD
kubectl create namespace argocd

# Install ArgoCD via its official manifest
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Wait for ArgoCD pods to be ready (this might take a few minutes)
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=argocd-server -n argocd --timeout=300s
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=argocd-repo-server -n argocd --timeout=300s
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=argocd-application-controller -n argocd --timeout=300s
        

Step 2: Access the ArgoCD UI

By default, the ArgoCD API server is not exposed externally. You can access it using port forwarding:


# Port forward the argocd-server service
kubectl port-forward svc/argocd-server -n argocd 8080:443
        

Now, open your browser and navigate to https://localhost:8080. You’ll likely encounter a certificate warning, which you can safely bypass for local testing.

To log in, you need the initial admin password. It’s stored in a Kubernetes secret:


# Get the initial admin password
kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 -d; echo
        

The username is admin. Use the retrieved password to log in. You should change this password after your first login for security reasons.


# Change admin password (after logging in via UI)
argocd admin initial-password --password your-new-secure-password
        

You’ll need the ArgoCD CLI tool for this. Install it by following the instructions on the official documentation.

Step 3: Prepare Your Git Repository for Kubernetes Manifests

Create a new Git repository (or use an existing one) to store your Kubernetes application manifests. A common structure involves separating environments or applications into different directories.

For this example, let’s create a simple Nginx application.


# Create a new directory for your GitOps repo
mkdir gitops-repo && cd gitops-repo
git init

# Create a directory for your application
mkdir apps/nginx-example
cd apps/nginx-example
        

Now, create two Kubernetes manifest files: deployment.yaml and service.yaml within apps/nginx-example.


# apps/nginx-example/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.6 # Our desired application version
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: "100m"
            memory: "128Mi"
          requests:
            cpu: "50m"
            memory: "64Mi"
        

# apps/nginx-example/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP # Or NodePort/LoadBalancer for external access
        

Commit these files to your Git repository:


git add .
git commit -m "Initial Nginx application manifests"
git branch -M main
git remote add origin YOUR_GIT_REPOSITORY_URL # e.g., https://github.com/your-username/gitops-repo.git
git push -u origin main
        

Ensure your Git repository is publicly accessible or configure ArgoCD with appropriate credentials if it’s private (beyond the scope of this basic setup, but supported).

Step 4: Create Your First ArgoCD Application

An ArgoCD application defines the connection between a Git repository path and a Kubernetes cluster/namespace. You can create an application via the UI or by applying an Application Custom Resource Definition (CRD) directly to Kubernetes.

Option A: Via ArgoCD UI

  1. Log in to the ArgoCD UI (https://localhost:8080).
  2. Click on “NEW APP”.
  3. Fill in the details:
    • Application Name: nginx-app
    • Project: default (or create a new one)
    • Sync Policy: Choose Automatic with Prune and Self Heal enabled for true GitOps automation. Or Manual for initial testing.
  4. In the “Source” section:
    • Repository URL: YOUR_GIT_REPOSITORY_URL (e.g., https://github.com/your-username/gitops-repo.git)
    • Revision: HEAD or main
    • Path: apps/nginx-example
  5. In the “Destination” section:
    • Cluster: in-cluster (for the cluster ArgoCD is running on)
    • Namespace: default (or your desired namespace)
  6. Click “CREATE”.

Option B: Via Application CRD (Recommended for GitOps)

The GitOps way to manage ArgoCD applications themselves is to define them as Kubernetes resources and commit them to Git. Create a new file, say argocd-apps/nginx-app.yaml, in your Git repository (perhaps in a separate repo for ArgoCD app definitions, or a dedicated folder in the same repo).


# argocd-apps/nginx-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx-app
  namespace: argocd # ArgoCD applications are typically managed in the argocd namespace
spec:
  project: default
  source:
    repoURL: https://github.com/your-username/gitops-repo.git # Replace with your repo URL
    targetRevision: HEAD
    path: apps/nginx-example # Path within your Git repository
  destination:
    server: https://kubernetes.default.svc # The in-cluster Kubernetes API server
    namespace: default # The target namespace for your Nginx deployment
  syncPolicy:
    automated:
      prune: true # Delete resources that are no longer in Git
      selfHeal: true # Automatically sync if drift is detected
    syncOptions:
    - CreateNamespace=true # Automatically create the target namespace if it doesn't exist
        

Commit this Application manifest to your Git repository. Then, you can apply it manually with kubectl or, even better, have another ArgoCD instance (the “root” ArgoCD) manage this application definition.


# Apply the ArgoCD Application manifest to your cluster
kubectl apply -f argocd-apps/nginx-app.yaml -n argocd
        

Step 5: Observe Synchronization

Whether you created the application via UI or CRD, you should now see nginx-app in the ArgoCD UI. Initially, it might be OutOfSync (if you chose manual sync) or immediately Syncing and then Synced (if automatic sync is enabled).

If it’s OutOfSync, click on the application and then click the “SYNC” button. ArgoCD will pull the manifests from your Git repository and apply them to your Kubernetes cluster. You’ll

Written by

Khader Vali

Senior Software Engineer specializing in cloud architecture, real-time systems, and enterprise-scale applications.

Share this article

Related Articles

Building Scalable Data Pipelines with AWS Kinesis, Glue, and Redshift

Jul 03, 2026 · 16 min read

FinOps: Data-Driven Cloud Cost Optimization for Engineers

Jun 21, 2026 · 18 min read

Building Real-Time Data Pipelines on AWS: Kinesis, Glue, Redshift

Aug 03, 2026 · 16 min read