PD-36 — Annexe : CloudHSM On-Demand CI/CD¶
Objectif : Stratégie on-demand pour CloudHSM DEV afin de réduire les coûts de ~78%.
Date : 2025-11-26 — 2025-11-27 Statut : Terminé
Vue d'ensemble¶
Problématique¶
- CloudHSM facturé à l'heure (~$0.37/h = ~$266/mois 24/7)
- Environnement DEV utilisé uniquement 8h/jour (lun-ven)
- Gaspillage estimé : ~$200/mois
Solution¶
- Keep-alive 30min via Redis
- Lambda AWS de suppression auto si inactif >30min
- Recréation HSM automatique au besoin (CI/CD)
Économie : ~$207/mois (-78% sur CloudHSM DEV)
Architecture¶
┌────────────────────────────────────────────────────────────────┐
│ GitLab CI/CD Pipeline (Backend DEV) │
├────────────────────────────────────────────────────────────────┤
│ │
│ .pre : check-hsm-status.sh │
│ ├─ Vérifier si HSM exists │
│ └─ Créer si absent (create-hsm.sh) [10-15min] │
│ │
│ before_script : .cloudhsm_keepalive │
│ └─ keepalive-hsm.sh touch │
│ └─ Redis SET "hsm:dev:last_access" = timestamp │
│ │
│ [stages: test, build, deploy...] │
│ ↓ │
│ Jobs avec extends: .cloudhsm_keepalive │
│ ├─ test:integration │
│ ├─ migrate:dev │
│ └─ deploy:dev │
│ │
│ .post : hsm-keepalive │
│ └─ keepalive-hsm.sh touch (final) │
│ │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ Redis (VPS OVH DEV) │
├────────────────────────────────────────────────────────────────┤
│ Key : "hsm:dev:last_access" │
│ Value : 1732788000 (timestamp unix) │
│ TTL : 7200s (2h) │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ AWS Lambda HSM Monitor │
├────────────────────────────────────────────────────────────────┤
│ Trigger : EventBridge (rate: 10min) │
│ Runtime : Python 3.11 │
│ Layer : redis==5.0.1 │
│ │
│ Logic : │
│ 1. GET Redis "hsm:dev:last_access" │
│ 2. Calculate idle_time = now - last_access │
│ 3. IF idle_time > 1800s (30min): │
│ → aws cloudhsmv2 delete-hsm │
│ → Économie: ~$0.37/h │
│ 4. ELSE: │
│ → Continue monitoring │
│ │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ AWS CloudHSM DEV │
├────────────────────────────────────────────────────────────────┤
│ State : ACTIVE → Facturé $0.37/h │
│ State : DELETED → Facturé $0 │
│ │
│ Recréation : create-hsm.sh (10-15min) via CI/CD │
└────────────────────────────────────────────────────────────────┘
Scripts HSM Lifecycle¶
| Script | Description | Usage |
|---|---|---|
check-hsm-status.sh | Vérifier état CloudHSM | CI/CD .pre stage |
create-hsm.sh | Créer HSM DEV (on-demand) | CI/CD / Manuel |
delete-hsm.sh | Supprimer HSM DEV | Lambda / Manuel |
keepalive-hsm.sh | Keep-alive Redis (30min) | CI/CD before_script |
Emplacement : ProbatioVault-infra/scripts/ci/hsm/
check-hsm-status.sh¶
./check-hsm-status.sh dev
# Exit 0 : HSM ACTIVE
# Exit 1 : Aucun HSM (à créer)
# Exit 2 : HSM provisioning en cours
create-hsm.sh¶
./create-hsm.sh dev
# Durée : 10-15 minutes (provisioning AWS)
# Coût : ~$0.37/h (~$266/mois si 24/7)
delete-hsm.sh¶
./delete-hsm.sh dev
# ⚠️ ATTENTION : Suppression irréversible
# Clés cryptographiques perdues si non backupées
keepalive-hsm.sh¶
# Enregistrer activité (CI/CD)
./keepalive-hsm.sh touch
# Vérifier inactivité (Lambda)
./keepalive-hsm.sh check
# ACTIVE : <30min inactivité
# INACTIVE : >30min inactivité → Éligible suppression
Flux opérationnels¶
Scénario 1 : Build CI/CD (HSM déjà actif)¶
1. GitLab Pipeline triggered (push branch dev)
↓
2. .pre stage : check-hsm-status.sh → HSM ACTIVE ✅
↓
3. before_script : keepalive-hsm.sh touch
↓
4. [test, build, deploy stages...]
↓
5. .post stage : keepalive-hsm.sh touch
↓
✅ Build terminé, HSM reste actif (keep-alive 30min)
Durée : ~10-20min | Coût : ~$0.12
Scénario 2 : Build CI/CD (HSM absent)¶
1. GitLab Pipeline triggered
↓
2. .pre stage : check-hsm-status.sh → HSM absent ❌
↓
3. create-hsm.sh → Attente ACTIVE (10-15min)
↓
4. [test, build, deploy stages...]
↓
✅ Build terminé, HSM actif
Durée : ~20-35min | Coût : ~$0.21
Scénario 3 : Inactivité >30min (suppression auto)¶
1. Lambda HSM Monitor triggered (EventBridge 10min)
↓
2. GET Redis "hsm:dev:last_access" → 35min ago
↓
3. idle_time > 1800s → delete-hsm
↓
✅ HSM supprimé, économie: ~$0.37/h
Analyse coûts¶
Avant/Après on-demand¶
| Environnement | Stratégie | Heures/mois | Coût/mois | Économie |
|---|---|---|---|---|
| DEV (avant) | 24/7 | 730 | $270 | — |
| DEV (après) | On-demand 8h/j | 160 | $59 | -78% |
| TEST | 24/7 | 730 | $270 | — |
| PROD | 24/7 HA | 730 | $540 | — |
Coûts additionnels on-demand¶
| Ressource | Coût/mois |
|---|---|
| Lambda HSM Monitor (144 exec/jour) | $0.00 (free tier) |
| CloudWatch Logs (7j retention) | $0.50 |
| EventBridge Rule (10min) | $0.00 |
| Total | $0.50 |
Économie nette : ~$210/mois
Déploiement¶
1. Terraform Lambda HSM Monitor¶
Resources créées :
- Lambda Function (Python 3.11)
- Lambda Layer (redis package)
- IAM Role (permissions minimales)
- EventBridge Rule (trigger 10min)
- CloudWatch Logs (retention 7j)
2. Variables GitLab CI/CD¶
Configurer dans GitLab > Settings > CI/CD > Variables :
| Variable | Valeur | Protected | Masked |
|---|---|---|---|
AWS_ACCESS_KEY_ID | (IAM key) | ✅ | ✅ |
AWS_SECRET_ACCESS_KEY | (IAM secret) | ✅ | ✅ |
AWS_DEFAULT_REGION | eu-west-3 | ✅ | ❌ |
REDIS_HOST | vps-dev.probatiovault.com | ✅ | ❌ |
REDIS_PORT | 6379 | ✅ | ❌ |
REDIS_PASSWORD | (secret) | ✅ | ✅ |
3. Intégration Pipeline Backend¶
# ProbatioVault-backend/.gitlab-ci.yml
include:
- local: '../ProbatioVault-infra/scripts/ci/hsm/.gitlab-ci-hsm.yml'
test:integration:
extends: .cloudhsm_keepalive # Active keep-alive
stage: test
script:
- npm run test:integration
Sécurité¶
IAM Permissions¶
Lambda IAM Role (Least Privilege) :
Pas de permissions : CreateHsm, InitializeCluster, iam:*
Backup clés HSM¶
CRITIQUE : HSM supprimé = clés perdues (irréversible)
Stratégie recommandée :
- Export PKCS#11 avant delete
- Stockage AWS Secrets Manager (chiffré KMS)
- Restore après recréation HSM
Monitoring¶
CloudWatch Logs Lambda¶
Redis Keep-Alive¶
Livrables Phase 3¶
| Catégorie | Fichiers | LOC |
|---|---|---|
| Scripts HSM | 4 fichiers (.sh) | 333 |
| Lambda AWS | 5 fichiers (Terraform + Python) | 503 |
| GitLab CI/CD | 3 fichiers (.yml + .sh) | 838 |
| Total code | 12 fichiers | 1,674 |
Métriques opérationnelles¶
| Opération | Durée |
|---|---|
| Check HSM status | 5s |
| Create HSM | 10-15min |
| Delete HSM | 5-10min |
| Keep-alive touch | 1s |
| Lambda execution | 5s |
| Événement | Fréquence |
|---|---|
| Pipeline GitLab | ~10-20/jour |
| Lambda trigger | 144/jour (10min) |
| HSM delete (si inactif) | ~1/jour |
| HSM create (premier build) | ~1/jour |
Correctif appliqué¶
Correctif 1 : Lambda Layer redis package¶
Problème : import redis échoue dans Lambda (package manquant)
Solution :
- Création
requirements.txtavecredis==5.0.1 - Script
build-layer.shpour packager le layer - Modification Terraform pour attacher le layer à la Lambda
Version : 1.0 Statut : Terminé Économie : ~$207/mois (-78% CloudHSM DEV)