| name | flux-gitops |
| description | Flux CD GitOps scaffolding: multi-environment repos, infrastructure components,
image automation, External Secrets integration, Kustomize overlays.
|
Flux GitOps Scaffold
Purpose
Scaffold and manage Flux CD GitOps repositories with:
- Multi-environment structure (dev/staging/prod)
- Infrastructure components (cert-manager, ingress-nginx, external-secrets)
- Application deployments with image automation
- External Secrets integration for secret management
Complementary to: helm-chart-developer skill (for Helm chart authoring).
This skill focuses on GitOps project structure and Flux-specific patterns.
When to Use
Activate for:
- Creating new GitOps repositories from scratch
- Adding infrastructure components to existing GitOps projects
- Setting up application deployments with image automation
- Configuring Flux Kustomization dependencies
- Multi-environment deployment patterns
Project Structure Pattern
gitops/
├── clusters/{env}/ # Flux orchestration layer
│ ├── kustomization.yaml # Aggregates all Flux Kustomizations
│ ├── 00-crds.yaml # CRDs (prune: false, wait: true)
│ ├── 01-controllers.yaml # dependsOn: crds
│ ├── 02-cluster-configs.yaml # dependsOn: controllers
│ ├── 03-services.yaml # dependsOn: cluster-configs
│ ├── 99-apps.yaml # dependsOn: services, cluster-configs
│ └── flux-system/
│
├── infra/
│ ├── base/
│ │ ├── cluster/
│ │ │ ├── controllers/ # cert-manager, ingress-nginx, ESO
│ │ │ └── configs/ # ClusterIssuer, ClusterSecretStore
│ │ └── services/ # redis, postgres (with configs/secrets)
│ ├── crds/ # Vendored CRDs (applied first)
│ │ ├── kustomization.yaml # Aggregates all CRD subdirs
│ │ ├── cert-manager/
│ │ └── external-secrets/
│ └── {env}/
│ ├── cluster/
│ │ ├── controllers/ # values only (ConfigMapGenerator)
│ │ └── configs/ # plain manifests
│ └── services/ # values + configs + secrets
│
├── apps/
│ ├── base/{app}/ # Base HelmRelease
│ └── {env}/{app}/ # values + configs + secrets
│ ├── configs/ # Plain ConfigMaps
│ └── secrets/ # ExternalSecrets
│
└── charts/app/ # Generic application chart
Structure Principle: Base + overlay with explicit layering. Controllers → Configs → Services → Apps.
See references/project-structure.md for detailed layout.
Core Workflows
1. Initialize GitOps Project
To create a new GitOps project:
-
Gather requirements via AskUserQuestion:
- Project name
- Environments (dev, staging, prod)
- Secrets provider (AWS/GCP/Azure/Vault)
- Cloud region/project
-
Create directory structure per references/project-structure.md
-
Generate cluster orchestration files (numbered Kustomizations)
-
Copy generic Helm chart from assets/charts/app/
-
Fetch latest component versions via Context7
2. Add Infrastructure Component
Three workflows depending on component type:
2a. Add Controller (cert-manager, ingress-nginx, ESO)
- FIRST: Get latest version via Context7 (see Version Management section)
- Vendor CRDs to
infra/crds/{component}/:
kustomization.yaml - Resources reference
crds.yaml - Vendored from upstream (curl from release)
- Create
infra/base/cluster/controllers/{component}/:
kustomization.yaml - Resources reference
helm.yaml - HelmRepository + HelmRelease (installCRDs: false)
- Create
infra/{env}/cluster/controllers/{component}/:
kustomization.yaml - refs base + ConfigMapGenerator
values.yaml - Environment values (installCRDs: false)
- Update
infra/crds/kustomization.yaml aggregator
- Update
infra/{env}/cluster/controllers/kustomization.yaml aggregator
2b. Add Cluster Config (ClusterIssuer, ClusterSecretStore)
- Create
infra/base/cluster/configs/{component}/:
kustomization.yaml - Resources reference
{component}.yaml - Plain manifest template
- Create
infra/{env}/cluster/configs/{component}/:
kustomization.yaml - refs base
{component}.yaml - Environment-specific manifest
- Update
infra/{env}/cluster/configs/kustomization.yaml aggregator
2c. Add Service (redis, postgres)
- FIRST: Get latest version via Context7 (see Version Management section)
- Create
infra/base/services/{component}/:
kustomization.yaml - Resources reference
helm.yaml - HelmRepository + HelmRelease
- Create
infra/{env}/services/{component}/:
kustomization.yaml - refs base + ConfigMapGenerator + configs + secrets
values.yaml - With envFrom injection
configs/{component}.config.yaml - Plain ConfigMap
secrets/{component}.external.yaml - ExternalSecret
- Update
infra/{env}/services/kustomization.yaml aggregator
Validation: Run kubectl kustomize infra/{env}/... to validate before commit.
See references/infra-components.md for supported components.
3. Add Application
To add application with image automation:
-
Gather via AskUserQuestion:
- Registry type (ECR/GCR/ACR/GHCR)
- Image repository URL
- Tag pattern (dev: run_id, prod: semver)
-
Create apps/base/{app}/:
kustomization.yaml - Resources reference
helm.yaml - HelmRelease referencing charts/app
-
Create apps/{env}/{app}/:
kustomization.yaml - refs base + ConfigMapGenerator + configs + secrets
values.yaml - With envFrom injection
patches.yaml - Image tag with automation marker
kustomizeconfig.yaml - ConfigMap name replacement
configs/{app}.config.yaml - Plain ConfigMap (non-sensitive)
secrets/{app}.external.yaml - ExternalSecret (sensitive)
-
Create image automation in apps/{env}/:
image-automation.yaml - ImageRepository + ImagePolicy + ImageUpdateAutomation
-
Update apps/{env}/kustomization.yaml aggregator
See references/image-automation.md for registry-specific patterns.
API Versions
Always use these API versions:
| Resource | API Version |
|---|
| HelmRelease | helm.toolkit.fluxcd.io/v2 |
| HelmRepository | source.toolkit.fluxcd.io/v1 |
| Kustomization (Flux) | kustomize.toolkit.fluxcd.io/v1 |
| GitRepository | source.toolkit.fluxcd.io/v1 |
| ImageRepository | image.toolkit.fluxcd.io/v1 |
| ImagePolicy | image.toolkit.fluxcd.io/v1 |
| ImageUpdateAutomation | image.toolkit.fluxcd.io/v1 |
| ExternalSecret | external-secrets.io/v1 |
| ClusterSecretStore | external-secrets.io/v1 |
CRITICAL: Never use deprecated versions (v2beta1, v2beta2). If found, propose migration.
Key Patterns
See references/key-patterns.md for detailed YAML patterns:
- HelmRelease with ConfigMap Values
- ConfigMap Generator (Kustomize overlay pattern)
- Flux Kustomization with Dependencies
- Image Automation Markers
- Configs & Secrets Pattern (ConfigMap, ExternalSecret, envFrom)
Orchestration
Five Flux Kustomizations with explicit dependsOn chain:
| File | DependsOn | Path | Critical Settings |
|---|
00-crds.yaml | - | ./infra/crds | prune: false, wait: true |
01-controllers.yaml | crds | ./infra/{env}/cluster/controllers | wait: true, timeout: 10m |
02-cluster-configs.yaml | controllers | ./infra/{env}/cluster/configs | wait: true, timeout: 5m |
03-services.yaml | cluster-configs | ./infra/{env}/services | wait: true, timeout: 10m |
99-apps.yaml | services, cluster-configs | ./apps/{env} | wait: true, timeout: 10m |
Why this order:
- CRDs must exist before controllers can install CRs
- Controllers must be running before configs (ClusterIssuer needs cert-manager)
- Cluster configs (ClusterSecretStore) needed before services can fetch secrets
- Services provide infrastructure for apps (redis, postgres)
Aggregator Pattern
Each directory Flux points to MUST have kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cert-manager
- ingress-nginx
- external-secrets
CRD Management
CRITICAL: Vendor CRDs into repository. Do NOT use nested Flux Kustomizations for CRDs.
curl -sL https://github.com/cert-manager/cert-manager/releases/download/{VERSION}/cert-manager.crds.yaml \
> infra/crds/cert-manager/crds.yaml
For HelmReleases with CRDs, disable CRD installation:
installCRDs: false
Version Management (MANDATORY)
CRITICAL: Never hardcode versions. Always use Context7 to get current versions.
Enforcement Layers
- SessionStart hook — Reminds about Context7 when k8s/Flux project detected
- PreToolUse hook — Checks versions in HelmRelease files:
- Empty version (
version: "") → Blocks and requires Context7
- Hardcoded version (
version: "1.2.3") → Asks for verification
- Documentation — No hardcoded versions provided (only Context7 workflow)
Workflow (REQUIRED for every HelmRelease)
Before creating ANY HelmRelease or vendoring CRDs:
# Step 1: Resolve library ID
Tool: resolve-library-id
Parameter: libraryName="{component}"
# Step 2: Query docs for version
Tool: query-docs
Parameters:
libraryId: "/{org}/{project}"
topic: "helm chart installation version"
# Step 3: Use version from documentation
Example: cert-manager
Tool: resolve-library-id
libraryName: "cert-manager"
# Returns: /jetstack/cert-manager
Tool: query-docs
libraryId: "/jetstack/cert-manager"
topic: "helm installation version"
# Extract version from documentation
Guardrails
NEVER:
- Copy versions from examples or documentation files
- Use versions from memory or previous sessions
- Hardcode versions without Context7 verification
ALWAYS:
- Fetch version via Context7 for EVERY new HelmRelease
- Verify version is current before deployment
- Use empty
version: "" as placeholder until Context7 fetched
See references/version-matrix.md for Context7 library IDs per component.
Validation
Before committing GitOps manifests, validate structure with kubectl kustomize:
kubectl kustomize infra/dev/cert-manager
kubectl kustomize apps/dev
kubectl kustomize clusters/dev
This catches:
- Missing files referenced in kustomization.yaml
- Invalid patches
- YAML syntax errors
- Invalid resource references
Definition of Done
Before completing GitOps scaffolding:
- Structure: All directories created per pattern
- Validation:
kubectl kustomize passes for all directories
- Dependencies:
dependsOn set correctly in Kustomizations
- Versions: Latest versions fetched via Context7
- API Versions: All using current stable APIs
- Values: ConfigMapGenerator with
disableNameSuffixHash: true
- Secrets: ExternalSecret configured (not hardcoded secrets)
- Image Automation: Markers set for automated updates
Anti-Patterns
| Avoid | Instead |
|---|
| Hardcoded secrets in values | ExternalSecret + secretRef |
prune: true for CRDs | prune: false to prevent deletion |
Missing dependsOn | Always set dependencies |
crds: CreateReplace | crds: Skip + vendored CRDs |
installCRDs: true in values | installCRDs: false (CRDs managed separately) |
| Nested Flux Kustomization for CRDs | Vendor CRDs into repo (race condition!) |
Missing wait: true | Always use wait: true + timeout |
| Missing aggregator kustomization.yaml | Every Flux path needs kustomization.yaml |
v2beta1/v2beta2 APIs | Use stable v2/v1 APIs |
| Hash suffix on ConfigMaps | disableNameSuffixHash: true |
{name}-{env} suffix | Skip suffix if env = namespace |
Examples
Trigger phrases:
- "Create a new GitOps repository for my microservices"
- "Add cert-manager to my Flux project"
- "Set up image automation for my app"
- "Configure multi-environment deployment"
- "Add ingress-nginx infrastructure"
- "Set up External Secrets with AWS"
Additional Resources
Reference Files
For detailed patterns, consult:
references/project-structure.md - Full directory layout
references/image-automation.md - Registry-specific automation
references/infra-components.md - Infrastructure patterns
references/version-matrix.md - Current versions + Context7 usage
Example Files
Working examples in examples/:
Orchestration:
orchestration-kustomizations.yaml - All 5 Flux Kustomizations with dependsOn chain
Controllers & Configs:
infra-base-helm.yaml - Base HelmRepo + HelmRelease for controller
cluster-controller-overlay.yaml - Controller overlay (values only)
cluster-config-overlay.yaml - Cluster config overlay (ClusterIssuer)
Services & Apps (with configs/secrets):
service-overlay-full.yaml - Service with configs/secrets
app-overlay-full.yaml - App with configs/secrets
config-configmap.yaml - Plain ConfigMap pattern
values-with-envfrom.yaml - values.yaml with envFrom injection
CRDs & Image Automation:
crds-kustomization.yaml - Vendored CRDs aggregator
image-automation-ecr.yaml - ECR automation
image-automation-ghcr.yaml - GHCR automation
external-secret.yaml - ESO pattern
Assets
Generic chart template in assets/charts/app/ - copy to target project.
Related Skills
helm-chart-developer - Helm chart authoring and ESO integration
conventional-commit - Commit message formatting