Agent Skill
2/7/2026

flux-gitops

Flux GitOps patterns for the homelab Kubernetes platform using ResourceSets. Use when: (1) Adding new Helm releases or applications to the platform, (2) Deploying a new service to Kubernetes, (3) Debugging Flux reconciliation issues or sync problems, (4) Understanding ResourceSet patterns, (5) Configuring Kustomizations and variable substitution, (6) Questions about helm-charts.yaml or platform structure, (7) GitOps workflow questions. Triggers: "add helm release", "deploy to kubernetes", "add new service", "add application", "flux resourceset", "flux reconciliation", "flux not syncing", "flux stuck", "gitops", "helm-charts.yaml", "platform values", "flux debug", "HelmRelease not ready", "kustomization", "helmrelease", "add chart", "deploy helm chart"

I
ionfury
22GitHub Stars
1Views
npx skills add ionfury/homelab

SKILL.md

Nameflux-gitops
DescriptionFlux GitOps patterns for the homelab Kubernetes platform using ResourceSets. Use when: (1) Adding new Helm releases or applications to the platform, (2) Deploying a new service to Kubernetes, (3) Debugging Flux reconciliation issues or sync problems, (4) Understanding ResourceSet patterns, (5) Configuring Kustomizations and variable substitution, (6) Questions about helm-charts.yaml or platform structure, (7) GitOps workflow questions. Triggers: "add helm release", "deploy to kubernetes", "add new service", "add application", "flux resourceset", "flux reconciliation", "flux not syncing", "flux stuck", "gitops", "helm-charts.yaml", "platform values", "flux debug", "HelmRelease not ready", "kustomization", "helmrelease", "add chart", "deploy helm chart"

name: flux-gitops description: | Flux GitOps patterns for the homelab Kubernetes platform using ResourceSets.

Use when: (1) Adding new Helm releases or applications to the platform, (2) Deploying a new service to Kubernetes, (3) Debugging Flux reconciliation issues or sync problems, (4) Understanding ResourceSet patterns, (5) Configuring Kustomizations and variable substitution, (6) Questions about helm-charts.yaml or platform structure, (7) GitOps workflow questions.

Triggers: "add helm release", "deploy to kubernetes", "add new service", "add application", "flux resourceset", "flux reconciliation", "flux not syncing", "flux stuck", "gitops", "helm-charts.yaml", "platform values", "flux debug", "HelmRelease not ready", "kustomization", "helmrelease", "add chart", "deploy helm chart" user-invocable: false

Flux GitOps Platform

The homelab Kubernetes platform uses Flux ResourceSets for centralized, declarative management of Helm releases and configurations.

For ResourceSet patterns, version management, and platform architecture, see kubernetes/platform/CLAUDE.md.

How to Add a New Helm Release

Step 1: Add to helm-charts.yaml

Add an entry to the inputs array:

inputs:
  - name: "my-new-chart"           # Unique release name (kebab-case)
    namespace: "my-namespace"       # Target namespace
    chart:
      name: "actual-chart-name"    # Chart name in repository
      version: "1.0.0"             # Pinned version
      url: "https://example.com/charts"  # Helm repository URL
    dependsOn: [cilium]            # Array of release names this depends on

For OCI registries:

    chart:
      name: "app-template"
      version: "3.6.1"
      url: "oci://ghcr.io/bjw-s/helm"  # Prefix with oci://

Step 2: Create Values File

Create charts/<release-name>.yaml with Helm values:

# yaml-language-server: $schema=<chart-schema-url>
---
# Helm values for the chart
replicas: 1
image:
  repository: myapp
  tag: v1.0.0

Step 3: Add to kustomization.yaml

Add the values file to the configMapGenerator:

configMapGenerator:
  - name: platform-values
    files:
      # ... existing entries
      - charts/my-new-chart.yaml

Step 4: Add Config Resources (Optional)

If the chart needs additional resources (secrets, configs), add to config/:

config/my-new-chart/
├── kustomization.yaml
├── secret.yaml
└── config.yaml

Then reference in config.yaml ResourceSet.

Step 5: Verify PodSecurity Compliance

Before finalizing values, check the target namespace's PodSecurity level in namespaces.yaml:

  • Identify the namespace security level: Look for security: restricted, baseline, or privileged in the namespace inputs
  • If restricted: Add full security context to chart values (see below)
  • Check the container image's default user: If it runs as root, set runAsUser: 65534
  • Verify all init containers and sidecars also have security context set

Required security context for restricted namespaces:

# Pod-level (chart-specific key varies: podSecurityContext, securityContext, pod.securityContext)
podSecurityContext:
  runAsNonRoot: true
  seccompProfile:
    type: RuntimeDefault

# Container-level (every container)
securityContext:
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  seccompProfile:
    type: RuntimeDefault

Restricted namespaces: cert-manager, external-secrets, system, database, kromgo. See kubernetes/platform/CLAUDE.md for the full list.

Validation gap: task k8s:validate does NOT catch PodSecurity violations. These are only caught at admission time in the cluster.

ResourceSet Template Syntax

The resourcesTemplate uses Go text/template with << >> delimiters:

resourcesTemplate: |
  apiVersion: helm.toolkit.fluxcd.io/v2
  kind: HelmRelease
  metadata:
    name: << inputs.name >>
    namespace: << inputs.provider.namespace >>
  spec:
    <<- if inputs.dependsOn >>
    dependsOn:
    <<- range $dep := inputs.dependsOn >>
      - name: << $dep >>
    <<- end >>
    <<- end >>
    chart:
      spec:
        chart: << inputs.chart.name >>
        version: << inputs.chart.version >>

Template Functions

  • << inputs.field >> - Access input field
  • <<- if condition >> - Conditional (with - to trim whitespace)
  • <<- range $item := inputs.array >> - Loop over array
  • hasPrefix "oci://" inputs.chart.url - String prefix check

Dependency Management

Release Dependencies

inputs:
  - name: "grafana"
    dependsOn: [kube-prometheus-stack, alloy]  # Waits for these

ResourceSet Dependencies

spec:
  dependsOn:
    - apiVersion: fluxcd.controlplane.io/v1
      kind: ResourceSet
      name: platform-namespaces  # Waits for namespaces ResourceSet

Debugging Flux

Check ResourceSet Status

kubectl get resourcesets -n flux-system
kubectl describe resourceset platform-resources -n flux-system

Check HelmRelease Status

kubectl get helmreleases -A
kubectl describe helmrelease <name> -n <namespace>

Check Reconciliation Logs

kubectl logs -n flux-system deploy/flux-controller -f | grep <release-name>

Force Reconciliation

flux reconcile helmrelease <name> -n <namespace>
flux reconcile kustomization flux-system -n flux-system

Common Issues

SymptomCauseSolution
waiting for dependenciesDependency not readyCheck dependsOn releases
values key not foundMissing values fileAdd to kustomization.yaml configMapGenerator
chart not foundWrong chart name/URLVerify chart exists in repository
namespace not foundNamespace not createdAdd to namespaces.yaml

Version Management

When adding a new Helm release, you must also add a version entry to kubernetes/platform/versions.env with the correct Renovate annotation. Use ${variable_name} in helm-charts.yaml to reference the version:

chart:
  version: "${my_chart_version}"  # Substituted from platform-versions ConfigMap

For annotation syntax, datasource selection, and debugging Renovate, see the versions-renovate skill.

OCI Registry Specifics

When using OCI registries like GHCR:

chart:
  name: "app-template"           # Just the chart name
  version: "3.6.1"
  url: "oci://ghcr.io/bjw-s/helm"  # Registry URL with oci:// prefix

The ResourceSet template automatically detects OCI URLs and sets type: oci on the HelmRepository.

Skills Info
Original Name:flux-gitopsAuthor:ionfury