Skip to main content

Git as the source of truth


Table of Contents

  1. Single Source of Truth
  2. Desired state vs actual state
  3. Immutability and versioning
  4. Branching strategies
  5. Best practices
  6. Hands-on exercises

1 - Single Source of Truth

Definition

Single Source of Truth (SSOT) = A single source is authoritative for the desired state of the system.

Why Git?

CharacteristicBenefit for SSOT
VersionedComplete history
DistributedHigh availability
Merge/DiffCollaboration
SignaturesAuthenticity
BranchesEnvironments

What goes into Git

gitops-repo/
├── apps/
│ ├── frontend/
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── ingress.yaml
│ └── backend/
│ ├── deployment.yaml
│ └── service.yaml
├── infrastructure/
│ ├── monitoring/
│ │ ├── prometheus.yaml
│ │ └── grafana.yaml
│ └── ingress/
│ └── nginx-ingress.yaml
└── namespaces/
└── namespaces.yaml

🔝 Back to table of contents


2 - Desired state vs actual state

The two states

Drift detection

# État désiré (Git)
spec:
replicas: 3

# État réel (Cluster) - Quelqu'un a fait kubectl scale
spec:
replicas: 5

# L'agent GitOps détecte :
# Drift detected: replicas 5 != 3
# Action: Reconciling to desired state

Reconciliation

ModeBehavior
Auto-syncAutomatic drift correction
Manual syncNotification, manual action
Dry-runDisplays differences only
# ArgoCD - Configuration de sync
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
syncPolicy:
automated:
prune: true # Supprime les ressources non dans Git
selfHeal: true # Corrige le drift automatiquement

🔝 Back to table of contents


3 - Immutability and versioning

Git history

# Chaque changement est tracé
git log --oneline
a1b2c3d (HEAD -> main) Rollback to v1.9 - hotfix #567
d4e5f6g Deploy v2.0 - feature #234
g7h8i9j Scale backend to 5 replicas
j0k1l2m Add monitoring stack
m3n4o5p Initial infrastructure

# Qui, quand, quoi, pourquoi
git show a1b2c3d
Author: [email protected]
Date: Mon Dec 15 14:30:00 2024
Message: Rollback to v1.9 - hotfix #567

# Rollback = simple git revert
git revert a1b2c3d

Tags for releases

# Tagger les versions stables
git tag -a v1.0.0 -m "Production release v1.0.0"
git push origin v1.0.0

# Utiliser les tags dans ArgoCD
spec:
source:
targetRevision: v1.0.0 # ou HEAD, ou branch

Benefits of immutability

BenefitDescription
AuditProof of who did what
RollbackReturn to any version
ReproducibilitySame commit = same state
ComplianceTraceability for SOC2, ISO

🔝 Back to table of contents


4 - Branching strategies

Strategy 1: Branch per environment

main (production)
├── staging
└── develop

# Promotion : develop → staging → main
# Workflow
git checkout develop
# Faire les changements
git commit -m "New feature"
git push

# Promotion vers staging
git checkout staging
git merge develop
git push

# Promotion vers production
git checkout main
git merge staging
git push

Strategy 2: Single branch + directories

main/
├── environments/
│ ├── dev/
│ │ └── kustomization.yaml
│ ├── staging/
│ │ └── kustomization.yaml
│ └── prod/
│ └── kustomization.yaml
└── base/
└── deployment.yaml

Strategy 3: Single branch + overlays (Kustomize)

# base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 1 # Base

# overlays/prod/kustomization.yaml
resources:
- ../../base
patchesStrategicMerge:
- replicas-patch.yaml

# overlays/prod/replicas-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 5 # Override pour prod

Comparison

StrategyProsCons
Branch per envSimple, clearMerge conflicts
Directory per envNo mergeDuplication
Kustomize overlaysDRY, flexibleComplexity

🔝 Back to table of contents


5 - Best practices

Repository structure

gitops-repo/
├── README.md
├── apps/
│ ├── app1/
│ │ ├── base/
│ │ └── overlays/
│ │ ├── dev/
│ │ ├── staging/
│ │ └── prod/
│ └── app2/
├── infrastructure/
│ ├── cert-manager/
│ ├── ingress-nginx/
│ └── monitoring/
└── clusters/
├── dev-cluster/
├── staging-cluster/
└── prod-cluster/

Commit conventions

# Format
<type>(<scope>): <description>

# Exemples
feat(frontend): deploy v2.3.0
fix(backend): increase memory limit to 1Gi
chore(monitoring): update Prometheus to 2.45
docs(readme): add deployment instructions

# Avec référence au ticket
feat(api): add rate limiting - closes #123

Review process

# Toujours via Pull Request
1. Créer une branche
2. Faire les changements
3. Ouvrir une PR
4. Review par l'équipe
5. Tests automatiques (lint, validation)
6. Merge = déploiement

What does NOT go into Git

  • ❌ Plaintext secrets
  • ❌ Dynamic data (metrics, logs)
  • ❌ Database state
  • ❌ Generated configurations

🔝 Back to table of contents


6 - Hands-on exercises

Quiz

Q1. What does "drift" mean in GitOps?

Answer

Drift is the gap between the desired state (in Git) and the actual state (in the cluster). For example, if Git says replicas: 3 but the cluster has replicas: 5.

Q2. Why don't secrets go directly into Git?

Answer

Because Git keeps the complete history. Even if you delete a secret, it remains in the history. You must use solutions like Sealed Secrets, SOPS or Vault.

Exercise: Choose a strategy

Your team has 3 environments. Which branching strategy do you recommend?

Recommendation

To start, Directory per environment is the simplest:

main/
├── dev/
├── staging/
└── prod/

Once comfortable, migrate to Kustomize overlays to reduce duplication.

🔝 Back to table of contents


Key takeaways

  • SSOT = Git is the only source of truth
  • Desired state (Git) vs actual state (cluster)
  • Drift = gap between the two, corrected by reconciliation
  • Git history = complete audit trail
  • Several branching strategies are possible
  • Secrets must be encrypted

🔝 Back to table of contents


← Previous chapter | Next chapter: Architecture →