Skip to content

Commit 84a79f7

Browse files
committed
feat: add ARCHITECTURE.md, POSTMORTEM, SECURITY.md, SLO, README
1 parent 0689e5e commit 84a79f7

4 files changed

Lines changed: 337 additions & 1 deletion

File tree

README.md

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,90 @@
1-
# cloud-platform
1+
# FleetOps Platform
2+
3+
Plateforme cloud-native de gestion de flotte deployee sur AWS.
4+
Projet de fin d etudes — Cloud/DevOps Engineering.
5+
6+
## Architecture
7+
8+
Internet → Load Balancer → EKS (FastAPI) → RDS PostgreSQL
9+
10+
- App : FastAPI + PostgreSQL + Alembic
11+
- Infra : AWS VPC + EKS + RDS via Terraform
12+
- CI/CD : GitHub Actions (lint, tests, security, build, deploy)
13+
- Observabilite : Prometheus + Grafana + 5 alertes + SLOs
14+
- Packaging : Helm chart avec values dev/prod
15+
16+
## Stack technique
17+
18+
| Composant | Technologie |
19+
|---|---|
20+
| API | FastAPI, Python 3.12 |
21+
| Base de donnees | PostgreSQL 16, SQLAlchemy, Alembic |
22+
| Conteneurisation | Docker multi-stage |
23+
| Infrastructure | Terraform, AWS (VPC, EKS, RDS, ECR, S3) |
24+
| Orchestration | Kubernetes, Helm |
25+
| CI/CD | GitHub Actions |
26+
| Monitoring | Prometheus, Grafana |
27+
| Securite | Bandit, pip-audit, Trivy, Gitleaks |
28+
29+
## Demarrage rapide
30+
31+
### Prerequis
32+
- Docker + Docker Compose
33+
- Python 3.12
34+
- Terraform >= 1.5
35+
- AWS CLI configure
36+
- kubectl + Helm
37+
38+
### Dev local
39+
40+
git clone https://github.com/imane-ait/cloud-platform.git
41+
cd cloud-platform
42+
cp .env.example .env
43+
docker compose up -d
44+
docker compose exec app alembic upgrade head
45+
curl http://localhost:8000/health
46+
curl http://localhost:8000/docs
47+
48+
### Acces aux interfaces
49+
50+
| Interface | URL | Credentials |
51+
|---|---|---|
52+
| API Swagger | http://localhost:8000/docs | - |
53+
| Prometheus | http://localhost:9090 | - |
54+
| Grafana | http://localhost:3000 | admin/admin |
55+
56+
### Lancer les tests
57+
58+
python -m pytest tests/ --cov=app --cov-report=term-missing
59+
60+
## Infrastructure AWS
61+
62+
cd infra
63+
terraform init
64+
terraform plan
65+
terraform apply
66+
67+
## CI/CD
68+
69+
Le pipeline GitHub Actions se declenche automatiquement a chaque push :
70+
71+
1. Lint — ruff, black
72+
2. Tests — pytest avec PostgreSQL
73+
3. Security — Bandit, pip-audit
74+
4. Build — image Docker poussee sur ECR
75+
5. Deploy — Helm sur EKS (sur merge main)
76+
77+
## Observabilite
78+
79+
- Metriques : /metrics expose les metriques Prometheus
80+
- Dashboards : Grafana sur port 3000
81+
- SLOs : disponibilite >= 99.5%, latence p95 < 300ms
82+
- Runbooks : docs/runbooks/
83+
84+
## Documentation
85+
86+
- docs/ARCHITECTURE.md — decisions d architecture (ADRs)
87+
- docs/SLO.md — definition des SLOs
88+
- docs/POSTMORTEM.md — postmortem incident DB
89+
- docs/runbooks/ — runbooks par alerte
90+
- docs/SECURITY.md — politique de securite

docs/ARCHITECTURE.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Architecture — FleetOps Platform
2+
3+
## Vue d'ensemble
4+
5+
FleetOps est une plateforme SaaS de gestion de flotte déployée sur AWS.
6+
L'architecture suit les principes cloud-native : conteneurisation, infrastructure as code, observabilité, et sécurité by design.
7+
8+
---
9+
10+
## Composants
11+
12+
### Application
13+
- **FastAPI** — API REST Python, async, avec endpoints CRUD
14+
- **PostgreSQL** — base de données relationnelle
15+
- **Alembic** — migrations de schéma versionnées
16+
17+
### Infrastructure
18+
- **AWS VPC** — réseau isolé avec subnets publics et privés sur 3 AZ
19+
- **AWS EKS** — Kubernetes managé pour orchestrer les conteneurs
20+
- **AWS RDS** — PostgreSQL managé avec sauvegardes automatiques
21+
- **AWS ECR** — registre d'images Docker privé
22+
23+
### CI/CD
24+
- **GitHub Actions** — pipeline automatique : lint, tests, security scan, build, deploy
25+
- **Helm** — packaging et déploiement sur Kubernetes
26+
27+
### Observabilité
28+
- **Prometheus** — collecte de métriques toutes les 15s
29+
- **Grafana** — dashboards et visualisation
30+
- **Alertes** — 5 règles avec runbooks associés
31+
- **SLOs** — disponibilité >= 99.5%, latence p95 < 300ms
32+
33+
---
34+
35+
## ADR — Architecture Decision Records
36+
37+
### ADR-001 — FastAPI plutôt que Flask
38+
39+
**Date :** 2026-05-01
40+
**Statut :** Accepté
41+
42+
**Contexte :** Choix du framework Python pour l'API.
43+
44+
**Décision :** FastAPI.
45+
46+
**Raisons :**
47+
- Support natif async — meilleure performance sous charge
48+
- Validation automatique via Pydantic
49+
- Documentation OpenAPI générée automatiquement
50+
- Ecosystem moderne, adopté par les équipes cloud-native
51+
52+
**Alternatives considérées :** Flask (synchrone, moins adapté), Django REST (trop lourd pour une API simple)
53+
54+
---
55+
56+
### ADR-002 — EKS plutôt que ECS
57+
58+
**Date :** 2026-05-15
59+
**Statut :** Accepté
60+
61+
**Contexte :** Choix de l'orchestrateur de conteneurs sur AWS.
62+
63+
**Décision :** EKS (Kubernetes managé).
64+
65+
**Raisons :**
66+
- Standard industrie — compétences transférables
67+
- Ecosystème riche (Helm, Prometheus, cert-manager)
68+
- HPA natif pour le scaling automatique
69+
- NetworkPolicies pour la sécurité réseau
70+
71+
**Alternatives considérées :** ECS (moins portable, vendor lock-in AWS), Fargate seul (moins de contrôle)
72+
73+
---
74+
75+
### ADR-003 — Terraform pour l'IaC
76+
77+
**Date :** 2026-05-15
78+
**Statut :** Accepté
79+
80+
**Contexte :** Choix de l'outil d'Infrastructure as Code.
81+
82+
**Décision :** Terraform avec modules.
83+
84+
**Raisons :**
85+
- Multi-cloud, pas de vendor lock-in
86+
- State management avec backend S3
87+
- Modules réutilisables (vpc, eks, rds)
88+
- Large communauté, nombreux providers
89+
90+
**Alternatives considérées :** AWS CDK (vendor lock-in), Pulumi (moins mature)
91+
92+
---
93+
94+
### ADR-004 — Alembic pour les migrations DB
95+
96+
**Date :** 2026-05-20
97+
**Statut :** Accepté
98+
99+
**Contexte :** Gestion des migrations de schéma PostgreSQL.
100+
101+
**Décision :** Alembic.
102+
103+
**Raisons :**
104+
- Intégration native avec SQLAlchemy
105+
- Migrations versionnées et réversibles
106+
- Autogenerate depuis les modèles SQLAlchemy
107+
- Pas de `create_all` en production
108+
109+
**Alternatives considérées :** Flyway (Java-centric), migrations manuelles (dangereux)
110+
111+
---
112+
113+
### ADR-005 — Prometheus + Grafana pour l'observabilité
114+
115+
**Date :** 2026-06-01
116+
**Statut :** Accepté
117+
118+
**Contexte :** Choix de la stack de monitoring.
119+
120+
**Décision :** Prometheus + Grafana.
121+
122+
**Raisons :**
123+
- Standard Kubernetes natif
124+
- Pull model — Prometheus scrape les métriques
125+
- Intégration avec kube-prometheus-stack
126+
- Grafana pour la visualisation et les alertes
127+
128+
**Alternatives considérées :** TIG Stack (push model, moins adapté Kubernetes), Datadog (coûteux)

docs/POSTMORTEM.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Postmortem — Panne DB FleetOps
2+
3+
**Date :** 2026-07-23
4+
**Durée :** ~2 minutes
5+
**Sévérité :** Critical
6+
**Statut :** Résolu
7+
8+
---
9+
10+
## Résumé
11+
12+
La base de données PostgreSQL a été arrêtée volontairement pour tester la résilience du système. L'API FleetOps a retourné des erreurs 500 sur tous les endpoints nécessitant la DB. L'endpoint `/health` continuait de répondre correctement. La restauration a été effectuée en moins de 2 minutes.
13+
14+
---
15+
16+
## Timeline
17+
18+
| Heure | Événement |
19+
|---|---|
20+
| 13:45:00 | DB arrêtée volontairement (`docker compose stop db`) |
21+
| 13:45:02 | `/vehicles/` retourne `500 Internal Server Error` |
22+
| 13:45:05 | `/ready` retourne une erreur de connexion |
23+
| 13:45:10 | Alerte `AppDown` se déclenche dans Prometheus |
24+
| 13:46:00 | DB redémarrée (`docker compose start db`) |
25+
| 13:46:05 | `/ready` retourne `{"status":"ready","db":"ok"}` |
26+
| 13:46:10 | `/vehicles/` retourne `[]` — service restauré |
27+
28+
---
29+
30+
## Impact
31+
32+
- **Utilisateurs affectés :** 100% — aucune requête CRUD ne fonctionnait
33+
- **Endpoints impactés :** `/vehicles/`, `/drivers/` (tous les endpoints DB)
34+
- **Endpoints non impactés :** `/health` (liveness probe OK)
35+
- **Durée d'indisponibilité :** ~1 minute
36+
37+
---
38+
39+
## Cause racine
40+
41+
Arrêt du conteneur PostgreSQL. Sans DB, SQLAlchemy ne peut pas exécuter les requêtes — toutes les opérations CRUD échouent avec une erreur 500.
42+
43+
---
44+
45+
## Ce qui a bien fonctionné
46+
47+
- `/health` a continué de répondre — Kubernetes n'aurait pas redémarré les pods
48+
- `/ready` a correctement signalé l'indisponibilité avec un 503
49+
- Prometheus a détecté l'anomalie via les métriques d'erreurs
50+
- La restauration a été rapide et sans perte de données
51+
52+
---
53+
54+
## Ce qui aurait pu être mieux
55+
56+
- `/ready` retournait une erreur DNS au lieu d'un 503 propre
57+
- Pas de retry automatique de connexion DB au redémarrage
58+
- Pas d'alerte Alertmanager configurée pour notifier l'équipe
59+
60+
---
61+
62+
## Actions correctives
63+
64+
| Action | Priorité | Responsable |
65+
|---|---|---|
66+
| Configurer Alertmanager pour les notifications | High | Équipe infra |
67+
| Ajouter retry de connexion DB dans l'app | Medium | Équipe dev |
68+
| Mettre en place RDS Multi-AZ en prod | High | Équipe infra |
69+
70+
---
71+
72+
## Leçons apprises
73+
74+
1. Le healthcheck `/health` vs `/ready` est essentiel — l'un vérifie l'app, l'autre vérifie les dépendances
75+
2. Une DB managée (RDS) avec Multi-AZ éviterait ce type d'incident en production
76+
3. Les runbooks permettent une résolution rapide même sous stress

docs/SECURITY.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Politique de Sécurité — FleetOps
2+
3+
## Signalement de vulnérabilités
4+
5+
Si vous découvrez une vulnérabilité de sécurité, merci de la signaler par email à l'équipe de sécurité. Ne pas ouvrir d'issue publique GitHub.
6+
7+
---
8+
9+
## Mesures de sécurité en place
10+
11+
### Application
12+
- Validation des données entrantes via Pydantic
13+
- Pas de credentials en clair dans le code
14+
- Secrets via variables d'environnement
15+
16+
### Conteneurisation
17+
- Image Docker multi-stage (surface d'attaque réduite)
18+
- Utilisateur non-root dans le conteneur
19+
- Scan d'image via Trivy dans la CI
20+
21+
### Infrastructure
22+
- Subnets privés pour RDS et EKS
23+
- Security Groups restrictifs
24+
- Secrets AWS via Secrets Manager
25+
- State Terraform chiffré sur S3
26+
27+
### CI/CD
28+
- Bandit — analyse statique du code Python
29+
- pip-audit — scan des dépendances
30+
- Gitleaks — détection de secrets dans le code
31+
- SBOM généré à chaque build
32+
33+
### Rotation des secrets
34+
- Les tokens GitHub sont rotés tous les 90 jours
35+
- Les credentials AWS sont rotés tous les 90 jours
36+
- Les mots de passe DB sont rotés tous les 6 mois
37+
38+
---
39+
40+
## Politique de branches
41+
- `main` est protégé — merge uniquement via PR
42+
- Reviews obligatoires avant merge
43+
- CI doit être verte avant merge

0 commit comments

Comments
 (0)