Skip to content

Commit f287b41

Browse files
authored
AWS: Added multi-account scanning feature (#110)
1 parent 70c4311 commit f287b41

30 files changed

Lines changed: 2946 additions & 32 deletions

.github/workflows/main-validation.yml

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,48 @@ jobs:
8787
name: aws-integration-main
8888
path: test-results.json
8989

90+
integration-test-aws-multi-account:
91+
name: Integration Test - AWS Multi-Account (Required)
92+
runs-on: ubuntu-latest
93+
needs: validate
94+
environment: cleancloud-test
95+
96+
steps:
97+
- uses: actions/checkout@v4
98+
99+
- name: Set up Python
100+
uses: actions/setup-python@v5
101+
with:
102+
python-version: "3.11"
103+
104+
- name: Install CleanCloud
105+
run: |
106+
python -m pip install --upgrade pip
107+
pip install -e ".[dev]"
108+
109+
- name: Configure AWS credentials (OIDC)
110+
uses: aws-actions/configure-aws-credentials@v4
111+
with:
112+
role-to-assume: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/CleanCloudCIReadOnly
113+
aws-region: us-east-1
114+
115+
- name: Test multi-account scan
116+
run: |
117+
set -e
118+
cleancloud scan \
119+
--provider aws \
120+
--accounts ${{ vars.AWS_ACCOUNT_ID }},${{ vars.AWS_SPOKE_ACCOUNT_ID }} \
121+
--all-regions \
122+
--output json \
123+
--output-file multi-account-results.json
124+
125+
- name: Upload test results
126+
if: always()
127+
uses: actions/upload-artifact@v4
128+
with:
129+
name: aws-multi-account-main
130+
path: multi-account-results.json
131+
90132
integration-test-azure:
91133
name: Integration Test - Azure (Required)
92134
runs-on: ubuntu-latest
@@ -138,7 +180,7 @@ jobs:
138180
notify-failure:
139181
name: Create Issue on Failure
140182
runs-on: ubuntu-latest
141-
needs: [validate, integration-test-aws, integration-test-azure]
183+
needs: [validate, integration-test-aws, integration-test-aws-multi-account, integration-test-azure]
142184
if: failure()
143185

144186
steps:

.github/workflows/pr-checks.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,47 @@ jobs:
169169
name: aws-integration-test-results
170170
path: test-results.json
171171

172+
integration-test-aws-multi-account:
173+
name: Integration Test - AWS Multi-Account
174+
runs-on: ubuntu-latest
175+
continue-on-error: true
176+
environment: cleancloud-test
177+
178+
steps:
179+
- uses: actions/checkout@v4
180+
181+
- name: Set up Python
182+
uses: actions/setup-python@v5
183+
with:
184+
python-version: "3.11"
185+
186+
- name: Install CleanCloud
187+
run: |
188+
python -m pip install --upgrade pip
189+
pip install -e ".[dev]"
190+
191+
- name: Configure AWS credentials (OIDC)
192+
uses: aws-actions/configure-aws-credentials@v4
193+
with:
194+
role-to-assume: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/CleanCloudCIReadOnly
195+
aws-region: us-east-1
196+
197+
- name: Test multi-account scan
198+
run: |
199+
cleancloud scan \
200+
--provider aws \
201+
--accounts ${{ vars.AWS_ACCOUNT_ID }},${{ vars.AWS_SPOKE_ACCOUNT_ID }} \
202+
--all-regions \
203+
--output json \
204+
--output-file multi-account-results.json
205+
206+
- name: Upload test results
207+
if: always()
208+
uses: actions/upload-artifact@v4
209+
with:
210+
name: aws-multi-account-pr-results
211+
path: multi-account-results.json
212+
172213
integration-test-azure:
173214
name: Integration Test - Azure
174215
runs-on: ubuntu-latest

README.fr.md

Lines changed: 130 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,44 @@
22

33
![PyPI](https://img.shields.io/pypi/v/cleancloud)
44
![Python Versions](https://img.shields.io/pypi/pyversions/cleancloud)
5+
![Docker Pulls](https://img.shields.io/docker/pulls/getcleancloud/cleancloud)
56
![License](https://img.shields.io/badge/License-MIT-yellow.svg)
67
[![Security Scanning](https://github.com/cleancloud-io/cleancloud/actions/workflows/security-scan.yml/badge.svg)](https://github.com/cleancloud-io/cleancloud/actions/workflows/security-scan.yml)
78
![GitHub stars](https://img.shields.io/github/stars/cleancloud-io/cleancloud?style=social)
89

910
**Languages / Langues :**
1011
🇬🇧 [English](README.md) | 🇫🇷 [Français](README.fr.md)
1112

13+
**Docs:** [Configuration AWS](docs/aws.md) · [Permissions & Commandes AWS](docs/aws.md#at-a-glance) · [Multi-comptes AWS](docs/aws.md#multi-account-scanning) · [Configuration Azure](docs/azure.md) · [Guide CI/CD](docs/ci.md) · [Règles de détection](docs/rules.md) · [Exemples de sortie](docs/example-outputs.md) · [Docker Hub](https://hub.docker.com/r/getcleancloud/cleancloud) · [GitHub Action](https://github.com/marketplace/actions/cleancloud-scan)
14+
1215
---
1316

14-
**Trivy pour le gaspillage cloud. Un scanner qui détecte les ressources orphelines et applique l'hygiène en CI.**
17+
**Applique la politique d'hygiène cloud en CI et donne aux équipes engineering, finance et ops une vue unifiée du gaspillage.**
18+
19+
**Supporte :** AWS · Azure — GCP bientôt disponible
20+
21+
Hygiène cloud en lecture seule pour les environnements réglementés & souverains.
1522

16-
Comme `tfsec` pour Terraform ou `trivy` pour les conteneurs — CleanCloud scanne votre environnement cloud et rapporte ce qui gaspille de l'argent. Exécutez-le une fois pour un audit ponctuel, planifiez-le, ou intégrez-le en CI/CD pour bloquer les builds sur des violations de politique.
23+
CleanCloud scanne votre environnement cloud et rapporte ce qui gaspille de l'argent. Exécutez-le une fois pour un audit ponctuel, planifiez-le, ou intégrez-le en CI/CD pour bloquer les builds sur des violations de politique.
1724

1825
- **20 règles de détection haut signal :** volumes orphelins, bases de données inactives, load balancers vides, et plus
1926
- **Gaspillage mensuel estimé :** par finding et en agrégat
27+
- **Scan multi-comptes :** scannez des AWS Organizations entières en quelques minutes — fichier de config, IDs inline, ou auto-découverte via `--org`
2028
- **Application de politique CI/CD (opt-in) :** `--fail-on-confidence HIGH` ou `--fail-on-cost 100` gate votre pipeline
2129
- **Formats de sortie multiples :** lisible, JSON, CSV, et markdown (à coller dans vos PRs GitHub ou Slack)
2230
- **Lecture seule par conception :** aucune suppression, aucune modification de tags, aucune mutation — jamais
2331
- **Aucun agent. Zéro télémétrie. Pas de SaaS.** S'exécute dans votre environnement, les données ne quittent jamais votre périmètre
2432

33+
### Ce que CleanCloud ne fait PAS
34+
35+
| | |
36+
|---|---|
37+
| ❌ Supprimer des ressources | ❌ Modifier ou créer des tags |
38+
| ❌ Écrire dans une API cloud | ❌ Stocker ou journaliser des credentials |
39+
| ❌ Envoyer des données de télémétrie | ❌ Nécessiter un compte SaaS ou un agent |
40+
41+
Toutes les opérations sont en lecture seule. Sûr pour les comptes de production, environnements air-gapped, et pipelines soumis à revue de sécurité.
42+
2543
**Cas d'usage :**
2644
- Audit ponctuel de gaspillage cloud — exécutez dans CloudShell, findings visibles en 60 secondes
2745
- Analyses d'hygiène planifiées — cron ou CI hebdomadaire pour détecter la dérive
@@ -53,12 +71,60 @@ Régions scannées : us-east-1, us-west-2, eu-west-1
5371

5472
## Démarrage
5573

74+
### Commandes
75+
76+
| Commande | Fonction |
77+
|---|---|
78+
| `cleancloud demo` | Affiche des findings exemples — aucun credential requis |
79+
| `cleancloud scan` | Scanne votre environnement cloud et rapporte les findings |
80+
| `cleancloud doctor` | Vérifie que les credentials et permissions sont correctement configurés |
81+
| `cleancloud --version` | Affiche la version installée |
82+
| `cleancloud --help` | Liste tous les flags |
83+
84+
<details>
85+
<summary>Tous les flags de scan</summary>
86+
87+
```
88+
# Obligatoire
89+
--provider aws|azure Fournisseur cloud à scanner
90+
91+
# Région (optionnel)
92+
--region REGION Région unique
93+
--all-regions Scanne toutes les régions actives (recommandé)
94+
95+
# Multi-comptes — AWS uniquement (optionnel, choisir un)
96+
--multi-account FILE Fichier de config listant les comptes (ex. .cleancloud/accounts.yaml)
97+
--accounts 111,222 IDs de comptes inline, séparés par des virgules
98+
--org Auto-découverte via AWS Organizations
99+
--concurrency N Comptes en parallèle (défaut : 3)
100+
--timeout SECONDS Timeout total du scan en secondes (défaut : 3600)
101+
102+
# Sortie (optionnel)
103+
--output human|json|csv|markdown Format de sortie (défaut : human)
104+
--output-file FILE Écrit la sortie dans un fichier
105+
106+
# Application CI/CD (optionnel, tous retournent exit code 2)
107+
--fail-on-confidence HIGH Échec sur findings HIGH confidence
108+
--fail-on-confidence MEDIUM Échec sur findings MEDIUM ou supérieur
109+
--fail-on-cost N Échec si gaspillage mensuel estimé >= $N
110+
--fail-on-findings Échec si au moins un finding
111+
```
112+
113+
</details>
114+
115+
**Via pipx (recommandé pour usage local) :**
56116
```bash
57117
pipx install cleancloud
58118
pipx ensurepath # ajoute cleancloud au PATH — relancez votre shell après
59119
cleancloud demo # visualisez des findings sans aucun credential cloud
60120
```
61121

122+
**Via Docker (recommandé pour CI/CD — Python non requis) :**
123+
```bash
124+
docker pull getcleancloud/cleancloud
125+
docker run --rm getcleancloud/cleancloud demo
126+
```
127+
62128
Prêt à scanner votre vrai environnement ? Authentifiez-vous d'abord, puis lancez :
63129

64130
```bash
@@ -114,7 +180,7 @@ pip uninstall cleancloud && pipx install cleancloud && pipx ensurepath
114180

115181
**Mauvaise version après installation** — Exécutez `which cleancloud` ; un ancien `pip install` masque peut-être le pipx.
116182

117-
**Version minimale recommandée : v1.6.3** — les versions antérieures ont des problèmes de setup. Exécutez `cleancloud --version` pour vérifier.
183+
**Version minimale recommandée : v1.7.2** — les versions antérieures ont des problèmes de setup. Exécutez `cleancloud --version` pour vérifier.
118184

119185
</details>
120186

@@ -259,12 +325,72 @@ Workflows GitHub Actions complets et prêts à l'emploi pour AWS (OIDC) et Azure
259325

260326
---
261327

328+
## Scan Multi-Comptes (AWS uniquement)
329+
330+
Conçu pour les entreprises utilisant AWS Organizations. Scannez chaque compte en parallèle — les findings sont agrégés dans un seul rapport.
331+
332+
```bash
333+
# Scan depuis un fichier de configuration (commitez .cleancloud/accounts.yaml dans votre repo)
334+
cleancloud scan --provider aws --multi-account .cleancloud/accounts.yaml --all-regions
335+
336+
# IDs de comptes en ligne — sans fichier
337+
cleancloud scan --provider aws --accounts 111111111111,222222222222 --all-regions
338+
339+
# Auto-découverte de tous les comptes de votre AWS Organization
340+
cleancloud scan --provider aws --org --all-regions --concurrency 5
341+
```
342+
343+
**Permissions requises :**
344+
345+
| Rôle | Permissions |
346+
|---|---|
347+
| Compte hub | 16 permissions lecture seule + `sts:AssumeRole` sur les rôles spoke |
348+
| Compte hub (`--org` uniquement) | Ci-dessus + `organizations:ListAccounts` |
349+
| Comptes spoke | 16 permissions lecture seule (identique au scan mono-compte — aucun changement) |
350+
351+
**`.cleancloud/accounts.yaml`** — à commiter dans votre repo :
352+
353+
```yaml
354+
role_name: CleanCloudReadOnlyRole
355+
accounts:
356+
- id: "111111111111"
357+
name: production
358+
- id: "222222222222"
359+
name: staging
360+
```
361+
362+
**Trust policy du compte spoke** — autorise le hub à assumer le rôle :
363+
364+
```json
365+
{
366+
"Effect": "Allow",
367+
"Principal": { "AWS": "arn:aws:iam::<HUB_ACCOUNT_ID>:root" },
368+
"Action": "sts:AssumeRole"
369+
}
370+
```
371+
372+
Politique IAM complète, trust policy et templates IaC : [Configuration multi-comptes AWS →](docs/aws.md#multi-account-scanning)
373+
374+
**Comment ça fonctionne :**
375+
376+
- **Hub-and-spoke** — CleanCloud assume `CleanCloudReadOnlyRole` dans chaque compte cible via STS. Aucun accès persistant, aucun credential stocké.
377+
- **Trois modes de découverte**`.cleancloud/accounts.yaml` pour un contrôle explicite, `--accounts` pour des scans ad-hoc rapides, `--org` pour l'auto-découverte complète via AWS Organizations.
378+
- **Détection de régions efficace** — les régions actives sont découvertes une seule fois sur le compte hub et réutilisées sur tous les spokes. Sans ça : N comptes × 160 appels API rien que pour la détection de régions. Avec : 160 appels une fois.
379+
- **Parallèle avec isolation** — chaque compte s'exécute dans son propre thread avec sa propre session. Un compte en échec (AccessDenied, timeout) n'affecte jamais les autres.
380+
- **Visibilité partielle** — si 2 régions échouent et 7 réussissent dans un compte, le compte est marqué `partial` avec les régions en échec nommées. Vous voyez exactement ce qui a été manqué.
381+
- **Progression en temps réel**`[3/50] done production (123456789012) — 47s, 12 findings` affiché au fil des comptes.
382+
- **Détail des coûts par compte** — la sortie JSON inclut le gaspillage mensuel estimé par compte.
383+
384+
Guide complet (politique IAM, trust policy, templates IaC) : [Configuration multi-comptes AWS →](docs/aws.md#multi-account-scanning)
385+
386+
---
387+
262388
## Feuille de route
263389

264390
- Règles AWS supplémentaires (cycle de vie S3, instances EC2 arrêtées)
265391
- Policy-as-code dans `cleancloud.yaml` (`fail_on_confidence`, `fail_on_cost` en config)
266392
- Filtrage de règles (flag `--rules`)
267-
- Scan multi-comptes (AWS Organizations)
393+
- Scan Azure Management Groups (multi-abonnements au niveau org)
268394

269395
---
270396

0 commit comments

Comments
 (0)