Skip to content

Commit 332db67

Browse files
authored
AI rule: aws.sagemaker.training_job.long_running (#151)
1 parent c47032a commit 332db67

12 files changed

Lines changed: 1430 additions & 14 deletions

File tree

README.fr.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ Pas encore de compte cloud ? `cleancloud demo` affiche un exemple de sortie sans
194194
- **Détection du gaspillage IA/ML sur les 3 clouds :** endpoints SageMaker et notebooks, clusters AML Compute et instances ML, endpoints Vertex AI et instances Workbench — facturés 500–23 000 $/mois par ressource en silence. Ressources GPU flaggées risque HIGH. Les outils natifs montrent la facture — CleanCloud indique quoi supprimer. Opt-in via `--category ai`
195195
- **Gouvernance policy-as-code :** `cleancloud.yaml` pour la configuration par règle, les exceptions avec dates d'expiration, les seuils de coût et de confiance, les exclusions par tag — versionné aux côtés de votre infrastructure. Chaque exception est une approbation auditée dans git.
196196
- **Application de politique (opt-in) :** `--fail-on-confidence HIGH` ou `--fail-on-cost 500` — appliquer des seuils de gaspillage en CI/CD sur un planning, géré par les équipes platform ou FinOps
197-
- **40 règles de détection sélectives et haut signal :** volumes orphelins, bases de données inactives, instances arrêtées, registres inutilisés, et plus — conçues pour éviter les faux positifs en environnements IaC, chacune avec une estimation de coût déterministe
197+
- **41 règles de détection sélectives et haut signal :** volumes orphelins, bases de données inactives, instances arrêtées, registres inutilisés, et plus — conçues pour éviter les faux positifs en environnements IaC, chacune avec une estimation de coût déterministe
198198
- **Scan multi-comptes (AWS) :** scannez des AWS Organizations entières en une exécution — fichier de config, IDs inline, ou auto-découverte via `--org`
199199
- **Scan multi-abonnements (Azure) :** scannez tous les abonnements Azure en parallèle — auto-découverte via Management Group, détail des coûts par abonnement inclus
200200
- **Scan multi-projets (GCP) :** scannez tous les projets GCP accessibles en parallèle — auto-découverte via Application Default Credentials, détail des coûts par projet inclus
@@ -275,6 +275,7 @@ L'infrastructure IA/ML inactive est la source de gaspillage cloud invisible à l
275275
| Endpoint SageMaker (GPU) | 500 – 23 000 $ / mois |
276276
| Instance Notebook SageMaker (GPU) | 500 – 23 000+ $ / mois |
277277
| Studio Apps SageMaker (KernelGateway/JupyterLab/CodeEditor) | 42 – 1 600+ $ / mois |
278+
| Training Job SageMaker (job GPU runaway/bloqué) | 670 – 2 360+ $ / jour |
278279
| Cluster AML Compute Azure (GPU) | 600 – 15 000 $ / mois |
279280
| Instance de calcul Azure ML (GPU) | 600 – 15 000+ $ / mois |
280281
| Déploiement Azure OpenAI Provisionné (PTU) | 1 460+ $ / PTU / mois |
@@ -284,7 +285,7 @@ L'infrastructure IA/ML inactive est la source de gaspillage cloud invisible à l
284285
CleanCloud détecte les endpoints à zéro invocation / zéro prédiction et les instances de notebook inactives sur les 3 clouds et les signale risque HIGH. Les outils natifs montrent la facture — ils ne vous disent pas *quel endpoint* supprimer.
285286

286287
```bash
287-
cleancloud scan --provider aws --category ai # PTUs Bedrock + endpoints + notebooks + Studio apps SageMaker + EC2 GPU
288+
cleancloud scan --provider aws --category ai # PTUs Bedrock + endpoints + notebooks + Studio apps + training jobs SageMaker + EC2 GPU
288289
cleancloud scan --provider azure --category ai # clusters AML + instances ML + PTUs OpenAI
289290
cleancloud scan --provider gcp --category ai # endpoints Vertex AI + Workbench
290291
cleancloud scan --provider aws --category all # hygiène + IA/ML ensemble
@@ -524,7 +525,7 @@ Oui. CleanCloud n'a besoin d'accès réseau qu'aux endpoints API de votre cloud
524525

525526
## Ce que CleanCloud détecte
526527

527-
40 règles pour AWS, Azure et GCP — conservatives, haut signal, conçues pour éviter les faux positifs en environnements IaC.
528+
41 règles pour AWS, Azure et GCP — conservatives, haut signal, conçues pour éviter les faux positifs en environnements IaC.
528529

529530
**AWS :**
530531
- Compute : instances arrêtées 30+ jours (charges EBS continuent)
@@ -533,7 +534,7 @@ Oui. CleanCloud n'a besoin d'accès réseau qu'aux endpoints API de votre cloud
533534
- Plateforme : instances RDS inactives (HIGH)
534535
- Observabilité : logs CloudWatch à rétention infinie
535536
- Gouvernance : ressources sans tags, security groups inutilisés
536-
- IA/ML *(opt-in : `--category ai`)* : Bedrock Provisioned Throughput (Model Units) inactifs avec zéro invocations depuis 7+ jours — facturés 600–7 300+$/MU/mois quel que soit le trafic ; endpoints SageMaker inactifs avec zéro invocations depuis 14+ jours — endpoints GPU flaggés risque HIGH ($500–$23K/mois) ; instances Notebook SageMaker sans activité depuis 14+ jours — notebooks GPU flaggés risque HIGH ($500–$23K+/mois) ; Studio Apps SageMaker (KernelGateway/JupyterLab/CodeEditor) sans activité utilisateur depuis 7+ jours — apps GPU flaggées risque HIGH ($42–$1 600+/mois)
537+
- IA/ML *(opt-in : `--category ai`)* : Bedrock Provisioned Throughput (Model Units) inactifs avec zéro invocations depuis 7+ jours — facturés 600–7 300+$/MU/mois quel que soit le trafic ; endpoints SageMaker inactifs avec zéro invocations depuis 14+ jours — endpoints GPU flaggés risque HIGH ($500–$23K/mois) ; instances Notebook SageMaker sans activité depuis 14+ jours — notebooks GPU flaggés risque HIGH ($500–$23K+/mois) ; Studio Apps SageMaker (KernelGateway/JupyterLab/CodeEditor) sans activité utilisateur depuis 7+ jours — apps GPU flaggées risque HIGH ($42–$1 600+/mois) ; training jobs SageMaker dépassant 24h — alerte précoce GPU à 75% du seuil, risque CRITICAL pour les jobs GPU ayant dépassé leur condition d'arrêt (670–2 360+$/jour pour instances p3/p4d/p5)
537538

538539
**Azure :**
539540
- Compute : VMs arrêtées (non désallouées) (HIGH)
@@ -558,7 +559,7 @@ Les règles sans marqueur de confiance sont MEDIUM — elles utilisent des heuri
558559

559560
## Feuille de route
560561

561-
**Plus de règles IA/ML**SageMaker Training Jobs (runaway/bloqués), artefacts d'entraînement orphelins dans S3
562+
**Plus de règles IA/ML** — artefacts d'entraînement orphelins dans S3
562563

563564
**Plus de règles AWS** — lacunes de cycle de vie S3, Redshift inactif, fuite de coût NAT Gateway, VPC endpoints inutilisés
564565

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ Idle AI/ML infrastructure is the fastest-growing source of invisible cloud spend
275275
| SageMaker endpoint (GPU) | $500 – $23,000 / month |
276276
| SageMaker Notebook Instance (GPU) | $500 – $23,000+ / month |
277277
| SageMaker Studio Apps (KernelGateway/JupyterLab/CodeEditor) | $42 – $1,600+ / month |
278+
| SageMaker Training Job (runaway/hung GPU job) | $670 – $2,360+ / day |
278279
| Azure AML compute cluster (GPU) | $600 – $15,000 / month |
279280
| Azure ML Compute Instance (GPU) | $600 – $15,000+ / month |
280281
| Azure OpenAI Provisioned Deployment (PTU) | $1,460+ / PTU / month |
@@ -284,7 +285,7 @@ Idle AI/ML infrastructure is the fastest-growing source of invisible cloud spend
284285
CleanCloud detects zero-invocation / zero-prediction endpoints and idle notebook instances across all three clouds and flags them HIGH risk. Native cost tools show the bill — they don't tell you *which endpoint* to delete.
285286

286287
```bash
287-
cleancloud scan --provider aws --category ai # Bedrock PTUs + SageMaker endpoints + notebooks + Studio apps + idle GPU EC2
288+
cleancloud scan --provider aws --category ai # Bedrock PTUs + SageMaker endpoints + notebooks + Studio apps + training jobs + idle GPU EC2
288289
cleancloud scan --provider azure --category ai # AML compute clusters + ML instances + OpenAI PTUs
289290
cleancloud scan --provider gcp --category ai # Vertex AI endpoints + Workbench
290291
cleancloud scan --provider aws --category all # hygiene + AI/ML together
@@ -524,7 +525,7 @@ Yes. CleanCloud only needs network access to your cloud provider's API endpoints
524525

525526
## What CleanCloud Detects
526527

527-
40 rules across AWS, Azure, and GCP — conservative, high-signal, designed to avoid false positives in IaC environments.
528+
41 rules across AWS, Azure, and GCP — conservative, high-signal, designed to avoid false positives in IaC environments.
528529

529530
**AWS:**
530531
- Compute: stopped instances 30+ days (EBS charges continue)
@@ -533,7 +534,7 @@ Yes. CleanCloud only needs network access to your cloud provider's API endpoints
533534
- Platform: idle RDS instances (HIGH)
534535
- Observability: infinite retention CloudWatch Logs
535536
- Governance: untagged resources, unused security groups
536-
- AI/ML *(opt-in: `--category ai`)*: idle Bedrock Provisioned Throughput (Model Units) with zero invocations 7+ days — bills $600–$7,300+/MU/month regardless of traffic; idle SageMaker endpoints with zero invocations 14+ days — GPU-backed endpoints flagged HIGH risk ($500–$23K/month); idle Notebook Instances with no activity 14+ days — GPU-backed notebooks flagged HIGH risk ($500–$23K+/month); idle Studio Apps (KernelGateway/JupyterLab/CodeEditor) with no user activity 7+ days — GPU-backed apps flagged HIGH risk ($42–$1,600+/month)
537+
- AI/ML *(opt-in: `--category ai`)*: idle Bedrock Provisioned Throughput (Model Units) with zero invocations 7+ days — bills $600–$7,300+/MU/month regardless of traffic; idle SageMaker endpoints with zero invocations 14+ days — GPU-backed endpoints flagged HIGH risk ($500–$23K/month); idle Notebook Instances with no activity 14+ days — GPU-backed notebooks flagged HIGH risk ($500–$23K+/month); idle Studio Apps (KernelGateway/JupyterLab/CodeEditor) with no user activity 7+ days — GPU-backed apps flagged HIGH risk ($42–$1,600+/month); long-running SageMaker training jobs beyond 24h threshold — GPU early warning at 75% of threshold, CRITICAL risk for GPU jobs that have outlived their stopping condition ($670–$2,360+/day for p3/p4d/p5 instances)
537538

538539
**Azure:**
539540
- Compute: stopped (not deallocated) VMs (HIGH)
@@ -558,7 +559,7 @@ Rules without a confidence marker are MEDIUM — they use time-based heuristics
558559

559560
## Roadmap
560561

561-
**More AI/ML waste rules**SageMaker Training Jobs (runaway/hung), orphaned training artifacts in S3
562+
**More AI/ML waste rules** — orphaned training artifacts in S3
562563

563564
**More AWS rules** — S3 lifecycle gaps, Redshift idle, NAT Gateway cost leakage (internal services routing through NAT instead of VPC endpoints — S3, DynamoDB, ECR, SSM), unused VPC endpoints
564565

cleancloud/doctor/aws.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,39 @@ def run_aws_ai_doctor(profile: Optional[str], region: Optional[str] = None) -> N
737737
permissions_failed.append(("sagemaker:DescribeApp", str(e)))
738738
warn(f"sagemaker:DescribeApp - {e}")
739739

740+
# --- sagemaker:ListTrainingJobs + sagemaker:DescribeTrainingJob (aws.sagemaker.training_job.long_running) ---
741+
try:
742+
sagemaker.list_training_jobs(MaxResults=1, StatusEquals="InProgress")
743+
permissions_tested.append("sagemaker:ListTrainingJobs")
744+
success("sagemaker:ListTrainingJobs")
745+
except Exception as e:
746+
permissions_failed.append(("sagemaker:ListTrainingJobs", str(e)))
747+
warn(f"sagemaker:ListTrainingJobs - {e}")
748+
749+
try:
750+
_tj_paginator = sagemaker.get_paginator("list_training_jobs")
751+
_target_job = None
752+
for _tj_page in _tj_paginator.paginate(
753+
StatusEquals="InProgress", PaginationConfig={"PageSize": 20}
754+
):
755+
for _tj in _tj_page.get("TrainingJobSummaries", []):
756+
_target_job = _tj
757+
break
758+
if _target_job:
759+
break
760+
761+
if _target_job:
762+
sagemaker.describe_training_job(TrainingJobName=_target_job["TrainingJobName"])
763+
permissions_tested.append("sagemaker:DescribeTrainingJob")
764+
success("sagemaker:DescribeTrainingJob")
765+
else:
766+
info(
767+
"sagemaker:DescribeTrainingJob - not tested (no InProgress training job found to probe)"
768+
)
769+
except Exception as e:
770+
permissions_failed.append(("sagemaker:DescribeTrainingJob", str(e)))
771+
warn(f"sagemaker:DescribeTrainingJob - {e}")
772+
740773
try:
741774
cloudwatch = session.client("cloudwatch", region_name=region)
742775
now = datetime.now(timezone.utc)

0 commit comments

Comments
 (0)