Skip to content

ArgoCD Setup

ArgoCD is the GitOps engine that drives the cluster. It is installed via Helm, bootstrapped with a single kubectl apply, and then manages itself going forward.


Bootstrap Process

The bootstrap follows a three-step process that takes the cluster from a bare Kubernetes installation to a fully self-managing GitOps platform.

flowchart TD
    A[1. Apply app-argocd.yaml] -->|creates| B[ArgoCD Bootstrap Application]
    B -->|points to| C[pitower/kubernetes/bootstrap/]
    C -->|installs| D[ArgoCD Helm Chart\n+ Namespace\n+ AppProject]
    D -->|ArgoCD starts| E[ArgoCD watches repository]
    E -->|discovers| F[ApplicationSets in\npitower/kubernetes/argocd/]
    F -->|generates| G[Application per app directory]
    G -->|syncs| H[All cluster workloads running]

    style A fill:#7c3aed,color:#fff
    style B fill:#ef652a,color:#fff
    style D fill:#ef652a,color:#fff
    style E fill:#ef652a,color:#fff
    style F fill:#18b7be,color:#fff
    style H fill:#326ce5,color:#fff

Step 1: Apply the Bootstrap Application

The only manual kubectl command needed to bring up the entire cluster:

kubectl apply -f pitower/kubernetes/argocd/app-argocd.yaml

This creates the argocd-bootstrap Application resource, which tells ArgoCD to look at the pitower/kubernetes/bootstrap/ directory for its own installation manifests.

Step 2: ArgoCD Installs Itself

The bootstrap Application points to a Kustomization that includes:

Resource Purpose
namespace.yaml Creates the argocd namespace
appproject.yaml Creates the apps AppProject with admin RBAC
argocd-values.yaml Helm values for the ArgoCD chart
kustomization.yaml Ties everything together with HelmChartInflationGenerator

The kustomization.yaml uses the helmCharts field to install ArgoCD from the official Helm chart:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - namespace.yaml
  - appproject.yaml

helmCharts:
  - name: argo-cd
    version: 9.4.2
    repo: https://argoproj.github.io/argo-helm
    releaseName: argocd
    namespace: argocd
    valuesFile: argocd-values.yaml

Step 3: ArgoCD Discovers Everything Else

Once ArgoCD is running, it picks up the ApplicationSets defined in pitower/kubernetes/argocd/. Each ApplicationSet scans a category directory and generates Applications for every subdirectory it finds.

Self-Managing

After the initial kubectl apply, ArgoCD manages its own upgrades. Changing the Helm chart version in kustomization.yaml and pushing to main triggers ArgoCD to upgrade itself.


Bootstrap Application

The app-argocd.yaml is the single entry point for the entire cluster:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: argocd-bootstrap
  namespace: argocd
spec:
  project: default
  source:
    repoURL: 'https://github.com/swibrow/home-ops.git'
    targetRevision: main
    path: pitower/kubernetes/bootstrap
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: true
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true

selfHeal is enabled here

Unlike the ApplicationSets for workloads (which disable selfHeal), the bootstrap Application does enable selfHeal. ArgoCD must always match the desired state to keep the cluster operational. If someone accidentally modifies ArgoCD's own resources, it will self-correct.


AppProject: apps

The bootstrap process creates an AppProject named apps that all ApplicationSet-generated Applications belong to. This project defines the security boundary for workload applications.

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: apps
  namespace: argocd
spec:
  description: Apps
  sourceRepos:
    - https://github.com/swibrow/home-ops
  destinations:
    - namespace: "*"
      name: "*"
  clusterResourceWhitelist:
    - group: "*"
      kind: "*"

Key properties of the apps project:

Property Value Reason
sourceRepos home-ops only Applications can only pull from the home-ops repository
destinations All namespaces, all clusters Apps can deploy to any namespace on the local cluster
clusterResourceWhitelist All groups, all kinds Apps can create cluster-scoped resources (CRDs, ClusterRoles, etc.)

Broad Permissions

The apps project grants wide permissions because this is a single-tenant home lab. In a multi-team environment, you would scope destinations and clusterResourceWhitelist per project.


Project Structure Summary

flowchart TD
    subgraph "ArgoCD Projects"
        Default["default project\n(bootstrap only)"]
        AppsProj["apps project\n(all workloads)"]
    end

    subgraph "Applications"
        Bootstrap["argocd-bootstrap\n(self-managing)"]
        AppSets["15 ApplicationSets"]
        GenApps["Generated Applications\n(one per app directory)"]
    end

    Default --> Bootstrap
    Bootstrap -->|installs ArgoCD +\ncreates apps project| AppsProj
    AppsProj --> AppSets
    AppSets -->|Git directory generator| GenApps

    style Default fill:#333,color:#fff
    style AppsProj fill:#7c3aed,color:#fff
    style Bootstrap fill:#ef652a,color:#fff
    style AppSets fill:#18b7be,color:#fff
    style GenApps fill:#326ce5,color:#fff
  • The argocd-bootstrap Application lives in the default project (ArgoCD's built-in project).
  • All workload Applications generated by ApplicationSets live in the apps project.
  • The bootstrap Application is the only resource that needs to be applied manually. Everything else is discovered and managed automatically.