Managing Hundreds of Amazon EKS Clusters at Fleet Scale · Part 1 of 18

Managing Hundreds of EKS Clusters: The Fleet Reference Architecture

The opener to an 18-part series. Once you run clusters by the hundred, the job stops being "operate a cluster" and becomes "operate a platform that emits clusters." This piece lays out the whole platform shape — GitOps-driven hub-and-spoke — and maps where every later article fits.

TL;DR

Run the fleet as one platform, not hundreds of pets. One Git repo holds the desired state; a stable IaC core module provisions each cluster and hands off — through a GitOps bridge — to Argo CD or Flux, which reconciles add-ons and workloads forever. Every cluster ships the same golden-path defaults, and policy-as-code (not tickets) keeps them consistent. The number that forces this thinking: at 300 clusters you pay roughly $21,900/month in control-plane fees before a single workload runs.2

Design it this way

  • Treat clusters as replaceable cattle: one Git source of truth, one Argo CD hub, many spoke clusters.
  • Provision with a stable Terraform core module (or Cluster API); hand off to Argo CD / Flux for add-ons and workloads.
  • Bake the same defaults into every cluster: Karpenter, EKS Pod Identity, access entries, policy-as-code.
  • Standardize the Kubernetes version and let policy enforce consistency across the fleet.

Don't do this

  • Don't click-ops or hand-build clusters one at a time.
  • Don't use EKS Blueprints to provision the core cluster in production — core module for the cluster, Blueprints for add-ons.
  • Don't let each team pick its own identity model, add-ons, or K8s version.
  • Don't ignore the per-cluster control-plane floor — it compounds fast.
Figure 1 · The fleet reference architecture Platform account (management) · us-east-1Platform VPCAccount A · us-east-1Spoke VPCAccount B · eu-west-1Spoke VPCAccount C · ap-southeast-1Spoke VPCGitOps syncGitOps syncGitOps syncArgo CD hubclusterManaged Prometheus+ GrafanaEKS spoke clusterEKS spoke clusterEKS spoke cluster+ hundreds morespoke clusters acrossaccounts / Regions
One Argo CD hub drives the desired state of every spoke cluster across accounts and Regions — the clusters are cattle, the platform is the product.

Why hundreds of clusters stop being a cluster problem

Running one EKS cluster well is a solved craft: pick a version, size some nodes, wire up IAM, ship workloads. Running three hundred of them is a different job entirely. The unit of thought changes from the cluster to the fleet, and every decision you used to make by hand — version, identity, networking, add-ons, cost — becomes an organization-scale policy problem.

Fleets this size are not hypothetical. Salesforce reported migrating more than 1,000 EKS clusters to Karpenter in a single program15 (a vendor-reported figure, not an AWS benchmark). When you operate at that count, artisanal per-cluster operations simply don't survive contact with reality — drift, inconsistent upgrades, and one-off IAM wiring turn into incidents.

The cleanest way to feel the shift is the bill. The EKS control-plane fee is a fixed floor of $0.10 per cluster-hour in standard support — about $74/month per cluster. Multiply out to 300 clusters and you're paying roughly $21,900/month (300 × $0.10 × 730 hours) in control-plane fees alone, before a single pod is scheduled.2 That number reframes the whole design: your job as a fleet operator is to make the marginal cluster cheap to create, cheap to keep consistent, and cheap to retire. (Pricing current as of 2026-06-30; re-verify at publish time.)

The shape to build toward — GitOps-driven hub-and-spoke

The golden path this whole series argues for is a GitOps-driven hub-and-spoke platform. Git holds the desired state of the fleet. A central Argo CD hub reconciles that state onto many spoke clusters spread across accounts and Regions. No human logs into a spoke cluster to change it; you change Git, and the platform converges the fleet (Figure 1).

The reason to default to Argo CD in the hub is reach from one place. Argo CD ApplicationSets, with cluster generators and label selectors, let you target the entire fleet from a single control plane — "every cluster labeled env=prod gets this add-on" — and you get one pane of glass over the whole estate.8

That centralization has a real cost, and it would be dishonest to skip it.

The Argo hub is a blast-radius concern, and its UI is reported to slow past roughly 3,000–5,000 applications (a practitioner figure, not a hard AWS limit).8

Flux is the first-class alternative: a distributed pull model with one instance per cluster pointing at a fleet repo, leaner, scaling with the API server, and better for edge or air-gapped clusters — at the cost of the single pane of glass. A common hybrid runs Flux for infrastructure and Argo CD for applications. The full Argo-vs-Flux decision is its own article later in the series.

How a cluster gets born and stays converged — IaC hands off to GitOps

A fleet has two distinct phases, and the whole platform hinges on the seam between them (Figure 2). First a cluster is provisioned; then it is reconciled forever.

For provisioning, AWS now recommends a stable core EKS Terraform module for the cluster itself, with EKS Blueprints patterns reserved for add-ons — explicitly not using Blueprints to provision the core cluster in production.7 The Kubernetes-native alternative is Cluster API (CAPA), which gives you declarative, in-cluster lifecycle management but obliges you to run a highly-available management cluster — if it goes down, all cluster operations stop.9

The handoff is the part the diagrams usually gloss over. The GitOps bridge pattern has IaC write its generated metadata — IAM role ARNs and similar outputs — into the Argo CD cluster secret, so ApplicationSets and Helm charts can consume real values instead of hard-coded ones.7 That secret is the seam where "provision once" hands off to "reconcile forever."

After the bridge, Argo CD or Flux owns the cluster's add-ons and workloads and continuously corrects drift back to what Git says. Provisioning is a one-time act; reconciliation never stops. Fleet provisioning, GitOps management, and golden-path templates each get their own deep-dive later.

Figure 2 · The golden-path pipeline PROVISION ONCE — IaC RECONCILE FOREVER — GitOps Git fleet desired state IaC core module provisions the cluster Argo CD / Flux reconciles the cluster Cluster add-ons + workloads GitOps bridge IAM ARNs → cluster secret observe drift → resync Every cluster ships the same defaults: Karpenter · EKS Pod Identity · access entries · policy-as-code
Provisioning is a one-time act; reconciliation never stops. The Argo cluster secret is the bridge where IaC outputs cross into continuous GitOps.

What every cluster ships with by default — the golden-path template

The point of a fleet platform is that a new cluster is never a blank slate. It comes off the line with the same opinionated defaults, so consistency is the path of least resistance rather than a review checklist. Four defaults define the template.

Compute: Karpenter. Karpenter is the fleet standard for autoscaling — groupless, workload-aware, provisioning best-fit EC2, mixing Spot and On-Demand in a single NodePool, and consolidating idle nodes.6 One honest caveat up front: AWS states there is no SLA for Karpenter; you own its operation. EKS Auto Mode is the managed alternative (a fee of roughly 12% on top of EC2 cost), covered later in the autoscaling article.

Identity: EKS Pod Identity. For EKS-in-cloud, EKS Pod Identity is the recommended default over IRSA — no per-cluster OIDC provider, IAM roles reusable across clusters, and IAM decoupled from cluster administration.3 IRSA doesn't go away: you still need it for Fargate, Windows, and portability to non-EKS or self-managed clusters.4 The identity article goes deep on the split.

Access: access entries. Cluster access is granted through EKS access entries, which replace the deprecated aws-auth ConfigMap and let you manage authorization as an AWS-native, auditable API rather than a hand-edited in-cluster map.5

Guardrails: policy-as-code. A golden-path template is only as good as what stops a team from stepping off it. Policy-as-code — Kyverno (YAML policies) or OPA/Gatekeeper (Rego) — enforces the baseline: no privileged pods, no host namespaces, no privilege escalation.10 Roll it out in audit mode first, then enforce, and manage the policies through the same GitOps flow as everything else.

The three decisions that will hurt — many-vs-few, IP exhaustion, cost drift

Most of the fleet is mechanical once the platform exists. Three decisions are not — they're expensive to reverse and each has a hard number behind it, so each earns its own article (Figure 3).

How many clusters? The control-plane floor (300 clusters ≈ $21,900/month2) pushes hard toward fewer, larger clusters. Isolation, blast radius, and compliance push the other way — and AWS's own scalability guidance is to use separate clusters for dev, test, and prod rather than namespaces for hard environment isolation.14 Getting that balance right is the many-vs-few article.

Will you run out of IP addresses? This one ambushes teams. On an m5.large you get only 29 pod IP addresses without prefix delegation, and 110 with it.1112 The trap: an EKS cluster is permanently bound to its creation-time VPC and subnets — you cannot migrate it to another VPC later.13 Addressing is a decision you make once, at the start, or pay for forever. That's the networking article.

Are you falling behind on upgrades? A version gets 14 months of standard support, then 12 months of extended support at a 6× control-plane price — $0.10 rises to $0.60 per cluster-hour.12 Let a fleet drift into extended support and the bill compounds across every lagging cluster. Upgrades and cost management are two later articles that share this math. (Version calendar and pricing current as of 2026-06-30; re-verify before acting.)

Figure 3 · The three hard decisions The three decisions the rest of the series is really about Many vs few clusters ≈ $21.9K/mo 300 clusters × $0.10 × 730h — the control-plane floor, before a single workload runs. → Article 02 IP exhaustion 29 → 110 pod IPs on one m5.large: bare vs prefix delegation. A cluster's VPC binding is permanent. → Article 08 Extended-support drift $0.10 → $0.60 the 6× jump when a version leaves standard support at 14 months. → Articles 14 & 15
Each hard decision has a number behind it and its own article — this figure is also your map to the three that matter most.

How the rest of the series maps onto this architecture

Every later article is a component of the platform in Figure 1. Read them in order and they build the fleet layer by layer; dip into one and you'll know exactly which part of the architecture it fills in.

#ArticleWhere it sits in the architecture
01Fleet reference architectureThis piece — the whole shape and the map
02Many vs few clustersThe tenancy + cost decision behind cluster count
03Fleet provisioning with IaCThe "provision once" half: core module vs Cluster API
04GitOps fleet managementThe Argo hub: ApplicationSets, Argo vs Flux
05Golden paths & the IDPThe self-service template teams consume
06Policy-as-codeThe guardrails: Kyverno / Gatekeeper baseline
07Greenfield reference architectureA concrete build of the golden path
08Networking & IP planningThe VPC/subnet layer and IP exhaustion
09Multi-cluster connectivityLoad balancing, mesh, and cross-cluster wiring
10Identity: Pod Identity vs IRSAThe identity default and its exceptions
11Secrets, supply chain, complianceThe secrets + encryption layer per cluster
12Autoscaling with KarpenterThe compute layer and EKS Auto Mode
13Observability at scaleManaged Prometheus + Grafana across the fleet
14Day-2 upgradesKeeping the fleet inside standard support
15Cost management & showbackThe four billing streams and the control-plane floor
16Migrating self-managed KubernetesGetting existing clusters onto the platform
17Migrating VM / legacy workloadsBringing non-container apps into the fleet
18Hybrid & the transition (capstone)Extending the platform beyond the cloud

When this shape is right — and when to build something smaller

Here's the decision to carry out of this piece. Build the full GitOps hub-and-spoke platform when you have dozens or more clusters spread across teams, accounts, and Regions, and you need consistency, compliance, and an auditable trail for every change. That's the situation the rest of the series is written for.

Don't build it for three clusters and one team. Standing up an Argo hub, a golden-path template, and policy-as-code for a handful of clusters is overhead you'll feel and won't recoup; a single Terraform repo with managed add-ons is enough at that size. The platform earns its keep at fleet scale, not before.

But adopt the defaults early even when you stay small: EKS Pod Identity, access entries, and Karpenter cost nothing extra to choose on day one, and retrofitting identity, policy, and GitOps onto a sprawling fleet later is the genuinely expensive path. Start on the golden path; grow the platform around it as the cluster count climbs.

The next article takes the first hard decision head-on: how many clusters should you actually run, and where the isolation-versus-cost line really falls.

Sources

Version and pricing facts are current as of 2026-06-30 and should be re-verified against the primary source before acting — EKS version and pricing details roll forward roughly every four months.

  1. AWS — Amazon EKS Kubernetes versions: standard support (14 months) + extended support (12 months) lifecycle. docs.aws.amazon.com/.../kubernetes-versions.html
  2. AWS — Amazon EKS pricing: control plane $0.10/cluster-hour standard, $0.60 extended; per-cluster floor and the many-vs-few cost math. aws.amazon.com/eks/pricing
  3. AWS — EKS Pod Identities: the recommended default over IRSA for EKS-in-cloud. docs.aws.amazon.com/.../pod-identities.html
  4. AWS — IAM roles for service accounts (IRSA): still required for Fargate, Windows, and portability. docs.aws.amazon.com/.../iam-roles-for-service-accounts.html
  5. AWS — EKS access entries: replace the deprecated aws-auth ConfigMap. docs.aws.amazon.com/.../access-entries.html
  6. Karpenter: groupless, workload-aware autoscaling; NodePool/EC2NodeClass; no AWS SLA. karpenter.sh
  7. AWS — Terraform EKS Blueprints: stable core module for the cluster + Blueprints patterns for add-ons; the GitOps bridge. aws-ia.github.io/terraform-aws-eks-blueprints
  8. Argo CD documentation: ApplicationSets with cluster generators/label selectors; central hub-and-spoke and its scale limits. argo-cd.readthedocs.io
  9. Cluster API Provider AWS (CAPA): declarative cluster lifecycle requiring an HA management cluster. cluster-api-aws.sigs.k8s.io
  10. Kyverno: YAML policy-as-code; baseline enforcement in audit-then-enforce mode (vs OPA/Gatekeeper). kyverno.io
  11. AWS — Choosing an EKS instance type: pod-per-node and bare pod-IP limits (m5.large = 29 without prefix delegation). docs.aws.amazon.com/.../choosing-instance-type.html
  12. AWS — Increase IP addresses (prefix delegation): raises m5.large to 110 pods. docs.aws.amazon.com/.../cni-increase-ip-addresses.html
  13. AWS — EKS network requirements: a cluster is permanently bound to its creation-time VPC/subnets. docs.aws.amazon.com/.../network-reqs.html
  14. AWS — EKS Best Practices: separate clusters for dev/test/prod vs namespace multi-tenancy. docs.aws.amazon.com/eks/latest/best-practices
  15. InfoQ (Jan 2026), reporting Salesforce: 1,000+ EKS clusters migrated to Karpenter (vendor-reported practitioner figure, not an AWS benchmark). infoq.com