CtrlK
BlogDocsLog inGet started
Tessl Logo

nitinjain999/platform-skills

Production-grade platform engineering handbook — Kubernetes, Terraform, Flux CD, GitHub Actions, AWS, and more.

67

Quality

84%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

fluxcd-kustomization.mdreferences/

FluxCD Kustomization Reference

The Flux Kustomization CRD (kustomize.toolkit.fluxcd.io/v1) is managed by kustomize-controller. It is Flux's primary mechanism for deploying manifests to a cluster.

This is distinct from Kustomize's kustomization.yaml config file — they share the name but are different resources.


Minimal example

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: apps
  namespace: flux-system
spec:
  interval: 10m
  prune: true
  sourceRef:
    kind: OCIRepository     # GitRepository | OCIRepository | Bucket | ExternalArtifact
    name: fleet-manifests
  path: ./apps
  wait: true
  timeout: 5m
  serviceAccountName: apps-reconciler    # for multi-tenant RBAC isolation

Core fields

FieldRequiredPurpose
sourceRef.kindYesGitRepository, OCIRepository, Bucket, ExternalArtifact
sourceRef.nameYesName of the source object
intervalYesHow often to reconcile
pruneYesDelete resources removed from source
pathNoSubdirectory within the artifact
targetNamespaceNoOverride namespace for all resources
waitNoBlock until resources are Ready (default: false)
timeoutNoFail fast if blocked (default: 5m)
forceNoRecreate resources that can't be patched
suspendNoPause reconciliation
deletionPolicyNoMirrorPrune (default), WaitForTermination
serviceAccountNameNoImpersonate this SA for RBAC isolation

Dependencies

Kustomizations wait until dependencies are Ready before reconciling:

spec:
  dependsOn:
    - name: infrastructure
      namespace: flux-system
    - name: cert-manager
      namespace: flux-system
      readyExpr: >
        status.conditions.filter(e, e.type == 'Ready').all(e, e.status == 'True')

readyExpr is a CEL expression with access to dep (the dependency object) and self (this Kustomization). Use status.observedGeneration >= 0 as a "reconciled-once" check for CRD-installing Kustomizations.


PostBuild variable substitution

${VAR} placeholders are replaced after kustomize build but before apply. Variables are sourced from inline substitute map or ConfigMaps/Secrets via substituteFrom.

spec:
  postBuild:
    substitute:
      CLUSTER_NAME: "production-eu"
      REPLICA_COUNT: "3"
    substituteFrom:
      - kind: ConfigMap
        name: flux-runtime-info    # label: reconcile.fluxcd.io/watch: Enabled
        optional: false
      - kind: Secret
        name: cluster-secrets
        optional: true

Rules:

  • Inline substitute values take precedence over substituteFrom
  • Escape a literal ${VAR} with $$$${VAR}
  • Only substitutes within this Kustomization's own path — add substituteFrom to the Kustomization that owns the manifest, not a sibling

SOPS decryption

spec:
  decryption:
    provider: sops
    secretRef:
      name: sops-age    # key: age.agekey

Without secretRef, Cloud KMS with workload identity is used (GCP, AWS, Azure).


Health checks

When wait: true, standard Kubernetes readiness conditions are evaluated. Custom CEL expressions override the built-in check:

spec:
  healthCheckExprs:
    - apiVersion: apps/v1
      kind: Deployment
      current: >
        object.status.conditions.filter(e, e.type == 'Available').all(e, e.status == 'True')
      inProgress: >
        object.status.conditions.filter(e, e.type == 'Progressing').exists(e, e.status == 'True')
      failed: >
        object.status.replicas > 0 && object.status.readyReplicas == 0

Remote cluster deployment

Secret-based (static kubeconfig):

spec:
  kubeConfig:
    secretRef:
      name: remote-cluster-kubeconfig
      key: value

Secretless (workload identity):

spec:
  kubeConfig:
    secretRef:
      name: remote-cluster-config
  # Secret contains provider fields: aws | azure | gcp | generic

When both kubeConfig and serviceAccountName are set, the controller impersonates the service account on the remote cluster.


Apply behaviour annotations

Flux uses server-side apply (SSA). Per-resource annotations tune field ownership:

AnnotationValueBehaviour
kustomize.toolkit.fluxcd.io/ssaOverrideFlux owns all fields; reverts external edits (default)
kustomize.toolkit.fluxcd.io/ssaMergePreserves non-overlapping fields from other tools (Terraform co-ownership)
kustomize.toolkit.fluxcd.io/ssaIfNotPresentOnly creates if absent — never updates
kustomize.toolkit.fluxcd.io/ssaIgnoreSkips this resource entirely
kustomize.toolkit.fluxcd.io/forceEnabledRecreates on immutable field changes
kustomize.toolkit.fluxcd.io/pruneDisabledProtects from garbage collection

Status and inventory

Managed resources are tracked in status.inventory using the format:

<namespace>_<name>_<group>_<kind>

This inventory powers prune: true — resources present in the inventory but absent from the current build are deleted.


Reconciliation triggers

# Force immediate reconciliation (fetches source first)
flux reconcile kustomization apps --with-source -n flux-system

# Annotate directly
kubectl annotate kustomization apps -n flux-system \
  reconcile.fluxcd.io/requestedAt="$(date -u +%Y-%m-%dT%H:%M:%SZ)" --overwrite

Validation

# Status overview
flux get kustomizations -A

# Detailed status with events
kubectl describe kustomization apps -n flux-system

# Logs for reconciliation errors
flux logs --kind=Kustomization --name=apps --namespace=flux-system

# List managed inventory
kubectl get kustomization apps -n flux-system -o jsonpath='{.status.inventory.entries[*]}' | tr ' ' '\n'

Retry interval

Configure retryInterval to recover faster from transient failures without waiting the full interval:

spec:
  interval: 30m
  retryInterval: 5m    # retry every 5m on failure instead of waiting 30m

Without retryInterval, a failed Kustomization waits the full spec.interval before the next attempt.


Common mistakes

MistakeCorrect approach
substituteFrom on a sibling KustomizationAdd substituteFrom to the Kustomization that owns the manifest
wait: false with dependsOnDependency checks are only meaningful when wait: true
prune: true without testingVerify status.inventory before enabling — garbage collection is immediate
Manual edit of a Flux-managed resourceFlux reverts on next reconciliation — add ssa: Merge annotation if co-ownership is needed
No retryInterval setFlux waits the full spec.interval between failure retries — set retryInterval: 5m

BEFORE_AFTER.md

CHANGELOG.md

CODE_OF_CONDUCT.md

COMMANDS.md

CONTRIBUTING.md

EDITOR_INTEGRATIONS.md

GETTING_STARTED.md

HOW_IT_WORKS.md

install.sh

INSTALLATION.md

LAUNCH.md

PROMPTS.md

QUICKSTART.md

README.md

renovate.json

SECURITY.md

SKILL.md

tessl.json

tile.json