Skip to content

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 charts
  • cluster-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

  1. Preview Environments:
  2. ApplicationSet with Pull Request Generator
  3. Ephemeral namespaces per PR
  4. Automatic cleanup on PR close

  5. Promotion Pattern:

  6. Code merge → Build → Tag → Docker push
  7. Promotion PR to cluster-gitops updates image tag
  8. ArgoCD syncs on merge

  9. Version Pinning:

  10. Staging/Production always pin to git tags
  11. Preview environments may track PR branches
  12. Chart versions remain at 0.0.0 (stable)

Key Design Decisions

Chart Versioning:

  • Keep Chart.yaml version at 0.0.0 permanently
  • 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