aws-radar
AWS resource inventory scanner + Cost Explorer reporter + draw.io architecture diagram generator.
Scans your AWS account(s) via SSO or IAM credentials and produces:
- A CSV inventory of every running resource
- A CSV of daily Cost Explorer spend by service (
--billing) - A
.drawiofile you can open in diagrams.net — with AWS icons, region containers, and service connections auto-wired
Supported services
Core — EC2 · RDS / Aurora · Lambda · ECS · EKS · ElastiCache · DynamoDB · S3 · OpenSearch · SQS · SNS · ALB / NLB
AI / ML (scanned by default) — Bedrock · SageMaker · Rekognition · Textract · Comprehend · Lex · Kendra · Transcribe · Polly · Translate · Forecast · Personalize
Installation
pip install aws-radar
Troubleshooting
ModuleNotFoundError: No module named 'boto3' (AWS CloudShell)
CloudShell ships its own system boto3, so a pip install --user aws-radar can skip
installing boto3 into your user site — leaving it unimportable at runtime. Install the
dependencies into the same user site:
python3 -m pip install --user boto3 rich
Or, cleanest, use an isolated virtual environment:
python3 -m venv ~/aws-radar-venv
~/aws-radar-venv/bin/pip install aws-radar
~/aws-radar-venv/bin/aws-radar run
Quick start
# One-shot: inventory + diagram
aws-radar run --profile my-sso-profile --all-regions --output architecture.drawio
# Or step by step:
aws-radar inventory --profile my-sso-profile --all-regions --export inventory.csv
aws-radar diagram --input inventory.csv --output architecture.drawio
# Daily cost by service for the last 90 days
aws-radar billing --profile my-sso-profile --output billing.csv
Then open architecture.drawio at app.diagrams.net.
Command-line options
The inventory command accepts the following options:
| Option | Description |
|---|---|
--region REGION |
AWS region (default: boto3 default) |
--profile PROFILE |
AWS SSO/named profile |
--all-regions |
Scan all enabled regions |
--ai |
Scan AI/ML services — on by default, so this is a no-op kept for compatibility |
--no-ai |
Skip AI/ML services |
--tags |
Fetch resource tags and add a Tags column (key=value;…) |
--tags-wide |
Also write a second CSV with one tag:<Key> column per tag key (implies --tags) |
--cost-allocation-tags |
Add a CostAllocTags column showing each resource's billing-activated tags (implies --tags) |
--include-aws-tags |
Include aws:-prefixed system tags (excluded by default) |
--billing |
Also pull Cost Explorer daily cost by service and write a CSV |
--billing-days N |
Billing window in days (default: 90) |
--billing-metric METRIC |
Cost Explorer metric (default: UnblendedCost) |
--billing-output FILE.csv |
Billing CSV path (default: billing.csv) |
--include-zero |
Keep zero-cost service/day buckets in the billing CSV |
--export FILE.csv |
Export results to CSV |
Billing
--billing pulls Cost Explorer for the trailing 90 days at daily
granularity, grouped by AWS service, and writes one CSV row per (day, service):
aws-radar inventory --all-regions --export inventory.csv --billing
AccountID,Date,Service,Amount,Currency
123456789012,2026-05-21,Amazon Elastic Compute Cloud - Compute,12.500000,USD
123456789012,2026-05-21,Amazon Simple Storage Service,1.100000,USD
If you only want the cost report and not a resource scan, use the standalone sub-command:
aws-radar billing --profile my-profile --output billing.csv
aws-radar billing --days 30 --metric AmortizedCost
A summary table of the top 20 services by spend is printed alongside the CSV.
Cost Explorer emits a bucket for every service the account has ever touched, so
zero-cost days are dropped by default — pass --include-zero to keep them. Note
that Cost Explorer is a global service reachable only through us-east-1 (the
region flags don't apply to it), it charges $0.01 per paginated API request,
and it must be enabled in the payer account before it returns data.
Tags
--tags fetches tags in bulk per region via the Resource Groups Tagging API
(one call per region) and joins them onto each resource by ARN, so you get a
serialized Tags column:
aws-radar inventory --all-regions --tags --export inventory.csv
Add --tags-wide to also emit inventory-wide.csv with one tag:<Key> column
per distinct key — handy for filtering/pivoting in a spreadsheet. Use
--cost-allocation-tags to highlight which of a resource's tags are activated
for cost allocation in Billing (read once from Cost Explorer).
S3 buckets are global, so their tags are fetched separately via
GetBucketTagging. Resources that aren't taggable (or have no tags) get an
empty Tags cell.
AI/ML services
AI/ML services are scanned by default. Pass --no-ai to skip them.
aws-radar only calls a service in regions where that service actually has an
endpoint, so enabling AI/ML by default costs little: a call into a region with
no endpoint takes about 9 seconds to fail (the hostname doesn't resolve and
botocore retries), and skipping those saves roughly 39 minutes on a full
--all-regions scan. Skips are reported as
Collecting Kendra indexes … skipped (no endpoint in eu-north-1).
The check reads botocore's bundled endpoint data and fails open — if a service is unknown to your installed boto3, it is scanned anyway rather than silently dropped.
Bedrock's control-plane calls have been seen hanging, so that collector carries
a 10-second budget. If it runs out, the run prints
Collecting Bedrock models/throughput … timed out after 10s – skipped and moves
on rather than stalling. No other collector is time-limited, so scans that are
legitimately slow on large accounts are never truncated.
AWS SSO usage
# Configure SSO once
aws configure sso
# Login before each session
aws sso login --profile my-profile
# Run
aws-radar run --profile my-profile --all-regions
Multi-account
for profile in prod staging dev; do
aws sso login --profile $profile
aws-radar run --profile $profile --csv ${profile}.csv --output ${profile}.drawio
done
Python API
import boto3
from aws_radar.inventory import run_inventory
from aws_radar.drawio import build_drawio
session = boto3.Session(profile_name="my-profile")
# include_ai defaults to True; pass include_ai=False to skip AI/ML services
rows = run_inventory(["us-east-1", "eu-west-1"], session, account_id="123456789012")
mxfile = build_drawio(rows, account_id="123456789012")
from aws_radar.billing import fetch_daily_cost_by_service, totals_by_service
cost_rows = fetch_daily_cost_by_service(session, "123456789012", days=90)
for service, total in totals_by_service(cost_rows)[:10]:
print(f"{service}: {total:,.2f}")
Required IAM permissions
Attach the AWS-managed ReadOnlyAccess policy, or grant these specific actions:
ec2:Describe* · rds:Describe* · lambda:ListFunctions
ecs:List*/Describe* · eks:List*/Describe*
elasticache:Describe* · dynamodb:ListTables/DescribeTable
s3:ListAllMyBuckets · opensearch:List*/Describe*
sqs:ListQueues · sns:ListTopics
elasticloadbalancing:DescribeLoadBalancers
sts:GetCallerIdentity
For --tags you also need (all included in ReadOnlyAccess):
tag:GetResources · s3:GetBucketTagging · ce:ListCostAllocationTags
For the AI/ML services scanned by default (all included in ReadOnlyAccess;
use --no-ai if you'd rather not grant them):
bedrock:List* · sagemaker:List* · rekognition:List*/DescribeProjects
textract:ListAdapters · comprehend:List* · lex:ListBots · kendra:ListIndices
transcribe:List* · polly:ListLexicons · translate:ListTerminologies
forecast:ListPredictors · personalize:ListCampaigns
For --billing / aws-radar billing:
ce:GetCostAndUsage
License
MIT
Metadata
Release files for aws-radar 1.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aws_radar-1.4.1.tar.gz | 42.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aws_radar-1.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 74.0 kB
Release files / aws_radar-1.4.1.tar.gz
| Download URL | aws_radar-1.4.1.tar.gz |
|---|---|
| Size | 42.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
43165732d7fe2180e7d83a34f40156e2556ba6556ec8500ee008c727d234dc24
|
|
BLAKE2b-256 checksum How to use checksums |
7a9f83f1c4a40f97ef7f3d86f460995acd5370b5caea837d7e829c866e2e1910
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / aws_radar-1.4.1-py3-none-any.whl
| Download URL | aws_radar-1.4.1-py3-none-any.whl |
|---|---|
| Size | 31.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fbf920cf293e78fdd9d2a0b3a32b76091fe91f684459a99f9d864833c082a3ce
|
|
BLAKE2b-256 checksum How to use checksums |
9c66fa5b2240c837078fcf0a0dd8e41b2c1e20c48c2368a03256c8ef74ed4c25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|