GitOps best practices
Table of Contents
- Recommended patterns
- Anti-patterns to avoid
- Security
- Monitoring and alerting
- Documentation
- Hands-on exercises
1 - Recommended patterns
Separation of Concerns
gitops-repo/
├── apps/ # Équipe dev
├── infrastructure/ # Équipe platform
└── clusters/ # Équipe SRE
# Permissions RBAC par dossier
# apps/* → développeurs
# infrastructure/* → platform team
# clusters/* → SRE uniquement
Small, Frequent Commits
# ✅ Bon : Un changement par commit
git commit -m "feat(frontend): update to v2.3.0"
git commit -m "fix(backend): increase memory to 1Gi"
# ❌ Mauvais : Tout dans un commit
git commit -m "Update frontend, backend, monitoring, ingress..."
Pull Request Workflow
# Branch protection rules
- Require PR reviews (2 approvers)
- Require status checks (lint, validate)
- No force push
- No direct commits to main
GitOps Validation Pipeline
# .github/workflows/validate.yml
name: Validate GitOps
on:
pull_request:
paths:
- 'apps/**'
- 'infrastructure/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate YAML
run: |
find . -name '*.yaml' -exec yamllint {} \;
- name: Validate Kubernetes manifests
uses: instrumenta/kubeval-action@master
- name: Kustomize build
run: |
for dir in apps/*/overlays/*/; do
kustomize build $dir > /dev/null
done
Immutable Tags
# ✅ Bon : Tags immutables
image: myapp:v1.2.3
image: myapp:sha-abc123
# ❌ Mauvais : Tags mutables
image: myapp:latest
image: myapp:dev
🔝 Back to table of contents
2 - Anti-patterns to avoid
Direct kubectl Access
# ❌ JAMAIS en production
kubectl set image deployment/myapp myapp=myapp:v2
kubectl scale deployment/myapp --replicas=10
kubectl delete pod myapp-xxx
# ✅ Toujours via Git
git checkout -b hotfix/scale-myapp
# Modifier le fichier
git commit -m "fix: scale myapp to 10"
git push && créer PR
Plaintext secrets
# ❌ JAMAIS
apiVersion: v1
kind: Secret
data:
password: bXlwYXNzd29yZA== # base64 n'est PAS sécurisé
# ✅ Utiliser Sealed Secrets, SOPS, Vault
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
spec:
encryptedData:
password: AgBj7...chiffré...
Giant mono-repo
# ❌ Tout dans un seul repo
gitops-monorepo/
├── team-a/
├── team-b/
├── team-c/
├── ... 50 équipes ...
└── infrastructure/
# ✅ Séparer par domaine/équipe
org/gitops-platform
org/gitops-team-a
org/gitops-team-b
Lack of validation
# ❌ Pas de CI sur les manifests
# → Erreurs détectées en production
# ✅ Pipeline de validation
- yamllint
- kubeval / kubeconform
- kustomize build
- helm template
- Policy checks (OPA/Kyverno)
Constant manual sync
# ❌ Sync manuel = pas vraiment GitOps
syncPolicy: {} # Pas d'automated
# ✅ Auto-sync avec self-heal
syncPolicy:
automated:
prune: true
selfHeal: true
🔝 Back to table of contents
3 - Security
Principle of least privilege
# GitOps controller avec permissions limitées
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: gitops-controller
rules:
# Seulement ce qui est nécessaire
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
# PAS de delete sur certaines ressources
Audit and traceability
# Tout est dans Git
git log --oneline --since="2024-01-01"
# a1b2c3d deploy v2.0 - [email protected]
# d4e5f6g scale to 5 - [email protected]
# Git blame
git blame apps/myapp/deployment.yaml
Signed Commits
# Configurer GPG signing
git config --global commit.gpgsign true
git config --global user.signingkey YOUR_KEY_ID
# Vérifier les signatures
git log --show-signature
# ArgoCD - Exiger des commits signés
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
source:
repoURL: ...
syncPolicy:
automated: {}
# + GPG verification dans ArgoCD settings
Network Policies
# Limiter les connexions du controller
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: gitops-controller
spec:
podSelector:
matchLabels:
app: argocd-repo-server
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- port: 443
protocol: TCP
🔝 Back to table of contents
4 - Monitoring and alerting
GitOps metrics
| Metric | Description |
|---|---|
| Sync Status | Applications in-sync vs out-of-sync |
| Sync Duration | Reconciliation time |
| Drift Count | Number of drifts detected |
| Failed Syncs | Synchronization failures |
ArgoCD Metrics
# ServiceMonitor pour Prometheus
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: argocd-metrics
spec:
selector:
matchLabels:
app.kubernetes.io/name: argocd-server
endpoints:
- port: metrics
Alerting
# PrometheusRule
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: gitops-alerts
spec:
groups:
- name: gitops
rules:
- alert: AppOutOfSync
expr: argocd_app_info{sync_status="OutOfSync"} == 1
for: 5m
labels:
severity: warning
annotations:
summary: "Application {{ $labels.name }} is out of sync"
- alert: AppDegraded
expr: argocd_app_info{health_status="Degraded"} == 1
for: 5m
labels:
severity: critical
Notifications
# ArgoCD Notifications
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
data:
service.slack: |
token: $slack-token
template.app-sync-failed: |
message: |
Application {{.app.metadata.name}} sync failed.
Error: {{.app.status.operationState.message}}
trigger.on-sync-failed: |
- send: [app-sync-failed]
when: app.status.operationState.phase in ['Error', 'Failed']
🔝 Back to table of contents
5 - Documentation
README in each folder
# apps/myapp/README.md
## MyApp
Description de l'application.
### Environnements
| Env | Namespace | Replicas |
|-----|-----------|----------|
| Dev | dev | 1 |
| Prod | production | 5 |
### Déploiement
Pour déployer une nouvelle version :
1. Modifier `overlays/<env>/kustomization.yaml`
2. Créer une PR
3. Attendre la review
4. Merge = déploiement automatique
### Rollback
```bash
git revert HEAD
git push
### Architecture Decision Records (ADR)
```markdown
# docs/adr/001-gitops-tool-selection.md
# ADR 001: Choix de l'outil GitOps
## Status
Accepted
## Context
Nous devons choisir un outil GitOps pour gérer nos déploiements K8s.
## Decision
Nous utilisons ArgoCD car :
- UI native importante pour nos développeurs
- CNCF Graduated
- Grande communauté
## Consequences
- Formation nécessaire pour l'équipe
- Installation et maintenance du controller
Runbooks
# docs/runbooks/sync-failed.md
# Runbook: Application Sync Failed
## Symptôme
Alerte `AppSyncFailed` déclenchée
## Diagnostic
1. Vérifier l'état ArgoCD
```bash
argocd app get <app-name>
- Voir les logs
argocd app logs <app-name>
Résolution
- Si erreur de manifest : corriger dans Git
- Si erreur réseau : vérifier la connectivité
- Si ressource bloquée : voir les events K8s
#### [🔝 Back to table of contents](#table-des-matieres)
---
<a name="exercices"></a>
## 6 - Hands-on exercises
### Quiz
**Q1.** Why should you never use `kubectl` directly in production?
<details>
<summary>Answer</summary>
- No traceability (who did what?)
- Causes **drift** (cluster state ≠ Git)
- No review process
- Self-healing will revert the change
- Not reproducible
</details>
**Q2.** Why avoid `latest` tags?
<details>
<summary>Answer</summary>
- **Not reproducible**: `latest` changes over time
- **No rollback**: impossible to go back
- **Difficult audit**: which version is really running?
- Use **immutable** tags: `v1.2.3`, `sha-abc123`
</details>
### Exercise: GitOps checklist
Create a checklist to validate your GitOps setup:
<details>
<summary>Complete checklist</summary>
**Repository**
- README in each folder
- .gitignore configured
- Branch protection enabled
- Mandatory PR reviews
**CI/CD**
- YAML validation (yamllint)
- K8s validation (kubeval)
- Kustomize/Helm build test
- Policy checks
**Security**
- Encrypted secrets (Sealed Secrets/SOPS)
- No plaintext credentials
- RBAC configured
- Signed commits (optional)
**Monitoring**
- GitOps metrics exposed
- Alerts configured
- Slack/Teams notifications
**Documentation**
- ADR for decisions
- Runbooks for incidents
- Architecture diagrams
</details>
#### [🔝 Back to table of contents](#table-des-matieres)
---
## Key takeaways
- **Patterns**: Small commits, PR workflow, immutable tags
- **Anti-patterns**: direct kubectl, plaintext secrets, no validation
- **Security**: Least privilege, signed commits, audit trail
- **Monitoring**: Sync metrics, drift alerts
- **Documentation**: README, ADR, runbooks
#### [🔝 Back to table of contents](#table-des-matieres)
---
[← Previous chapter](./08-multi-environnements.md) | [Next chapter: Exercises →](./10-exercices-projets.md)