ADR-003: Cluster Architecture and GitOps Strategy¶
Status¶
Approved - Partially Implemented
Context¶
The SyRF monorepo requires a comprehensive deployment strategy that supports:
- Multiple microservices with independent versioning
- Environment promotion (preview → staging → production)
- GitOps principles with declarative configuration
- Minimal manual intervention
- Clear audit trail and rollback capabilities
Decision¶
Core Architecture¶
GitOps Model: Implement ArgoCD-based GitOps with separate repositories:
syrf-monorepo: Application code and Helm chartscluster-gitops: Environment configurations and ArgoCD manifests
Versioning Strategy:
- Use GitVersion 6.x in ContinuousDeployment mode
- Per-service semantic versioning with service-specific tag prefixes
- Git tags drive both Docker image tags and deployment versions
Container Registry: GitHub Container Registry (GHCR)
- Image format:
ghcr.io/camaradesuk/syrf-{service}:{version} - Tags:
{version},{version}-sha.{shortsha},latest
Repository Structures¶
Application Repository (syrf-monorepo)¶
src/
├── services/
│ ├── {service}/
│ │ ├── charts/{chart}/ # Helm chart (version 0.0.0)
│ │ ├── GitVersion.yml # Service versioning config
│ │ └── Dockerfile
└── libs/ # Shared libraries
GitOps Repository (cluster-gitops)¶
cluster-gitops/
├── apps/ # ArgoCD Application manifests (multi-source)
├── environments/
│ ├── staging/ # Staging values
│ ├── production/ # Production values
│ └── preview/ # PR preview values
└── docs/ # Deployment operations documentation
Note: Helm charts are in syrf-monorepo at src/services/{service}/charts/
Applications use multi-source pattern to reference charts from monorepo
Deployment Patterns¶
- Preview Environments:
- ApplicationSet with Pull Request Generator
- Ephemeral namespaces per PR
-
Automatic cleanup on PR close
-
Promotion Pattern:
- Code merge → Build → Tag → Docker push
- Promotion PR to cluster-gitops updates image tag
-
ArgoCD syncs on merge
-
Version Pinning:
- Staging/Production always pin to git tags
- Preview environments may track PR branches
- Chart versions remain at 0.0.0 (stable)
Key Design Decisions¶
Chart Versioning:
- Keep Chart.yaml version at
0.0.0permanently - Use git tags for version tracking (
{service}-v{version}) - Image tags drive deployments, not chart versions
Build Optimization:
- Detect code vs. non-code changes
- Retag existing images for non-code changes
- Fall back to full build if retag fails
Workflow Structure:
- Single integrated workflow: version → tag → build → push
- Avoids GitHub token triggering limitations
- Path-based change detection for selective builds
Consequences¶
Positive¶
- Clear separation: Code repo vs. configuration repo
- Audit trail: All deployments via git commits
- Fast rollback: Git revert = cluster rollback
- Independent scaling: Services version independently
- Preview validation: Test changes before staging
- Build efficiency: Smart retagging saves 2-5 min per build
Negative¶
- Complexity: Two repositories to manage
- Learning curve: Team needs GitOps understanding
- Cluster dependency: Full implementation blocked without Kubernetes
- Initial setup: Significant configuration required
Implementation Status¶
Completed¶
- ✅ Monorepo structure
- ✅ GitVersion configuration
- ✅ CI/CD workflow (auto-version.yml)
- ✅ Docker build implementation
- ✅ GHCR push configuration
- ✅ cluster-gitops repository created
- ✅ Helm charts created
- ✅ ArgoCD manifests prepared
Pending¶
- ⏳ ArgoCD installation (blocked by cluster)
- ⏳ ApplicationSet for PR previews
- ⏳ Promotion PR automation
- ⏳ Production cutover
Success Criteria¶
- Commit to staging < 10 minutes (p50)
- Preview environment ready < 2 minutes
- All changes via cluster-gitops PRs
- Zero untracked drift
- Rollback via git revert
Technical Details¶
Service Dependencies¶
See Dependency Map for complete service dependency matrix.
GitVersion Configuration¶
Each service uses:
mode: ContinuousDeployment
tag-prefix: '{service}-v'
major-version-bump-message: '^(feat|fix|chore)!:|BREAKING CHANGE:'
minor-version-bump-message: '^feat:'
patch-version-bump-message: '^fix:'
Path Filtering¶
Services rebuild when their dependencies change:
- Service code:
src/services/{service}/** - Shared libraries:
src/libs/**(selective based on dependencies) - Build files:
Directory.Build.props,nuget.config
Helm Library Charts¶
Shared templates via library chart pattern:
- Common labels, resources, security contexts
- Consumed via file:// dependency
- DRY principle for chart templates