Amazon EKS — Flux on EKS
Flux is a CNCF graduated GitOps toolkit. Unlike ArgoCD’s UI-first approach, Flux is API-first — entirely managed via Kubernetes custom resources. It’s lightweight, composable, and ideal for platform teams automating multi-tenant clusters.
Bootstrap Flux on EKS
# Install Flux CLI
brew install fluxcd/tap/flux
# Check prerequisites
flux check --pre
# Bootstrap (creates Flux components + Git repo structure)
flux bootstrap github \
--owner=my-org \
--repository=fleet-infra \
--branch=main \
--path=clusters/production \
--personal
This:
- Creates the
fleet-infrarepo (if it doesn’t exist) - Installs Flux components in the cluster (
flux-systemnamespace) - Configures Flux to watch
clusters/production/in the repo
Core CRDs
GitRepository — Define Source
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: my-app
namespace: flux-system
spec:
interval: 1m
url: https://github.com/my-org/my-app-manifests
ref:
branch: main
secretRef:
name: github-token # GitHub PAT or deploy key
Kustomization — Deploy from Source
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
namespace: flux-system
spec:
interval: 5m
targetNamespace: production
sourceRef:
kind: GitRepository
name: my-app
path: ./overlays/production
prune: true # Delete resources removed from Git
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: my-app
namespace: production
timeout: 3m
HelmRelease — Deploy Helm Charts
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: nginx-ingress
namespace: flux-system
spec:
interval: 10m
chart:
spec:
chart: ingress-nginx
version: "4.x"
sourceRef:
kind: HelmRepository
name: ingress-nginx
values:
controller:
replicaCount: 2
service:
type: LoadBalancer
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: ingress-nginx
namespace: flux-system
spec:
interval: 1h
url: https://kubernetes.github.io/ingress-nginx
Multi-Tenancy with Flux
Create separate namespaces with their own GitRepository and RBAC:
# Platform team defines tenant
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: team-a
namespace: flux-system
spec:
interval: 5m
sourceRef:
kind: GitRepository
name: fleet-infra
path: ./tenants/team-a
prune: true
serviceAccountName: team-a # Scoped RBAC
Team-a’s directory structure:
tenants/team-a/
├── namespace.yaml
├── rbac.yaml
├── git-repository.yaml # Team A's app repo
└── kustomization.yaml # Deploys to team-a namespace
Image Automation
Flux can watch ECR for new image tags and update Git automatically:
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
name: my-app
namespace: flux-system
spec:
image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app
interval: 1m
provider: aws # Uses IRSA for ECR auth
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: my-app
namespace: flux-system
spec:
imageRepositoryRef:
name: my-app
filterTags:
pattern: '^v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)$'
extract: '$version'
policy:
semver:
range: '>=1.0.0'
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: my-app
namespace: flux-system
spec:
interval: 1m
sourceRef:
kind: GitRepository
name: fleet-infra
git:
commit:
author:
name: fluxcdbot
email: flux@example.com
messageTemplate: "Update image to {{range .Changed.Changes}}{{.NewValue}}{{end}}"
push:
branch: main
update:
path: ./clusters/production
strategy: Setters
Tag the Deployment image with a marker comment:
spec:
containers:
- name: my-app
image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:v1.0.0 # {"$imagepolicy": "flux-system:my-app"}
Flux vs ArgoCD
| Feature | Flux | ArgoCD |
|---|---|---|
| UI | No native UI (use Weave GitOps) | Built-in web UI |
| Architecture | API-first, CRD-based | UI/CLI with API |
| Multi-tenancy | Built-in with service accounts | AppProject-based |
| Helm support | HelmRelease CRD | Application with Helm source |
| Image automation | Built-in controllers | Separate Image Updater |
| CNCF status | Graduated | Graduated |
| Complexity | Lower (composable controllers) | Higher (monolithic) |
| Best for | Platform teams, automation-first | Dev teams wanting a UI |
Monitoring Flux
# Check Flux health
flux check
# View all Flux resources
flux get all
# Check sync status
flux get kustomizations
flux get helmreleases
# View events
flux events
Best Practices
- Use bootstrap — don’t install Flux manually
- Separate infra and app repos — fleet-infra for platform, app repos for dev teams
- Enable prune — keep cluster state clean
- Use health checks — Flux marks sync as failed if deployments don’t become healthy
- Use image automation — eliminate manual image tag updates in Git
- Use multi-tenancy — scope team access with service accounts