Back to Blog
Software EngineeringTechnologyJune 18, 20263 min read

GitOps with Argo CD: A Guide to Declarative Kubernetes CD

Master GitOps with Argo CD for robust Kubernetes CD. Learn how to implement declarative infrastructure and automate your deployments with this step-by-step guide.

GitOpsArgo CDKubernetesDevOpsCI/CDInfrastructure as CodeKustomizeLinuxServer

GitOps with Argo CD: A Guide to Declarative Kubernetes CD

I’ve spent years chasing "drift" in production clusters. You know the drill: someone runs a kubectl edit to fix a memory limit, forgets to update the Helm chart, and three weeks later, a redeployment wipes out the fix. It's a nightmare. That's why I moved my teams to GitOps.

Using Argo CD for Kubernetes CD transforms your repository into the single source of truth. When your infrastructure is declarative, the cluster state is just a reflection of your Git repo. If it's not in Git, it doesn't exist.

Why GitOps?

In a traditional CI/CD pipeline, the CI server (like Jenkins or GitHub Actions) pushes changes to the cluster. This requires the CI server to hold cluster-admin credentials. That’s a security risk.

Argo CD flips this. It runs inside your cluster as a controller. It pulls the desired state from Git and reconciles it with the live environment. If someone manually changes a service type, Argo CD detects the drift and—depending on your policy—reverts it automatically.

Prerequisites

Before we dive into the YAML, make sure you have:

  • A Kubernetes cluster (v1.24+)
  • kubectl installed
  • Helm or Kustomize (if you’re managing complex apps)

Step 1: Installing Argo CD

I prefer installing via the official manifests. It’s straightforward and keeps the control plane isolated.

Bash
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.8.4/manifests/install.yaml

Once the pods are running, you’ll need to expose the server. For local testing, port-forwarding works, but for production, use an Ingress controller like Nginx or Istio.

Bash
kubectl port-forward svc/argocd-server -n argocd 8080:443

Log in with the default admin password, which is the name of the initial server pod:

Bash
kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2

Step 2: Defining Your Declarative Infrastructure

Don't just point Argo CD at a raw directory. Structure your repo to separate your application code from your deployment manifests. I typically use a base and overlays pattern with Kustomize.

Here’s a basic Application manifest that tells Argo CD where to look:

YAML
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: 'https://github.com/my-org/my-app-manifests.git'
    targetRevision: HEAD
    path: overlays/production
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: my-app-prod
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

The selfHeal: true flag is the magic piece. It ensures that if the live state drifts from Git, Argo CD forces the cluster to match the repository.

Step 3: Integrating with CI/CD Pipelines

You might wonder where your CI pipeline fits in. Your CI pipeline should build the Docker image, push it to your registry, and then—crucially—update the image tag in the Git repository.

Don't let the CI pipeline talk to Kubernetes. Let the CI pipeline talk to Git. This creates an audit log of every change, who made it, and exactly what version is deployed.

Common Pitfalls to Avoid

  1. Secret Management: Never store raw secrets in Git. Use tools like External Secrets Operator or Bitnami Sealed Secrets. They allow you to commit encrypted manifests that only your cluster can decrypt.
  2. Over-Syncing: If you have high-frequency deployments, disable selfHeal temporarily during maintenance windows to avoid unnecessary churn.
  3. Ignoring Sync Waves: If your app has dependencies (e.g., a DB migration must finish before the API starts), use Argo CD "Sync Waves" to order your deployments.

The Result

Once you’ve implemented this, your workflow changes. You stop SSHing into nodes or running kubectl commands. Instead, you submit a Pull Request. Once approved and merged, Argo CD handles the heavy lifting of rolling out the change.

It’s cleaner, it’s auditable, and most importantly, it’s repeatable. When a cluster dies, you don't panic. You just point a new cluster at your Git repository, and Argo CD reconstructs your entire production environment in minutes.

That’s the power of Declarative Infrastructure. Stop managing servers; start managing state.

Similar Posts