GitOps on Amazon EKS (2026): Argo CD vs Flux, App-of-Apps, and the Decisions That Actually Bite
Quick summary: AWS Prescriptive Guidance says Argo CD and Flux both handle most GitOps scenarios capably — so picking one is a fit decision, not a winner. The decisions that actually cause incidents are the ones underneath: plaintext secrets in the GitOps repo, CI running kubectl apply and reintroducing drift, no App-of-Apps so onboarding is click-ops, and repo topology you can't change later. Here is the Argo CD vs Flux matrix, an App-of-Apps example, and the five traps independent of tool.
Key Takeaways
- AWS Prescriptive Guidance says Argo CD and Flux both handle most GitOps scenarios capably — so picking one is a fit decision, not a winner
- AWS's own Prescriptive Guidance says Argo CD and Flux both handle most GitOps scenarios capably — so the question "which is better
- This is for platform and DevOps engineers running Amazon EKS who want GitOps done right, not the GitOps section of a general DevOps practices post repeated
- Benchmark pattern (not a cited client) — A composite platform onboarding apps onto EKS by hand-creating Argo CD Applications one at a time, with a CI job that also ran "to be safe
- EKS exposes a native Argo CD capability (cluster registration + Application manifests)
Table of Contents
AWS’s own Prescriptive Guidance says Argo CD and Flux both handle most GitOps scenarios capably — so the question “which is better?” is the wrong one, and arguing it is how teams burn a week before writing a single manifest. Both are CNCF-graduated, both use Git as the single source of truth, both reconcile continuously and self-heal drift. Picking one is a fit decision. The decisions that actually cause incidents on Amazon EKS are underneath the tool choice: plaintext secrets in the repo, CI running kubectl apply and quietly reintroducing drift, no App-of-Apps so every new app is click-ops, and a repo topology you can’t change later without pain. This post covers the fit decision quickly and the traps thoroughly.
This is for platform and DevOps engineers running Amazon EKS who want GitOps done right, not the GitOps section of a general DevOps practices post repeated. We ship an Argo CD vs Flux decision matrix and an Argo CD App-of-Apps example.
Benchmark pattern (not a cited client) — A composite platform onboarding apps onto EKS by hand-creating Argo CD Applications one at a time, with a CI job that also ran
kubectl apply“to be safe.” Representative shape, not a billed result: two systems wrote to the cluster, so live state drifted from Git and a rollback-by-Git-revert silently did nothing (the pipeline had already re-applied the old state). Moving to App-of-Apps (onboarding = a commit) and removingkubectl applyfrom CI (build + push to ECR + PR-bump only) made Git authoritative again — at which pointgit revertbecame a real rollback. The fix was process, not a tool swap.
The fit decision (do this in an afternoon, not a quarter)
Run the decision matrix. The honest summary:
- Argo CD — when you want a visual UI / app dashboard, an application-centric model, strong multi-cluster from a central control plane, and enterprise RBAC/SSO. EKS exposes a native Argo CD capability (cluster registration + Application manifests).
- Flux — when you want lightweight, CLI-driven, modular controllers, strong multi-tenancy, and built-in image-update automation, and you don’t need a bundled UI.
Opinionated take: if your org is larger, multi-team, and values a UI for “what’s deployed where,” start with Argo CD — the application-centric model and dashboard reduce onboarding friction. If you’re a lean, CLI-native platform team that wants composable controllers and automated image updates, Flux fits. Either is fine. Don’t run both against the same workloads.
The five traps that actually cause incidents (independent of tool)
- Secrets do not go in Git. Use External Secrets Operator backed by AWS Secrets Manager (or SOPS+KMS, or Sealed Secrets). Git holds references and encrypted material, never plaintext.
- Pod identity, not access keys. Use EKS Pod Identity / IRSA so the controller and workloads get scoped IAM — the same least-privilege discipline as IAM best practices.
- App-of-Apps (or ApplicationSets) for scale. A root app pointing at child apps makes onboarding a commit, not click-ops — see the example. Flux: Kustomization/HelmRelease composition.
- Repo topology, decided up front. Mono-repo vs per-team; environment-per-branch vs environment-per-directory. Changing it later is painful; pick deliberately.
- The CI/reconcile boundary. CI builds, tests, pushes to ECR, and opens a PR bumping the image tag. The controller deploys on merge. CI must not run
kubectl apply— that reintroduces drift and breaks Git-as-source-of-truth.
What broke — A team committed a Kubernetes Secret manifest with a base64-encoded (not encrypted) database password to the GitOps repo, reasoning “the repo is private.” A contractor with read access — legitimately granted for a different service — now had the prod DB credential, and base64 is encoding, not encryption. Caught in a routine access review, not by tooling. They rotated the credential, moved to External Secrets Operator backed by Secrets Manager (Git now holds only an
ExternalSecretreference), and added a pre-commit secret scanner. base64 in a manifest looks opaque; it protects nothing.
Where GitOps stops and IaC starts
GitOps handles what runs inside the cluster. The cluster itself (EKS control plane, node groups, VPC, IAM) stays in Terraform or CDK with its own drift detection. Crossplane or AWS Controllers for Kubernetes (ACK) can extend the GitOps model to provision AWS managed services declaratively — useful, but keep the boundary clear: IaC for infrastructure, GitOps for workloads.
What to do this week
- Pick one tool with the matrix and commit — stop debating Argo CD vs Flux.
- Audit the repo for plaintext secrets (base64 counts as plaintext). Move them to External Secrets + Secrets Manager.
- Pull
kubectl applyout of CI. CI builds + pushes to ECR + opens a tag-bump PR; the controller deploys on merge. - Bootstrap App-of-Apps so the next app onboards as a commit, using the example.
What this post doesn’t cover
- EKS cluster provisioning, autoscaling, and cost — see EKS + Karpenter cost-optimized autoscaling and Karpenter vs Cluster Autoscaler.
- A full GitOps install walkthrough — this is the decision and trap guide, not a step-by-step; AWS Prescriptive Guidance has install detail.
- Progressive delivery internals (Argo Rollouts / Flagger canary mechanics) — see also blue-green vs canary.
- Exact feature parity between Argo CD and Flux — both evolve; confirm specifics in each project’s upstream docs.
Related: 10 AWS DevOps practices · EKS + Karpenter autoscaling · Terraform vs CDK · Secrets Manager vs Parameter Store · DevOps pipeline setup
If you only do one thing: Pull kubectl apply out of your CI pipeline and let the GitOps controller be the only thing that writes to the cluster. Until Git is the single writer, your “single source of truth” is a story, and your rollbacks are unreliable.
Related reading
- The AWS CLI Bug That Broke /dev/null Across Your Entire System
- AWS Environment Parity: Why Dev/Staging/Prod Drift Costs More Than It Saves
- What DevOps Guides Don
- DevOps on AWS: CodePipeline vs GitHub Actions vs Jenkins
- Two Free LocalStack Alternatives in 2026: MiniStack vs floci
- The Terraform Command Cheat Sheet for AWS Engineers (2026 Edition)
- How to Build Ultra-Fast Asset Pipelines with Bun, Vite, and Rust-Based Tooling (2026)
AWS Cloud Architect & AI Expert
AWS-certified cloud architect and AI expert with deep expertise in cloud migrations, cost optimization, and generative AI on AWS.