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-resourcesets.mdreferences/

FluxCD ResourceSet Reference

ResourceSet (fluxcd.controlplane.io/v1) generates Kubernetes resources from input value matrices using templates. It powers multi-tenant orchestration, fleet management, and self-service platform patterns that would otherwise require N copies of the same manifest.


Core concept

A ResourceSet takes one or more sets of inputs and renders a template block once per input entry. The result is a set of Kubernetes resources owned and reconciled by the Flux Operator.

apiVersion: fluxcd.controlplane.io/v1
kind: ResourceSet
metadata:
  name: tenant-apps
  namespace: flux-system
spec:
  inputsFrom:
    - kind: ResourceSetInputProvider
      name: tenant-list
  resources:
    - apiVersion: kustomize.toolkit.fluxcd.io/v1
      kind: Kustomization
      metadata:
        name: << inputs.tenant >>-apps
        namespace: flux-system
      spec:
        interval: 10m
        prune: true
        sourceRef:
          kind: OCIRepository
          name: << inputs.tenant >>-manifests
        path: ./apps
        serviceAccountName: << inputs.tenant >>

Template delimiters are << >> — not {{ }}.


Template functions

Templates use slim-sprig (Go sprig subset):

<< inputs.tenant >>                          # simple substitution
<< inputs.tag | default "latest" >>          # default value
<< inputs.config | toYaml | nindent 4 >>     # serialize nested object
<< if eq inputs.env "prod" >>3<< else >>1<< end >>  # conditional

Input strategies

StrategyBehaviour
Flatten (default)Concatenates all inputs into a flat list
PermuteCartesian product of all provider outputs

Under Permute, field names are namespaced under the normalized provider name. A provider named image-tag is accessed as inputs.image_tag.tag. Inline inputs on a ResourceSet named my-apps require inputs.my_apps.region, not inputs.region.

Always set filter.limit: 1 on OCIArtifactTag providers used with Permute — multiple exports per provider create a cross-product explosion (operator stalls at 10,000 permutations).


ResourceSetInputProvider types

apiVersion: fluxcd.controlplane.io/v1
kind: ResourceSetInputProvider
metadata:
  name: tenant-list
  namespace: flux-system
spec:
  type: Static           # Static | OCIArtifactTag | ECRArtifactTag | GitHubTag | GitHubPullRequest | GitLabTag | AzureContainerTag | ExternalService
  defaultValues:
    region: eu-west-1
TypeExported fieldsUse case
StaticFrom defaultValuesFixed config, shared cluster variables
OCIArtifactTagid, tag, digestGitless image automation
ECRArtifactTagid, tag, digestECR-native gitless automation
GitHubTagid, tag, shaFleet release tracking
GitHubPullRequestid, sha, branch, author, titlePreview environments per PR
GitLabTagid, tag, shaGitLab fleet release tracking
AzureContainerTagid, tag, digestACR gitless automation
ExternalServiceFrom HTTP JSON responseCustom registry / inventory API

Key spec fields:

FieldPurpose
typeProvider type (required)
urlRegistry or repo URL
secretRef.nameCredentials secret
filter.limitMax inputs returned (default: 100)
filter.semverSemver range to filter/sort tags
defaultValuesMerged defaults added to every exported entry
scheduleCron expression for reconciliation windows

Reconciliation interval is set via spec.interval on the ResourceSetInputProvider. The annotation form is also supported as an override:

spec:
  interval: 5m         # polling interval on the provider

# Optional override via annotation (takes precedence over spec.interval):
# annotations:
#   fluxcd.controlplane.io/reconcileEvery: "5m"

Dependencies

ResourceSets support CEL-based readiness expressions:

spec:
  dependsOn:
    - kind: Kustomization
      name: platform-rbac
      namespace: flux-system
      readyExpr: >
        status.conditions.filter(e, e.type == 'Ready').all(e, e.status == 'True')
    - kind: Kustomization
      name: cert-manager
      namespace: flux-system
      readyExpr: "status.observedGeneration >= 0"   # reconciled-once check

Advanced patterns

Conditional resource inclusion

resources:
  - apiVersion: v1
    kind: Namespace
    metadata:
      name: << inputs.tenant >>
      annotations:
        fluxcd.controlplane.io/reconcile: << if eq inputs.active "true" >>enabled<< else >>disabled<< end >>

When the annotation value is disabled, that resource is excluded for that input entry.

copyFrom

Copies ConfigMaps or Secrets from another namespace and keeps them in sync. Required for distributing shared config across tenant namespaces:

spec:
  resources:
    - apiVersion: v1
      kind: ConfigMap
      metadata:
        name: cluster-config
        namespace: << inputs.tenant >>
        annotations:
          fluxcd.controlplane.io/copyFrom: flux-system/cluster-config

For Secrets, the type field must also be set in the template.

Built-in input fields

FieldDescription
inputs._indexZero-based index of current input
inputs._idAdler-32 checksum of input values — stable unique ID
inputs.provider.kindResourceSet or ResourceSetInputProvider
inputs.provider.nameName of the providing object

Deduplication

When multiple inputs produce resources with identical GVK + namespace + name, the last input wins.


Common patterns

Gitless multi-tenant fleet

Chain of ResourceSets with dependsOn: policies → infra → apps. Each tenant gets a Namespace, OCIRepository, Kustomization, RBAC, and registry credentials — all from a single ResourceSet template.

Preview environments

A GitHubPullRequest provider with label filter feeds a ResourceSet that spins up per-PR namespaces and deployments. Cleaned up automatically when the PR closes.

Gitless image automation

OCIArtifactTag provider + Permute strategy pins HelmRelease resources to tag@digest without Git commits. Set limit: 1 per provider.

apiVersion: fluxcd.controlplane.io/v1
kind: ResourceSetInputProvider
metadata:
  name: app-image
  namespace: flux-system
  annotations:
    fluxcd.controlplane.io/reconcileEvery: "2m"
spec:
  type: OCIArtifactTag
  url: oci://ghcr.io/my-org/my-app
  secretRef:
    name: registry-auth
  filter:
    limit: 1
    semver: ">=1.0.0"
---
apiVersion: fluxcd.controlplane.io/v1
kind: ResourceSet
metadata:
  name: app-release
  namespace: flux-system
spec:
  inputsFrom:
    - kind: ResourceSetInputProvider
      name: app-image
  resources:
    - apiVersion: helm.toolkit.fluxcd.io/v2
      kind: HelmRelease
      metadata:
        name: my-app
        namespace: apps
      spec:
        interval: 10m
        chartRef:
          kind: OCIRepository
          name: my-app-chart
        values:
          image:
            tag: "<< inputs.tag >>@<< inputs.digest >>"

Validation

# List all ResourceSets
kubectl get resourceset -A

# Inspect inputs and generated resources
kubectl describe resourceset <name> -n flux-system

# List resources generated by a specific ResourceSet
kubectl get kustomization,helmrelease -l resourceset.fluxcd.io/name=<name> -A

# Force immediate reconciliation
kubectl annotate resourceset <name> -n flux-system \
  fluxcd.controlplane.io/requestedAt="$(date -u +%Y-%m-%dT%H:%M:%SZ)" --overwrite

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