Skip to content

GitOps with ArgoCD

Why GitOps?

kubectl apply from a developer's laptop is not auditable, reproducible, or safe. With ArgoCD:

  • Every change is a Git commit — auditable, reviewable, revertible
  • The cluster state always matches what's in Git
  • No direct kubectl access needed for deployments
  • Drift detection — ArgoCD alerts if someone changes resources manually

App-of-Apps Pattern

We use ArgoCD's app-of-apps pattern: a single root Application watches k8s/argocd-apps/ and creates child Applications.

k8s/root-app.yaml                    ← Apply once manually
    │
    ├── k8s/argocd-apps/
    │   ├── knative-config.yaml       → watches k8s/knative/
    │   ├── demo-apps.yaml            → watches k8s/apps/
    │   └── kro.yaml                  → watches k8s/kro/
    │
    └── Each child Application syncs its own directory

Bootstrap

# After terraform installs ArgoCD, apply the root app once:
kubectl apply -f k8s/root-app.yaml

# ArgoCD takes over from here — all changes via Git

What Goes Where

Layer Tool Why
AKS, networking, Event Hubs, ACR Terraform Infrastructure lifecycle, state management
DAPR extension, Istio addon Terraform AKS extensions are ARM resources
Managed Identities, role assignments Terraform IAM is infrastructure
KNative config, brokers, triggers ArgoCD Application-level Kubernetes resources
KRO ResourceGraphDefinitions ArgoCD Platform CRDs
Applications (AcmeService instances) ArgoCD Workloads
NetworkPolicies, AuthorizationPolicies ArgoCD Generated by KRO or declared in k8s/apps/

Secrets

Secrets stay out of Git

kafka-auth-secret contains SAS credentials for Event Hubs. It is created manually (or via External Secrets Operator) and is not managed by ArgoCD.

# Manual secret creation
kubectl create secret generic kafka-auth-secret \
  --from-literal=password='Endpoint=sb://...' \
  --from-literal=protocol='SASL_SSL' \
  --from-literal=sasl.mechanism='PLAIN' \
  --from-literal=user='$ConnectionString'

Directory Structure

k8s/
├── root-app.yaml              # Bootstrap (apply once)
├── argocd-apps/               # App-of-apps: each file = one ArgoCD Application
│   ├── knative-config.yaml    # → k8s/knative/
│   ├── demo-apps.yaml         # → k8s/apps/
│   └── kro.yaml               # → k8s/kro/
├── knative/                   # Broker config, triggers
├── apps/                      # Demo apps + security policies
├── istio/                     # Istio config for KNative namespaces
└── kro/                       # KRO ResourceGraphDefinition + examples