Step-by-step guide to automating Kubernetes deployments with ArgoCD

You’ve probably felt the rush of a hot release that lands a bug in production. That panic is real, but it doesn’t have to be. With ArgoCD you can let Git do the heavy lifting, keep your clusters in sync, and ship faster without losing confidence.

Why automation matters now

Kubernetes already gives us a powerful platform, but it also adds a lot of moving parts. Every time a developer pushes a change, someone has to make sure the right yaml files land in the right namespace. Manual steps are slow, error‑prone, and they break the “fail fast” mindset we try to live by. ArgoCD turns the deployment process into a repeatable, auditable workflow that lives in Git – the single source of truth we all trust.

Prerequisites

Before we dive in, make sure you have:

  • A Kubernetes cluster you can admin (any cloud or on‑prem works)
  • kubectl installed and configured for that cluster
  • A Git repository that will hold your manifests
  • Basic knowledge of yaml and Helm (optional but helpful)

If you’re missing any of these, pause the guide and get them sorted. The steps assume you can run commands locally and have cluster admin rights.

Install ArgoCD

ArgoCD itself runs as a set of pods inside the cluster. The quickest way to get it up is with the official manifest.

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

The command creates a namespace called argocd and drops all the required components there. It takes a minute or two; you can watch the pods with kubectl get pods -n argocd.

Once the pods are Running, expose the UI. For a quick test I use port‑forward:

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

Now open http://localhost:8080 in your browser. The default admin password is the name of the argocd-server pod – you can fetch it with:

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

Log in with user admin and that password, then change the password right away.

Connect ArgoCD to your cluster

ArgoCD can manage any cluster it knows about. If you’re running it inside the same cluster you want to manage, it already has a context called in-cluster. To add an external cluster, run:

argocd cluster add <context-name>

Replace <context-name> with the name you see in kubectl config get-contexts. ArgoCD will store the credentials as a secret, and you’ll see the new cluster listed in the UI under Settings → Clusters.

Define an application

An “Application” in ArgoCD is a pointer to a Git repo, a path inside that repo, and a target namespace. Create a simple yaml file called argo-app.yaml:

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

A few things to note:

  • repoURL points to the Git repo that holds your manifests.
  • path is the folder inside the repo where the yaml files live.
  • destination.namespace is where the resources will be created.
  • The syncPolicy tells ArgoCD to keep the live state in sync automatically, delete resources that disappear from Git (prune), and fix drift (selfHeal).

Apply the file:

kubectl apply -f argo-app.yaml

You’ll see a new entry in the ArgoCD UI. Its status will be OutOfSync until the manifests match the cluster.

Set up a Git repo

If you don’t already have a repo, create one and push a simple deployment. Here’s a minimal example for an Nginx app:

# k8s/production/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.23-alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80

Commit and push this folder to the repo you referenced in argo-app.yaml. ArgoCD will detect the change and start a sync automatically because of the automated policy.

Trigger a sync manually (optional)

Sometimes you want to test a change before the automated loop runs. In the UI click Sync on the application, or use the CLI:

argocd app sync my-app

If everything is wired correctly you’ll see the Nginx pods appear in the prod namespace within seconds.

Tips for faster releases

  1. Keep manifests small – Split large yaml files into logical pieces. Smaller diffs mean quicker syncs.
  2. Use Helm or Kustomize – They let you templatize values and avoid copy‑paste. ArgoCD supports both out of the box.
  3. Enable health checks – ArgoCD can wait for pods to become ready before marking a sync as successful. Add proper readinessProbes to your containers.
  4. Limit auto‑prune – In production you may want to turn off pruning for a while and only enable it after a stable release cycle.
  5. Monitor sync status – Set up alerts on the ArgoCD API for failed syncs. A simple Prometheus rule can save you from a silent drift.

A quick personal note

When I first introduced ArgoCD to my team, we ran into a classic “it works on my laptop” scenario. The culprit was a stray imagePullPolicy: Never in a dev manifest that never made it into Git. Once we forced every change through a pull request, the problem vanished. The lesson? Automation is only as good as the discipline you pair with it. Treat Git like a contract, not a sandbox.

With the steps above you should have a working ArgoCD pipeline that watches a Git repo, keeps your cluster in sync, and gives you fast, reliable releases. The next time you push a change, you’ll see the green check mark instead of a frantic Slack ping.

Reactions
Do you have any feedback or ideas on how we can improve this page?