Loading...
Loading...
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"
npx skill4agent add ionfury/homelab flux-gitopsinputsinputs:
- 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 chart:
name: "app-template"
version: "3.6.1"
url: "oci://ghcr.io/bjw-s/helm" # Prefix with oci://charts/<release-name>.yaml# yaml-language-server: $schema=<chart-schema-url>
---
# Helm values for the chart
replicas: 1
image:
repository: myapp
tag: v1.0.0configMapGeneratorconfigMapGenerator:
- name: platform-values
files:
# ... existing entries
- charts/my-new-chart.yamlconfig/config/my-new-chart/
├── kustomization.yaml
├── secret.yaml
└── config.yamlconfig.yamlnamespaces.yamlsecurity: restrictedbaselineprivilegedrestrictedrunAsUser: 65534restricted# 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: RuntimeDefaulttask k8s:validateresourcesTemplate<<>>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 >><< inputs.field >><<- if condition >>-<<- range $item := inputs.array >>hasPrefix "oci://" inputs.chart.urlinputs:
- name: "grafana"
dependsOn: [kube-prometheus-stack, alloy] # Waits for thesespec:
dependsOn:
- apiVersion: fluxcd.controlplane.io/v1
kind: ResourceSet
name: platform-namespaces # Waits for namespaces ResourceSetkubectl get resourcesets -n flux-system
kubectl describe resourceset platform-resources -n flux-systemkubectl get helmreleases -A
kubectl describe helmrelease <name> -n <namespace>kubectl logs -n flux-system deploy/flux-controller -f | grep <release-name>flux reconcile helmrelease <name> -n <namespace>
flux reconcile kustomization flux-system -n flux-system| Symptom | Cause | Solution |
|---|---|---|
| Dependency not ready | Check |
| Missing values file | Add to kustomization.yaml configMapGenerator |
| Wrong chart name/URL | Verify chart exists in repository |
| Namespace not created | Add to namespaces.yaml |
kubernetes/platform/versions.env${variable_name}helm-charts.yamlchart:
version: "${my_chart_version}" # Substituted from platform-versions ConfigMapchart:
name: "app-template" # Just the chart name
version: "3.6.1"
url: "oci://ghcr.io/bjw-s/helm" # Registry URL with oci:// prefixtype: oci