9ebc9c8868
---ci--- project: atelier phase: 6 milestone: v0.3 status: complete requirements: covered: [ATELIER-60..91] partial: [] ---/ci---
8.3 KiB
8.3 KiB
ArgoCD — Derived Rules
Derives from
domains/gitops-operators/first-principles.md. Applies P1–P10 to ArgoCD specifically. For the ArgoCD-vs-Flux decision, see the decision matrix at the end of this doc and influx.md.
What ArgoCD Is (P1 Git is the Source of Truth, P3 Pull, Don't Push)
- ArgoCD is a pull-based GitOps controller for Kubernetes. It runs
inside the target cluster, pulls desired state from git, and
reconciles the cluster to match. CI never holds
kubectlrights against the cluster (P3). - An Application is a declarative binding of "this git path" to "this cluster destination." The Application CRD is the unit of reconciliation. The cluster is a derivative of git, never the authority (P1).
- ArgoCD supports Helm charts, Kustomize overlays, ksonnet, and raw
manifests as source formats — see
domains/kubernetes/helm.mdanddomains/kubernetes/kustomize.md.
Application CRD (P2 Declarative Over Imperative, P4 Continuous Reconciliation)
- An Application declares
source(repo, path, revision, chart),destination(server, namespace), andsyncPolicy. The reconciler loops continuously; drift is corrected automatically, not on-demand (P4).
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: payments-api
namespace: argocd
spec:
source:
repoURL: https://git.example.com/platform/payments
targetRevision: 1.2.3
path: manifests/prod
destination:
server: https://kubernetes.default.svc
namespace: payments
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=false
automated.prune: truedeletes resources removed from git.selfHeal: truecorrects hand-edited drift back to git (P8). Disable both for workloads that need manual approval gates.
App-of-Apps (P6 Operators Encode Domain Knowledge, C6 Composability)
- The App-of-Apps pattern: one root Application points at a git directory of child Application manifests. The root app reconciles the children; the children reconcile the workloads. This is the ArgoCD expression of composition — a fleet of apps as a tree of Applications.
- Use App-of-Apps for cluster bootstrapping (one repo, many clusters, many apps). Do not use it as a substitute for a package manager; if you are templating hundreds of near-identical Applications, use a generator (ApplicationSet) instead.
Sync Waves and Hooks (P4 Continuous Reconciliation, P7 Reversibility)
- Sync waves order resources within a sync:
PreSync→Sync→PostSync. Use waves to run a job before a Deployment, or a migration before the app that depends on it. - Sync hooks (
PreSync,Sync,PostSync,SyncFail) are Resources annotated to execute at a wave boundary. ASyncFailhook runs on sync failure — the abort path (P7). - Wave ordering is a correctness mechanism, not a performance one. Mis-ordered waves (e.g., app starts before its migration job) are a correctness bug.
Health and Status (P9 Failure is Observable and Surfaced)
- ArgoCD assesses every resource's health (
Healthy,Progressing,Degraded,Missing,Suspended) and surfaces the aggregate as Application status. Sync status (Synced,OutOfSync) reports drift against git. - Health checks are pluggable via Lua scripts for custom CRDs. An
Operator-managed CRD without a health check reads as
Progressingforever — write one (seeoperators.md). - Out-of-sync or degraded status must emit a notification (Slack,
PagerDuty, webhook). Silent drift is the bug (P9). Wire status to
domains/observability/metrics.md.
Diff and Drift (P8 Reconcile, Don't Mutate by Hand, P4)
argocd app diffshows the diff between git and live cluster. A non-empty diff on a synced app is hand-edit drift — the recovery isselfHeal, not a manualkubectl apply(P8).- Drift detection runs continuously (P4). The gap between "git changed" and "cluster matches git" is observable, not assumed.
RBAC and SSO (P10 Least Privilege Reconciliation)
- ArgoCD's own RBAC governs who can view, sync, and admin Applications. Bind to SSO (OIDC, SAML) for human identity; bind the controller's service account to a Role scoped to the namespaces it reconciles.
- The controller's credentials must not be
cluster-admin(P10). Use namespace-scoped Roles viaApplicationSetnamespaces or cluster-wide AppProject restrictions. Seedomains/kubernetes/rbac.mdanddomains/security/authorization.md. - AppProjects bound the blast radius of what an Application can deploy (allowed repos, destinations, roles). One AppProject per team or environment; the default project is for nothing in production.
Multi-Cluster (P4 Locality, P10)
- ArgoCD registers external clusters by secret. The controller pulls from git and pushes to the registered cluster's API server. The "pull, don't push" boundary (P3) is between the target cluster's reconciler and CI — the controller-to-apiserver hop is internal to the platform.
- Scope each registered cluster's credentials to the namespaces ArgoCD manages there. Do not register a cluster with cluster-admin and call it done (P10).
Sync Windows (P5 Reversibility, P7)
- Sync windows restrict when automated sync runs (e.g., no syncs during business hours, or syncs only in a maintenance window). They are a reversibility mechanism: a bad commit lands in git, but the sync window holds it until review.
- Sync windows do not replace health monitoring (P9). A degraded app inside a window is still an incident.
Secrets (P10, cross-link security/secrets)
- Do not store raw Secrets in the GitOps repo. Use a sealed-secret
controller (Bitnami Sealed Secrets, SOPS, External Secrets
Operator) so the git store holds encrypted material only. See
domains/security/secrets.mdfor the general secret-hygiene principles.
ArgoCD vs Flux — Decision Matrix (IDEATE-21, D-039)
| Axis | ArgoCD | Flux |
|---|---|---|
| Architecture | Monolithic controller + Application CRD | Composable GitOps Toolkit controllers (source, kustomize, helm, notification) |
| Reconciliation unit | Application (one CRD per app) | Kustomization / HelmRelease (one per deploy unit) |
| UI | Web UI + CLI (full dashboard, tree view, diff viewer) | CLI-first; UI via Weave GitOps or FluxUI (add-on) |
| Sync model | Periodic poll or webhook; sync waves + hooks | Poll + webhook; runs continuously, no explicit sync waves |
| Multi-cluster | One ArgoCD manages many clusters (hub-and-spoke) | One Flux per cluster (per-cluster autonomy) |
| Templating in repo | Helm, Kustomize, ksonnet, raw manifests, Jsonnet | Helm, Kustomize, raw manifests |
| RBAC | Built-in RBAC + SSO + AppProjects | Kubernetes RBAC (no built-in RBAC layer) |
| Progressive delivery | Argo Rollouts (sister project, tight integration) | Flagger (sister project, tight integration) |
| Best for | Teams wanting a UI, multi-cluster from one pane, App-of-Apps bootstrapping | Teams wanting composable controllers, per-cluster autonomy, minimal footprint |
| Watch out for | Monolithic controller scaling, UI as ops crutch, AppProject sprawl | No native UI, steeper learning curve, manual multi-cluster orchestration |
- Use ArgoCD when you want a UI, central multi-cluster management, and sync-wave ordering. Use Flux when you want composable controllers, per-cluster autonomy, and a minimal footprint.
- Both are CNCF graduated and both implement the OpenGitOps
principles. The choice is architectural fit, not correctness. See
flux.mdfor the Flux-side perspective.
What Violates ArgoCD Discipline
| Violation | Principle |
|---|---|
CI pipeline with kubectl rights pushing to the cluster |
P3 Pull, Don't Push |
argocd app set used as the steady state instead of git |
P1 Git is the Source of Truth |
selfHeal: false on a prod app with no manual gate |
P8 Reconcile, Don't Mutate by Hand |
Controller ServiceAccount bound to cluster-admin |
P10 Least Privilege Reconciliation |
| Sync failure with no notification wired | P9 Failure is Observable and Surfaced |
| AppProject with no destination restrictions in prod | P10 Least Privilege Reconciliation |
| Raw Secret in the GitOps repo | P10, domains/security/secrets.md |
Manual kubectl edit on an ArgoCD-managed resource |
P8 Reconcile, Don't Mutate by Hand |