New: Workbenches are here. Build your own DevOps agents.

Fleet Scale GitOps

GitOps for IaC and Kubernetes at fleet scale

Implement GitOps across IaC and K8s, even at thousand-cluster scale. One pull-based system reconciles Terraform, Helm, and manifests into any cloud, datacenter, or edge site, and every change is reviewed in Git.

Fleet architecture
AWSprivate networkprod-use1EKS · 1.31agentprod-euw1EKS · 1.31agentAzureprivate networkprod-eusAKS · 1.31agentdev-wusAKS · 1.31agentGCPprivate networkdata-usc1GKE · 1.31agentml-use4GKE · 1.31agentEdgeprivate networkstore-0412k3s · 1.31agentstore-0977k3s · 1.31agentagents poll · egress only · tolerant of intermittent linksPlural control planemanagement clusterGit cacheauto-shardedTemplatingper-cluster valuesAuth proxyagent gRPC tunnelIaC stacksTerraform, PulumiGit · Helm · OCI · Terraform modules
✓ Agent-initiated, egress-onlyEach cluster polls for its own desired state. Nothing needs a route into your clusters.
✓ No central kubeconfigsThe control plane never holds cluster-admin credentials, so there is no single key to the fleet.
✓ Scales with the fleetNo watch streams or single-master control loops. Adding the thousandth cluster is like adding the first.

Pull architecture

Built for the fleet you’ll have, not the one you have today

Most GitOps tools centralize credentials and push changes through long-lived watch streams. That works for ten clusters and breaks at a thousand. Plural inverts it: a thin agent on each cluster pulls its desired state, so the control plane never needs to reach in.

Runs anywhere

Manage workloads in any cloud, on-prem, at the edge, or on a laptop running KIND. If it runs Kubernetes, it can join the fleet.

Secure by default

An agent-initiated gRPC tunnel powers the auth proxy, so you get full dashboards without multi-cloud networking or exposed cluster APIs.

Horizontally scalable

The Git cache auto-shards across the control plane, and there are no watch streams or single-master control loops to saturate.

Toolchain agnostic

Helm, Kustomize, raw manifests, and Liquid templating today, with an agent built to support whatever comes next.

Every layer

Cloud infrastructure and workloads in one GitOps workflow

Stop stitching together Argo CD, Flux, Atlantis, and custom scripts. Plural reconciles the whole stack from Git, from the VPC to the Helm chart.

IaC stacks, reconciled on every commit

Turn any Terraform, Pulumi, or Ansible codebase into a stack that runs on every commit. Plans land in the pull request for review, so nobody applies changes from a laptop with admin credentials.

Runs execute on a cluster next to the resources they manage, over egress-only networking.

How stacks work
stacks/eks-prod.yaml
apiVersion: deployments.plural.sh/v1alpha1
kind: InfrastructureStack
metadata:
name: eks-prod
namespace: stacks
spec:
type: TERRAFORM
approval: true # plan in the PR, apply on approval
manageState: true
repositoryRef:
name: infra
namespace: infra
clusterRef:
name: mgmt-use1 # runs next to the resources it manages
namespace: infra
git:
ref: main
folder: terraform/eks-prod

Terraform outputs flow straight into Kubernetes

Cluster metadata set in Terraform, like IAM role ARNs, hostnames, and domains, is templated into Helm values at deploy time. No copy-pasting outputs, no per-cluster forks of the same chart.

Infrastructure and the services that depend on it change together, in one declarative commit.

terraform → helm values
terraform/eks-prod/cluster.tf
resource "plural_cluster" "this" { name = "eks-prod" tags = { fabric = "eks" } metadata = jsonencode({ domain = "prod.acme.dev" externaldnsRoleArn = module.iam.arn }) }
helm-values/externaldns.yaml.liquid
domainFilters:
- {{ cluster.metadata.domain }}
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: >-
{{ cluster.metadata.externaldnsRoleArn }}

One hierarchy, one permission model

Projects own stacks and clusters, and clusters own services. Permissions granted on a parent flow down automatically, so “this team owns these clusters” is a single binding mapped to your SSO groups.

Ownership · permissions flow down
Projectteam boundary · RBAC root
└ StackTerraform · Pulumi · Ansible
└ ClusterEKS · AKS · GKE · k3s · on-prem
└ ServiceHelm · Kustomize · YAML

Fleet-wide

Deploy once, land on every cluster that matches

Define a service once and Plural keeps it running everywhere it belongs, including clusters that don’t exist yet.

Global services target by tag, not by list

Replicate ingress controllers, service meshes, cert-manager, and your own platform add-ons across the fleet by tag, Kubernetes distribution, or Cluster API provider.

New clusters pick up their baseline the moment they register.

Global services in the docs
services/external-dns.yaml
apiVersion: deployments.plural.sh/v1alpha1
kind: GlobalService
metadata:
name: external-dns
namespace: infra
spec:
tags:
fabric: eks # every EKS cluster, now and in the future
template:
git:
url: git@github.com:acme/infra.git
ref: main
folder: helm-values
helm:
chart: externaldns
version: 6.31.4
valuesFiles:
- externaldns.yaml.liquid

Promote safely from dev to a thousand prod clusters

Pipelines move changes through environments with approval gates and automated checks between stages. Pair them with Sentinels to prove each stage is healthy before the next one starts.

How pipelines work
Pipeline · external-dns v6.31.4
dev12 clusters✓ healthy
staging48 clusters✓ sentinel passed
prod940 clusters● awaiting approval
Approve promotion to prod
We reduced our k8s upgrade cycles from 3 months to 1 day, and delegated them from principal engineers to a single mid-level engineer.
Director of DevOps
Global cybersecurity provider

Questions

Does Plural need network access to my clusters?
No. The deployment agent on each cluster initiates every connection and polls the control plane for changes. Even the dashboard and auth proxy run over a channel the agent opens, so cluster APIs never need to be exposed.
Which infrastructure-as-code tools are supported?
Terraform, Pulumi, and Ansible are supported natively, and custom stacks let you bring any other toolchain. Plans are posted to pull requests, and runs execute on a cluster close to the resources they manage.
How does this work for edge and on-prem clusters?
Because agents pull, a cluster behind NAT, a firewall, or an intermittent link simply catches up when it can reach the control plane. Lightweight distributions like k3s are fully supported.
Can we self-host the control plane?
Yes. Run Plural as a managed service, or deploy the control plane onto any Kubernetes cluster you designate as your management cluster.

GitOps that scales with your fleet

See Plural reconcile IaC and Kubernetes across your clusters in a 30-minute demo.