Cluster-Forge implements a sophisticated dual-repository GitOps deployment pattern that supports both external GitHub deployment and local cluster-native deployment through separate configuration and application repositories.
clusterForge:
repoUrl: "http://gitea-http.cf-gitea.svc:3000/cluster-org/cluster-forge.git"
targetRevision: # filled by bootstrap script --target-revision
externalValues:
enabled: true # Uses multi-source pattern
repoUrl: "http://gitea-http.cf-gitea.svc:3000/cluster-org/cluster-values.git"
targetRevision: main # always main for local cluster overridesPurpose: Self-contained cluster-native GitOps with local Gitea
Use Cases: Air-gapped environments, autonomous operation, production deployments
Network: Self-contained within cluster network
Features:
- Local Gitea serves both cluster-forge and cluster-values repositories
- Initialization handled by gitea-init-job during bootstrap
- Zero external dependencies once bootstrapped
- Full configuration version control within cluster
clusterForge:
repoUrl: "https://github.com/silogen/cluster-forge.git"
targetRevision: # filled by bootstrap script --target-revision (e.g., v1.8.0, feature-branch)
externalValues:
enabled: false # Single source from GitHubPurpose: Traditional GitOps with external GitHub dependency
Use Cases: Initial deployment, CI/CD pipelines, feature branch testing
Network: Requires external internet access
Features:
- Direct GitHub access for application deployment
- Supports custom branch selection for testing
Cluster-Forge uses YAML merge semantics for cluster size configuration:
# Bootstrap merges values using yq eval-all
yq eval-all '. as $item ireduce ({}; . * $item)' \
values.yaml values_medium.yaml- Base:
values.yaml(common applications and defaults) - Size Override:
values_small.yaml,values_medium.yaml, orvalues_large.yaml - External:
cluster-values/values.yamlfrom Gitea (when externalValues.enabled: true) - Runtime: Domain and cluster-specific parameters injected during bootstrap
Size files only contain differences from base (Don't Repeat Yourself):
Base values.yaml:
- Complete application definitions for all apps
- Alpha-sorted
enabledAppslist - Common defaults applicable to all sizes
Size-specific values:
- Only resource overrides that differ from base
- Size-specific enabledApps additions (e.g., storage policies)
- HA configurations for large clusters
Example:
# values_small.yaml - only differences
enabledApps:
- kyverno-policies-storage-local-path # Added to base list
apps:
argocd:
valuesObject:
controller:
resources:
limits:
cpu: 2000m # Override from base
memory: 4Gi| Cluster Size | Apps from Base | Additional Apps | Configuration Overrides |
|---|---|---|---|
| Small | All base apps | +1 (storage policy) | Minimal resources, single replicas |
| Medium | All base apps | +1 (storage policy) | Balanced resources, single replicas |
| Large | All base apps | +0 (no additions) | Production resources, OpenBao HA (3 replicas) |
The bootstrap script establishes the GitOps foundation:
Phase 1: Pre-Cleanup
- Removes previous installations when applicable
Phase 2: GitOps Foundation Bootstrap
- ArgoCD deployment (helm template)
- OpenBao deployment and initialization
- Gitea deployment and initialization
- Creates cluster-org organization
- Clones cluster-forge from initial-cf-values ConfigMap
- Creates cluster-values repository
Phase 3: App-of-Apps Deployment
- Creates cluster-forge Application in ArgoCD
- Uses multi-source when externalValues.enabled: true
- ArgoCD manages all remaining applications
When using local mode (externalValues.enabled: true), ArgoCD uses two separate repositories:
Source 1: Application Source (cluster-forge)
- Helm charts and manifests in
sources/directory - Application definitions in
root/chart - Component versions and configurations
Source 2: Configuration Source (cluster-values)
- Custom
values.yamlfor environment-specific overrides - Domain and cluster-specific settings
- Independent versioning from application code
This separation enables:
- Different update cadences for infrastructure vs. configuration
- Easy configuration rollback without affecting application versions
- Clear ownership separation
When ArgoCD renders applications with multi-source:
- Base values from
cluster-forge/root/values.yaml - Size-specific from
cluster-forge/root/values_<size>.yaml - External overrides from
cluster-values/values.yaml - Runtime parameters (domain, targetRevision) injected by bootstrap
# Clone local configuration repository from Gitea
git clone http://gitea.cluster.example.com/cluster-org/cluster-values.git
cd cluster-values
# Modify cluster configurations
vim values.yaml
git add values.yaml
git commit -m "Update cluster configuration"
git push
# ArgoCD automatically detects and syncs the changesExample: AIRM Image Repository Configuration
To configure custom AIRM image repositories post-bootstrap, modify cluster-values/values.yaml:
# Custom AIRM image repositories for private registry
airm-api:
airm:
backend:
image:
repository: harbor.mycompany.com/airm/airm-api
frontend:
image:
repository: harbor.mycompany.com/airm/airm-ui
airm-dispatcher:
airm:
dispatcher:
image:
repository: harbor.mycompany.com/airm/airm-dispatcherThis allows deployment from private registries, air-gapped environments, or custom built images.
Benefits of the dual-repository pattern:
- Full Git history: Track all cluster configuration changes
- Pull request workflow: Review configuration changes before deployment
- Automatic deployment: ArgoCD syncs on Git push
- Rollback capabilities: Revert via Git history
- Separation of concerns: Infrastructure code vs. environment configuration
- 🎯 Deployment Flexibility: Support for both external and local GitOps modes
- 🔄 Version Control: Full Git history for all cluster configuration changes
- 🛡️ Air-Gap Ready: Works in secure, isolated environments with local Gitea
- 👥 Developer Experience: Local Git access for cluster configuration management
- 📦 Multi-Source Pattern: Separate application code from configuration
- 🔧 Maintainability: DRY principle eliminates configuration redundancy
- 🚀 Bootstrap Automation: Single command establishes complete GitOps infrastructure
This architectural pattern enables clusters to operate with full GitOps benefits while maintaining flexibility for different deployment scenarios from development to air-gapped production environments.