TocConsulting/awsmap

GitHub: TocConsulting/awsmap

awsmap 是一款快速全面的 AWS 资源清单映射与盘点工具,支持跨 150+ 服务和所有区域并行扫描,并提供 SQL 查询、自然语言问答和漂移检测能力。

Stars: 95 | Forks: 12

AWS Inventory Tool

PyPI version Downloads Docker Docker Pulls License: MIT Python 3.9+ AWS Services

# awsmap 一个快速、全面的工具,用于映射和盘点跨 150 多种服务和所有区域的 AWS 资源。

awsmap demo: scan, SQL query, security queries, and natural-language ask

## 功能特性 - **150 多种 AWS 服务**:涵盖计算、存储、数据库、网络、安全等 - **多区域**:跨所有已启用区域并行扫描 - **本地数据库**:每次扫描自动存储在 SQLite 中 - 可离线查询您的清单 - **SQL 查询引擎**:针对您的清单历史记录运行 SQL(`awsmap query "SELECT ..."`) - **预置查询库**:30 个开箱即用的安全与合规查询(`awsmap query -n admin-users`) - **自然语言查询**:用纯英文提问 - 零依赖,开箱即用(`awsmap ask show me all EC2 without Owner tag`) - **示例库**:1381 个按服务组织的、随时可运行的问题(`awsmap examples lambda`) - **多账户**:扫描多个账户,跨所有账户进行查询 - **标签筛选**:按标签筛选 - 同一标签的多个值满足“或”逻辑(Owner=John 或 Jane),不同标签满足“与”逻辑(Owner=John 且 Environment=Production) - **精美的 HTML 报告**:支持搜索、筛选、深色模式和导出的交互式报告 - **多种输出格式**:支持 JSON、CSV 和 HTML 格式 - **快速**:40 个 worker 并行执行(对于典型账户约需 2 分钟) - **漂移检测**:随时间比较快照 - 检测添加、删除和修改的资源(`awsmap diff`) - **闲置资源检测**:从收集的数据中查找闲置或浪费的资源,无需额外调用 API(`awsmap waste`) - **标签合规性**:审计标签覆盖情况并根据必需标签进行评分(`awsmap tags`) - **基于扫描范围的查询**:可查询扫描历史中的任何时间点,而不仅仅是当前状态(`awsmap query --scan`、`awsmap ask --scan`) - **支持控制台登录**:兼容 `aws login` 凭证提供程序 ## 安装说明 ### PyPI ``` pip install awsmap ``` **环境要求:** Python 3.9+,已配置 AWS 凭证 ### Docker ``` docker pull tarekcheikh/awsmap ``` 或者在本地构建: ``` git clone https://github.com/TocConsulting/awsmap.git cd awsmap docker build -t awsmap . ``` ### 开发者安装 ``` git clone https://github.com/TocConsulting/awsmap.git cd awsmap pip install -e . ``` ## Docker 使用方法 ``` # 使用 AWS credentials 文件 docker run --rm \ -v ~/.aws:/root/.aws:ro \ -v $(pwd)/output:/app/output \ -v ~/.awsmap:/root/.awsmap \ awsmap -p myprofile -o /app/output/inventory.html # 使用环境变量 docker run --rm \ -e AWS_ACCESS_KEY_ID \ -e AWS_SECRET_ACCESS_KEY \ -e AWS_DEFAULT_REGION=us-east-1 \ -v $(pwd)/output:/app/output \ -v ~/.awsmap:/root/.awsmap \ awsmap -o /app/output/inventory.html # 查询存储的 inventory docker run --rm \ -v ~/.awsmap:/root/.awsmap \ awsmap query "SELECT service, COUNT(*) as count FROM resources GROUP BY service ORDER BY count DESC" # 列出可用服务 docker run --rm awsmap --list-services ``` ## 用法 ``` # 完整 account inventory(所有服务,所有区域,HTML 输出) awsmap -p myprofile # 特定服务(逗号分隔或多个 -s 标志) awsmap -p myprofile -s ec2,s3,rds,lambda,iam # 特定区域 awsmap -p myprofile -r us-east-1,eu-west-1 # 按 tags 过滤(同一 key 使用 OR 逻辑) awsmap -p myprofile -t Owner=John -t Owner=Jane -t Environment=Production # JSON 输出 awsmap -p myprofile -f json -o inventory.json # 列出可用 collectors awsmap --list-services # 显示每个服务的耗时(用于 debugging) awsmap -p myprofile --timings # 排除默认的 AWS resources(默认 VPCs、security groups 等) awsmap -p myprofile --exclude-defaults # 跳过本地数据库存储 awsmap -p myprofile --no-db ``` ## 多账户 扫描多个 AWS 账户。每次扫描都存储在同一个本地数据库中 - 您可以跨所有账户进行查询。 ``` # 扫描不同的 accounts(不同的 profiles) awsmap -p production awsmap -p staging awsmap -p dev-account # 跨所有 accounts 查询 awsmap query -n resources-by-account awsmap ask how many resources per account # 限定到一个 account awsmap query -n admin-users -a production awsmap ask -a staging show me all Lambda functions ``` ## 查询您的资源清单 每次扫描都会自动存储在本地 SQLite 数据库(`~/.awsmap/inventory.db`)中。可以使用原生 SQL 或自然语言离线查询。 ### SQL 查询 ``` # 统计每个 service 的 resources 数量 awsmap query "SELECT service, COUNT(*) as count FROM resources GROUP BY service ORDER BY count DESC" # 查找特定区域内的所有 EC2 实例 awsmap query "SELECT id, name, region FROM resources WHERE service='ec2' AND type='instance'" # 查看扫描历史 awsmap query "SELECT * FROM scans ORDER BY timestamp DESC" # JSON 或 CSV 输出 awsmap query "SELECT * FROM resources WHERE service='s3'" -f json awsmap query "SELECT service, id, name FROM resources" -f csv # 查询 tags(过滤出具有该 tag 的 resources) awsmap query "SELECT id, name, json_extract(tags, '$.Owner') as owner FROM resources WHERE service='ec2' AND json_extract(tags, '$.Owner') IS NOT NULL" ``` **更多 SQL 示例:** 请参阅 `examples/queries/*.sql` 获取可自定义的、开箱即用的查询模板。 ### 预置查询库 awsmap 内置了 30 个预置查询,用于常见的安全、合规和运维任务。无需 SQL 知识。 ``` # 列出所有可用查询 awsmap query --list # 运行命名查询 awsmap query -n admin-users awsmap query -n users-without-mfa awsmap query -n open-security-groups awsmap query -n untagged-resources # 传递参数(查找带有 Owner tag 的 resources) awsmap query -n resources-by-tag -P tag=Owner # 多个参数(查找缺少 Environment tag 的 EC2) awsmap query -n missing-tag -P tag=Environment -P service=ec2 # 限定到特定 account awsmap query -n admin-users -a production # 显示查询 SQL 而不运行 awsmap query --show admin-users # 从文件运行 SQL awsmap query -F my-query.sql ``` **参数格式:** 使用 `-P parameter=value`,其中 `parameter` 是查询参数名(例如 `tag`、`service`),而 `value` 是您要搜索的内容。示例:`-P tag=Owner` 表示“按 Owner 标签筛选”(而不是 `-P Owner=SomeValue`)。 **可用查询:** | 查询 | 描述 | 示例 | |-------|-------------|---------| | **IAM / 安全** | | | | `admin-users` | 具有管理员权限的 IAM 用户(直接权限和通过组获取的权限) | `awsmap query -n admin-users` | | `admin-roles` | 具有管理员权限的 IAM 角色 | `awsmap query -n admin-roles` | | `users-without-mfa` | 未启用 MFA 的 IAM 用户 | `awsmap query -n users-without-mfa` | | `iam-inactive-users` | 没有登录凭证且没有访问密钥的 IAM 用户 | `awsmap query -n iam-inactive-users` | | `old-access-keys` | 拥有访问密钥的 IAM 用户 | `awsmap query -n old-access-keys` | | `cross-account-roles` | 信任策略允许外部账户访问的 IAM 角色 | `awsmap query -n cross-account-roles` | | `open-security-groups` | 包含 0.0.0.0/0 入站规则的 Security group | `awsmap query -n open-security-groups` | | `secrets-no-rotation` | 未开启自动轮换的 Secrets Manager 密钥 | `awsmap query -n secrets-no-rotation` | | **S3** | | | | `public-s3-buckets` | 启用了公开访问权限的 S3 存储桶 | `awsmap query -n public-s3-buckets` | | `encryption-status` | S3 存储桶及其加密配置 | `awsmap query -n encryption-status` | | `s3-no-versioning` | 未启用版本控制的 S3 存储桶 | `awsmap query -n s3-no-versioning` | | `s3-no-logging` | 未启用访问日志记录的 S3 存储桶 | `awsmap query -n s3-no-logging` | | **EC2 / EBS** | | | | `stopped-instances` | 处于停止状态的 EC2 实例 | `awsmap query -n stopped-instances` | | `unused-volumes` | 未挂载到任何实例的 EBS 卷 | `awsmap query -n unused-volumes` | | `ebs-unencrypted` | 未加密的 EBS 卷 | `awsmap query -n ebs-unencrypted` | | `unused-eips` | 未关联到任何实例的 Elastic IP | `awsmap query -n unused-eips` | | `default-vpcs` | 跨所有区域的默认 VPC | `awsmap query -n default-vpcs` | | **RDS** | | | | `rds-public` | 启用了公开访问的 RDS 实例 | `awsmap query -n rds-public` | | `rds-unencrypted` | 未加密的 RDS 实例 | `awsmap query -n rds-unencrypted` | | `rds-no-multi-az` | 未启用 Multi-AZ 的 RDS 实例 | `awsmap query -n rds-no-multi-az` | | `rds-engines` | 按引擎分组的 RDS 实例 | `awsmap query -n rds-engines` | | **Lambda** | | | | `lambda-runtimes` | 按 runtime 分组的 Lambda 函数 | `awsmap query -n lambda-runtimes` | | `lambda-high-memory` | 内存大于 512 MB 的 Lambda 函数 | `awsmap query -n lambda-high-memory` | | **标签** | | | | `untagged-resources` | 没有任何标签的资源 | `awsmap query -n untagged-resources` | | `missing-tag` | 缺少特定标签的资源 | `awsmap query -n missing-tag -P tag=Owner` | | `resources-by-tag` | 包含特定标签的资源 | `awsmap query -n resources-by-tag -P tag=Owner` | | **清单** | | | | `resources-by-service` | 每个服务的资源数量 | `awsmap query -n resources-by-service` | | `resources-by-region` | 每个区域的资源数量 | `awsmap query -n resources-by-region` | | `resources-by-account` | 每个账户的资源数量 | `awsmap query -n resources-by-account` | | `resources-per-account-service` | 每个账户中每个服务的资源数量 | `awsmap query -n resources-per-account-service` | 您也可以通过将 `.sql` 文件放在 `~/.awsmap/queries/` 目录中来添加您自己的查询。请使用与内置查询相同的头部格式(`-- name:`、`-- description:`、`-- params:`)。 ### 自然语言查询 使用 `awsmap ask` 用简单的英文提问关于您的资源清单的问题。**无需任何设置** - 内置零依赖解析器,开箱即用。 ``` awsmap ask how many resources per region awsmap ask show me all EC2 instances without Owner tag awsmap ask which S3 buckets are in eu-west-1 awsmap ask what services have the most resources ``` awsmap 使用**内置解析器**(零依赖)将您的问题转换为 SQL,向您展示生成的查询,并显示结果。 ### 示例库 使用 `awsmap examples` 浏览并运行按 AWS 服务组织的 1381 个预置问题。 ``` # 列出带有问题数量的所有服务 awsmap examples # 浏览某个服务的问题 awsmap examples lambda # 按编号运行特定问题 awsmap examples lambda 5 # 跨所有问题搜索 awsmap examples --search "public" awsmap examples --search "encryption" ``` #### 多账户查询 当扫描了多个账户时,`awsmap ask` 默认会查询所有账户。使用 `-a` 限定在单个账户范围内: ``` # 跨所有 accounts 查询 awsmap ask show me all IAM users # 限定到一个 account awsmap ask -a production show me Lambda functions ``` ## 漂移检测 随时间比较 AWS 清单快照,以检测发生了哪些变化 - 添加、删除或修改的资源。 ``` # 最近一次扫描更改了什么?(无参数:上次扫描与当前的比较) awsmap diff # 过去 7 天内更改了什么? awsmap diff --from 7d # 比较两个特定日期 awsmap diff --from 2026-01-15 --to 2026-02-09 # 限定到特定服务 awsmap diff --from 30d -s ec2,s3 # 限定到特定 account(按 profile name、alias 或 account ID) awsmap diff --from 7d -a production -r us-east-1 # 仅显示已添加或已移除的 resources awsmap diff --from 7d --type added awsmap diff --from 7d --type removed # 仅显示摘要(无 resource 详情) awsmap diff --from 7d --summary # 忽略仅 tag 的更改 awsmap diff --from 30d --ignore-tags # JSON 输出 awsmap diff --from 7d -f json -o drift-report.json # HTML 报告(交互式,带 filters 和 dark mode) awsmap diff --from 7d -f html -o drift-report.html ``` **工作原理:** awsmap 从您的扫描历史中重建时间点快照。对于每个 `(account, service)`,它会找到在给定日期或之前进行的最新扫描,然后逐字段比较两个快照。这能正确处理部分扫描 - 如果您在周一扫描了 EC2,在周二扫描了 S3,每个服务都会使用各自最新的扫描结果。 如果不指定 `--from`,`awsmap diff` 会将最近一次扫描之前的状态与当前状态进行比较,以便您准确查看最新扫描更改了什么。如果只指定 `--to` 而没有 `--from`,则默认将 `--from` 设为紧邻 `--to` 之前的扫描。 **相对日期:** `7d`、`30d`、`90d`、`yesterday`、`today`,或者精确日期如 `2026-01-15`。 **变更类型:** - **Added** - 资源存在于较新的快照中,但在较旧的快照中不存在 - **Removed** - 资源存在于较旧的快照中,但在较新的快照中不存在 - **Modified** - 资源在两个快照中都存在,但详细信息、标签或名称发生了更改(带有字段级别的差异) ## 闲置资源检测 从 awsmap 已经收集的数据中查找闲置或可能浪费的资源。无需调用新的 AWS API - 规则将针对您最新存储的快照运行。 ``` # 对当前 snapshot 运行所有 rules awsmap waste # 仅统计每条 rule 的数量 awsmap waste --summary # 限定到一个 account(按 profile name、alias 或 account ID) awsmap waste -a production # 仅运行特定 rules awsmap waste -t unattached-ebs -t available-eni # 更改 snapshots 和 AMIs 的 age threshold(默认 90 天) awsmap waste --min-age-days 180 # 包含默认的 AWS resources(默认排除) awsmap waste --include-defaults # HTML 报告(交互式,带 filters 和 dark mode) awsmap waste -f html -o waste.html ``` **规则:** | 规则 Key | 标记内容 | |----------|---------------| | `unattached-ebs` | 处于 `available` 状态的 EBS 卷 | | `unassociated-eip` | 未绑定到实例或网卡的 Elastic IP | | `available-eni` | 处于 `available`(未挂载)状态的网络接口 | | `idle-target-group` | 没有注册目标的目标组 | | `empty-classic-elb` | 没有实例的 Classic Load Balancer | | `old-snapshot` | 存在时间超过 `--min-age-days`(默认为 90)的 EBS 快照 | | `old-ami` | 存在时间超过 `--min-age-days`(默认为 90)的 AMI | | `stopped-instance` | 处于 `stopped` 状态的 EC2 实例 | awsmap 会报告数量以及需要处理的资源。它不会估算资金成本。输出格式可以是 `table`(默认)、`json` 或 `html`;除非您传入 `--include-defaults`,否则将排除 `is_default` 资源。 ## 标签合规性 审计整个资源清单中的标签覆盖情况,并根据一组必需的标签进行评分。基于已收集的数据运行。 ``` # “至少有一个 tag”的覆盖率 awsmap tags # 针对所需 tags 的合规性 awsmap tags -R Owner,Environment,CostCenter # 限定到一个 account 和 service,仅列出不合规模 resources awsmap tags -a production -s ec2 --noncompliant-only # 仅列出没有 tags 的 resources awsmap tags --untagged-only # 仅显示分数,不列出 resources awsmap tags -R Owner --summary # HTML 报告 awsmap tags -R Owner,Environment -f html -o tag-compliance.html ``` 报告会显示总体合规性评分、每个必需标签的覆盖率(以便您找出差距所在)、各服务的分类明细,以及不合规资源及其缺失标签的列表。 - 必需标签来源于 `-R/--required`(逗号分隔或可重复使用)或 `required_tags` 配置项。如果两者都未设置,合规性检查将退化为“至少拥有一个标签”。 - 空的标签值(例如 `Owner=`)将被视为缺失。 - 默认情况下排除 `is_default` 资源;传入 `--include-defaults` 可保留它们。 - 设置一次默认的必需标签集:`awsmap config set required_tags Owner,Environment,CostCenter`。 - 输出格式为 `table`(默认)、`json` 或 `html`。 ## 查询特定扫描 默认情况下,`query` 和 `ask` 针对当前快照(`is_current`)运行。使用 `--scan` 可以指向您历史记录中的任何一次扫描。 ``` # 列出存储的 scans awsmap query --list-scans # 对上次 scan 运行命名查询 awsmap query --scan previous -n admin-users # 针对最新 scan 的原始 SQL(使用 {scan_filter} 占位符) awsmap query --scan latest "SELECT service, COUNT(*) FROM resources WHERE {scan_filter} GROUP BY service" # 针对第一次(最旧)scan 的自然语言 awsmap ask --scan first show me ec2 instances ``` 选择器:`latest`、`previous`、`first`,或者显式指定 ``(参见 `--list-scans`)。命名查询、文件和 `ask` 会自动应用该范围。对于原始内联 SQL,请在范围应用的位置包含 `{scan_filter}` 占位符;如果在没有占位符的原始 SQL 上使用 `--scan`,将会报错,而不是运行未加限制查询。 ## 演示数据库 生成一个真实的合成数据库,无需 AWS 账户即可试用 awsmap。涵盖所有 150 多种服务、多个账户以及带有漂移的多次扫描。 ``` # 使用默认值生成(3 个 accounts,3 个 scans,约 12,000 个 resources) awsmap demo # 自定义选项 awsmap demo --accounts 2 --scans 5 --db ./demo.db # 覆盖现有的 awsmap demo --force ``` 生成后,使用 `--db` 将任何命令指向演示数据库: ``` awsmap query --db ~/.awsmap/demo.db -n admin-users awsmap ask --db ~/.awsmap/demo.db show me all EC2 instances awsmap diff --db ~/.awsmap/demo.db --from 30d awsmap examples lambda 5 --db ~/.awsmap/demo.db ``` 或者将其设置为默认数据库: ``` awsmap config set db ~/.awsmap/demo.db ``` ### 演示选项 (`awsmap demo`) | 选项 | 描述 | |--------|-------------| | `--db` | 数据库路径(默认:`~/.awsmap/demo.db`) | | `--accounts` | 要生成的账户数量(1-5,默认:3) | | `--scans` | 每个账户用于生成漂移的扫描次数(1-5,默认:3) | | `--seed` | 用于结果可重复的随机种子(默认:42) | | `--force` | 覆盖现有的演示数据库 | ## CLI 选项 ### 扫描选项 | 选项 | 描述 | |--------|-------------| | `-p, --profile` | AWS profile 名称 | | `-r, --region` | 要扫描的区域(逗号分隔或使用多个标志) | | `-s, --services` | 要扫描的服务(逗号分隔或使用多个标志) | | `-t, --tag` | 按 Key=Value 过滤标签(允许多次使用) | | `-f, --format` | 输出格式:`html`(默认)、`json`、`csv` | | `-o, --output` | 输出文件路径 | | `-w, --workers` | 并行 worker 数量(默认:40) | | `-q, --quiet` | 抑制进度输出 | | `--timings` | 显示每个服务的时间摘要 | | `--include-global` | 在按非全局区域过滤时包含全局服务 | | `--exclude-defaults` | 排除默认的 AWS 资源(默认 VPC、安全组等) | | `--no-db` | 跳过本地数据库存储 | | `--list-services` | 列出可用的服务收集器 | ### 查询选项 (`awsmap query`) | 选项 | 描述 | |--------|-------------| | `-n, --name` | 运行预置的命名查询 | | `-F, --file` | 从文件运行 SQL | | `-l, --list` | 列出可用的预置查询 | | `-S, --show` | 显示命名查询的 SQL 而不运行它 | | `-P, --param` | 命名查询的参数(`key=value`,允许多次使用) | | `-a, --account` | 限定在一个账户范围内(账户 ID、账户别名或 AWS profile) | | `--scan` | 限定在一次扫描范围内:`latest`、`previous`、`first` 或 ``(原生 SQL 需要包含 `{scan_filter}` 占位符) | | `--list-scans` | 列出已存储的扫描并退出 | | `--db` | 数据库路径(默认:`~/.awsmap/inventory.db`) | | `-f, --format` | 输出格式:`table`(默认)、`json`、`csv` | ### 提问选项 (`awsmap ask`) | 选项 | 描述 | |--------|-------------| | `-a, --account` | 限定在一个账户范围内(账户 ID、账户别名或 AWS profile) | | `--scan` | 限定在一次扫描范围内:`latest`、`previous`、`first` 或 `` | | `--db` | 数据库路径(默认:`~/.awsmap/inventory.db`) | ### 差异选项 (`awsmap diff`) | 选项 | 描述 | |--------|-------------| | `--from` | 用于比较的起始日期。支持:`YYYY-MM-DD`、`7d`、`30d`、`yesterday`、`today`。如省略,则将上一次扫描与当前状态进行比较 | | `--to` | 结束日期(默认:当前状态)。日期格式与 `--from` 相同 | | `-a, --account` | 限定在一个账户范围内(账户 ID、别名或 profile) | | `-s, --service` | 要比较的服务(逗号分隔或使用多个标志) | | `-r, --region` | 要比较的区域(逗号分隔或使用多个标志) | | `--type` | 仅显示一种变更类型:`all`(默认)、`added`、`removed` 或 `modified` | | `--summary` | 仅显示汇总数量,无资源详细信息 | | `--ignore-tags` | 忽略仅有标签变更的情况 | | `-f, --format` | 输出格式:`table`(默认)、`json`、`html` | | `-o, --output` | 输出文件路径 | | `--db` | 数据库路径(默认:`~/.awsmap/inventory.db`) | ### 闲置检测选项 (`awsmap waste`) | 选项 | 描述 | |--------|-------------| | `-a, --account` | 限定在一个账户范围内(账户 ID、别名或 profile) | | `-t, --type` | 仅运行特定的规则 key(逗号分隔或使用多个标志) | | `--min-age-days` | 针 `old-snapshot` 和 `old-ami` 的存在天数阈值(默认:90) | | `--include-defaults` | 包含默认的 AWS 资源(默认排除) | | `--summary` | 仅显示每条规则的数量,不列出具体资源 | | `-f, --format` | 输出格式:`table`(默认)、`json`、`html` | | `-o, --output` | 输出文件路径 | | `--db` | 数据库路径(默认:`~/.awsmap/inventory.db`) | ### 标签选项 (`awsmap tags`) | 选项 | 描述 | |--------|-------------| | `-R, --required` | 必需的标签 key(逗号分隔或可多次使用)。退化为使用 `required_tags` 配置项 | | `-a, --account` | 限定在一个账户范围内(账户 ID、别名或 profile) | | `-s, --service` | 限定在特定服务范围内(逗号分隔或使用多个标志) | | `--untagged-only` | 仅列出没有任何标签的资源 | | `--noncompliant-only` | 仅列出缺少必需标签的资源 | | `--include-defaults` | 包含默认的 AWS 资源(默认排除) | | `--summary` | 仅显示评分,不列出具体资源 | | `-f, --format` | 输出格式:`table`(默认)、`json`、`html` | | `-o, --output` | 输出文件路径 | | `--db` | 数据库路径(默认:`~/.awsmap/inventory.db`) | ### 示例选项 (`awsmap examples`) | 参数 / 选项 | 描述 | |-------------------|-------------| | `` | 显示特定服务的问题 | | ` ` | 针对数据库运行第 N 个问题 | | `-s, --search` | 按关键字搜索所有问题 | | `--db` | 数据库路径(默认:`~/.awsmap/inventory.db`) | ### 配置命令 (`awsmap config`) 设置持久化默认值,这样就不必重复输入 CLI 参数。CLI 参数始终会覆盖配置值。 仅接受下面列出的 key - 未知的 key 和无效的值将被拒绝。如果手动编辑了配置文件且包含无效条目,`awsmap config list` 会检测到它们,向您发出警告,并自动清理该文件。 | 命令 | 描述 | |---------|-------------| | `awsmap config set key value` | 设置配置值(已验证) | | `awsmap config get key` | 获取配置值 | | `awsmap config list` | 列出所有配置值(检测并清理无效条目) | | `awsmap config delete key` | 删除配置值 | **可用的配置 key(仅接受这些项):** | Key | 应用对象 | 描述 | 示例 | |-----|-----------|-------------|---------| | `profile` | `awsmap` (扫描) | 默认 AWS profile | `awsmap config set profile production` | | `regions` | `awsmap` (扫描) | 默认区域(逗号分隔) | `awsmap config set regions us-east-1,eu-west-1` | | `services` | `awsmap` (扫描) | 默认服务(逗号分隔) | `awsmap config set services ec2,s3,lambda` | | `format` | `awsmap` (扫描) | 默认输出格式(`html`、`json`、`csv`) | `awsmap config set format json` | | `workers` | `awsmap` (扫描) | 默认并行 worker 数 | `awsmap config set workers 20` | | `exclude_defaults` | `awsmap` (扫描) | 排除默认的 AWS 资源(`true`/`false`) | `awsmap config set exclude_defaults true` | | `db` | `query`、`ask` | 默认数据库路径 | `awsmap config set db /path/to/inventory.db` | | `query_format` | `query` | 默认查询输出格式(`table`、`json`、`csv`) | `awsmap config set query_format csv` | | `required_tags` | `tags` | 默认必需标签 key(逗号分隔) | `awsmap config set required_tags Owner,Environment,CostCenter` | ``` # 设置您常用的 profile 和 regions awsmap config set profile production awsmap config set regions us-east-1,eu-west-1 # 现在只需运行: awsmap # 等同于:awsmap -p production -r us-east-1,eu-west-1 # CLI 标志仍然覆盖 config: awsmap -p staging # Uses staging profile, but regions from config ``` ## Shell 自动补全 awsmap 支持 bash、zsh 和 fish 的 Tab 键补全。可补全子命令、服务名称、区域、AWS profile、查询名称、账户名称和配置 key。 ``` # Bash eval "$(awsmap completion bash)" # add to ~/.bashrc # Zsh eval "$(awsmap completion zsh)" # add to ~/.zshrc # Fish awsmap completion fish > ~/.config/fish/completions/awsmap.fish ``` **补全内容:** | 上下文 | 补全项 | |---------|-------------| | `awsmap ` | 子命令:ask、config、completion、demo、diff、examples、query | | `awsmap -s ` | 服务名称(ec2、s3、lambda、...) | | `awsmap -r ` | AWS 区域名称 | | `awsmap -p ` | 来自 ~/.aws/credentials 和 ~/.aws/config 的 AWS profile 名称 | | `awsmap query -n ` | 预置查询名称 | | `awsmap query -a ` | 来自数据库的账户别名、profile 和 ID | | `awsmap config set ` | 有效的配置 key | | `awsmap examples ` | 来自示例库的服务名称 | ## 支持的服务 | 类别 | 服务 | |----------|----------| | **计算** | ec2, lambda, ecs, eks, ecr, ecr-public, lightsail, autoscaling, application-autoscaling, elasticbeanstalk, batch, apprunner, imagebuilder | | **存储** | s3, efs, fsx, backup, datasync, dlm, storagegateway | | **数据库** | rds, dynamodb, elasticache, memorydb, docdb, neptune, redshift, redshift-serverless, keyspaces, opensearch, opensearch-serverless, dax, dsql, timestream-influxdb | | **网络** | vpc, elbv2, elb, route53, route53resolver, route53domains, cloudfront, globalaccelerator, apigateway, apigatewayv2, appsync, directconnect, network-firewall, servicediscovery, vpc-lattice, networkmanager | | **安全** | iam, sso, kms, secretsmanager, acm, acm-pca, wafv2, guardduty, inspector2, securityhub, ds, cognito, accessanalyzer, macie2, detective, shield, fms, cloudhsmv2, auditmanager, securitylake | | **管理与监控** | cloudwatch, logs, cloudtrail, ssm, config, sns, sqs, events, xray, grafana, amp, ce, budgets, compute-optimizer, service-quotas, resource-groups, health, synthetics, appconfig, organizations, servicecatalog, resiliencehub | | **Serverless** | stepfunctions, kinesis, firehose, kafka, serverlessrepo, eventbridge-scheduler, eventbridge-pipes, schemas | | **开发者工具** | cloudformation, codeartifact, codebuild, codepipeline, codedeploy, devicefarm | | **数据分析** | athena, glue, mwaa, lakeformation, emr, emr-serverless, cleanrooms, quicksight, datazone | | **AI/ML** | sagemaker, bedrock, lexv2, rekognition, textract, transcribe, translate, comprehend, polly, personalize, kendra, frauddetector | | **媒体** | mediaconvert, mediaconnect, mediapackage, medialive, mediastore, mediatailor ivs | | **迁移与传输** | transfer, dms | | **终端用户计算** | workspaces, amplify, connect | | **IoT** | iot, iotsitewise | | **其他** | ram, resource-explorer-2, mq, sesv2, appflow, gamelift, outposts, fis, location | 有关各服务详细的资源类型,请参见 [SERVICES.md](SERVICES.md)。 ## 输出格式 ### HTML(默认) 交互式报告包含: - 带有资源数量和图表的仪表板 - 跨所有资源的全局搜索 - 按服务和区域筛选 - 可折叠的服务部分 - 点击复制 ARN/ID - 可点击的标签徽章(显示所有标签) - 深色/浅色模式切换 - 将筛选后的视图导出为 CSV - 适合打印 ### JSON ``` { "metadata": { "account_id": "123456789012", "timestamp": "2024-12-24 15:30:00 UTC", "resource_count": 1590 }, "resources": [ { "service": "ec2", "type": "instance", "id": "i-1234567890abcdef0", "arn": "arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0", "name": "my-instance", "region": "us-east-1", "is_default": false, "details": {...}, "tags": {"Owner": "John", "Environment": "Production"} } ] } ``` ### CSV 扁平格式,包含列:service, type, id, name, region, arn, is_default, tags ## 标签筛选 ``` # 单个 tag awsmap -t Environment=Production # 同一 key 的多个值(OR 逻辑) awsmap -t Owner=John -t Owner=Jane # 返回 Owner 为 "John" 或 "Jane" 的 resources # 多个 keys(AND 逻辑) awsmap -t Owner=John -t Environment=Production # 返回 Owner 为 "John" 且 Environment 为 "Production" 的 resources # 组合 awsmap -t Owner=John -t Owner=Jane -t Environment=Production # 返回 (Owner 为 "John" 或 "Jane") 且 Environment 为 "Production" 的 resources ``` ## 全局服务与区域服务 AWS 有两种类型的服务: - **区域服务**(EC2、RDS、Lambda 等) - 资源存在于特定区域 - **全局服务**(IAM、Route53、CloudFront 等) - 资源是账户级别的,不特定于某个区域 ### awsmap 如何处理全局服务 当您按区域过滤时,awsmap 会根据它们的**控制面位置**智能地包含全局服务: | 命令 | 行为 | |---------|----------| | `awsmap`(无区域) | 所有服务(区域 + 全局) | | `awsmap -r us-east-1` | us-east-1 中的区域服务 + 控制面位于 us-east-1 的全局服务 | | `awsmap -r us-west-2` | us-west-2 中的区域服务 + 控制面位于 us-west-2 的全局服务 | | `awsmap -r eu-west-1` | 仅 eu-west-1 中的区域服务(无全局服务) | | `awsmap -r eu-west-1 --include-global` | eu-west-1 中的区域服务 + 所有全局服务 | ### 按控制面分类的全局服务 基于 [AWS Global Services 文档](https://docs.aws.amazon.com/whitepapers/latest/aws-fault-isolation-boundaries/global-services.html): | 控制面 | 全局服务 | |---------------|-----------------| | **us-east-1** | IAM, Organizations, Route53, Route53 Domains, CloudFront, Shield, Budgets, Cost Explorer, Health | | **us-west-2** | Network Manager, Global Accelerator | ### S3 存储桶 S3 存储桶名称是全局唯一的,但**每个存储桶都有特定的区域**。awsmap 将 S3 视为区域服务: ``` # 仅 eu-west-1 中的 S3 buckets awsmap -r eu-west-1 -s s3 # 所有 S3 buckets awsmap -s s3 ``` ## 性能表现 并行扫描跨所有区域的 **150 多种服务**。 | 账户规模 | 资源数量 | 预计耗时 | |--------------|-----------|----------------| | 小型 | <500 | ~1.5 分钟 | | 中型 | 500-5,000 | ~2 分钟 | | 大型 | 5,000-20,000 | ~3-5 分钟 | | 企业级 | 20,000+ | ~5-10 分钟 | **调优选项:** ``` # 提高 parallelism 以加快扫描速度 awsmap -p myprofile -w 50 # 为受速率限制的 accounts 降低 parallelism awsmap -p myprofile -w 20 # 仅扫描特定服务(速度更快) awsmap -p myprofile -s ec2,s3,lambda,iam # 仅扫描特定区域 awsmap -p myprofile -r us-east-1,eu-west-1 ``` **为什么扫描很快?** - 可配置 worker 的并行执行(默认:40) - 感知区域的收集器会自动跳过不支持的 region - 全局服务(IAM、Route53 等)只收集一次,而不是按区域收集 - 智能区域过滤在不相关时排除全局服务 - 优化的 API 调用(在可用时使用批量操作) ## IAM 权限 只有扫描操作(`awsmap`)会调用 AWS,并且它需要对您想要盘点的服务具有只读访问权限。分析命令(`query`、`ask`、`diff`、`waste`、`tags`)完全在本地数据库上运行,不需要任何 AWS 权限。 除了针对具体服务的读取操作外,扫描过程还会调用 `sts:GetCallerIdentity`、`account:ListRegions`(用于发现已启用的区域;如果被拒绝,则回退到内置区域列表),以及 `iam:ListAccountAliases`(用于获取账户别名)。 ### 推荐:ReadOnlyAccess 加少量补充 挂载 AWS 托管的 [`ReadOnlyAccess`](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/ReadOnlyAccess.html) 策略。它由 AWS 维护,涵盖了 awsmap 绝大多数的读取调用。 然而,`ReadOnlyAccess` 并没有覆盖所有内容:它在一些较新的服务上存在滞后(Amazon Location、MediaTailor、Timestream for InfluxDB、Textract adapters),并且故意省略了一些读取操作(例如 `glue:GetConnections`)。awsmap 调用了 26 个未被 `ReadOnlyAccess` 授权的读取操作。这些操作是通过对 awsmap 确切的 API 调用与实时的 `ReadOnlyAccess` 文档进行差异对比得出的,因此该列表是精确的差异结果,而不是猜测。 将此补充策略与 `ReadOnlyAccess` 一并挂载: ``` { "Version": "2012-10-17", "Statement": [ { "Sid": "awsmapSupplementalReadOnly", "Effect": "Allow", "Action": [ "airflow:GetEnvironment", "bedrock:ListTagsForResource", "codeartifact:ListPackageGroups", "fms:GetResourceSet", "fms:ListResourceSets", "geo:ListGeofenceCollections", "geo:ListMaps", "geo:ListPlaceIndexes", "geo:ListRouteCalculators", "geo:ListTrackers", "glue:GetConnections", "mediatailor:ListChannels", "mediatailor:ListPlaybackConfigurations", "mediatailor:ListSourceLocations", "quicksight:ListAnalyses", "quicksight:ListDashboards", "quicksight:ListDataSets", "quicksight:ListDataSources", "quicksight:ListTagsForResource", "rekognition:DescribeCollection", "textract:GetAdapter", "textract:ListAdapters", "timestream-influxdb:GetDbInstance", "timestream-influxdb:ListDbInstances", "timestream-influxdb:ListDbParameterGroups", "timestream-influxdb:ListTagsForResource" ], "Resource": "*" } ] } ``` 将两者都挂载到角色上(或者对用户使用 `attach-user-policy`): ``` # 1. 附加 AWS 托管的 ReadOnlyAccess policy aws iam attach-role-policy \ --role-name YourRoleName \ --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess # 2. 从上面的 JSON 创建补充 policy 并附加它 aws iam create-policy \ --policy-name awsmap-supplemental-readonly \ --policy-document file://awsmap-supplemental-readonly.json aws iam attach-role-policy \ --role-name YourRoleName \ --policy-arn arn:aws:iam:::policy/awsmap-supplemental-readonly ``` 每个收集器调用都经过了封装,因此拒绝权限永远不会中断扫描:受影响的资源只会被跳过。该补充策略仅消除了这些盲区,从而使资源清单完整。所有 26 个操作均为只读。 ### 替代方案:不使用托管策略 如果您无法使用 `ReadOnlyAccess`,请为 awsmap 扫描的服务授予读取操作(`Describe*`、`List*`、`Get*`,以及适用的 `BatchGet*`/`Search*`),并加上上述的补充操作。完整的独立列表涵盖大约 150 个服务前缀;有关具体服务的读取操作,请参见 [IAM Service Authorization Reference](https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html)。 ## 不会被收集的内容 此工具仅收集**用户拥有的资源**,不包括: - AWS 托管策略(仅限客户托管策略) - AWS 托管的 KMS key(仅限客户托管) - 默认的参数组和选项组 - AWS 服务相关角色 - 预留实例产品(定价目录) - 基础模型(Bedrock 目录) - 自动备份(仅限手动快照) - AWS 系统 keyspace(Keyspaces:`system_*`) - AWS 默认队列/组(MediaConvert、X-Ray) - AWS 托管域列表(Route53 Resolver:`AWSManagedDomains*`) - 默认数据湖设置(Lake Formation) **默认 VPC 资源**(默认 VPC、子网、安全组、路由表、互联网网关、NACL、DHCP 选项)默认会被收集,并在 HTML 报告中带有“DEFAULT”徽章标记。使用 `--exclude-defaults` 将其过滤掉。 有关已过滤资源的完整列表,请参见 [SERVICES.md](SERVICES.md#filtered-resources)。 ## 为什么使用内置 NLQ 解析器而不是 AI/LLM? 我们评估了自然语言查询的三种方法: | 方法 | 准确率 | 成本 | 延迟 | 离线支持 | |----------|----------|------|---------|---------| | **Ollama(本地 LLM)** | ~80% | 免费 | 慢(数秒) | 是 | | **OpenAI / Anthropic APIs** | ~95% | 按次查询付费 | 依赖网络 | 否 | | **内置解析器 (awsmap)** | **100%** | **免费** | **即时** | **是** | - **Ollama** 模型是免费的并且在本地运行,但在针对真实的 AWS 清单查询进行测试时,准确率约为 80% - 五分之一的查询会生成错误的 SQL 或静默失败。对于一个用户信任其输出的 CLI 工具来说,这是不可接受的。 - **OpenAI / Anthropic APIs** 会产生更好的结果,但需要 API key,每次查询都要花钱,并且依赖于网络连接。对于一个本该正常工作的基础设施工具来说,这并不理想。 - **内置解析器** 是一个零依赖、确定性的 NL-to-SQL 引擎。它通过了 **1500 个真实测试问题(100% 通过率)**(与 1381 个示例库分开)。它涵盖了列表、计数、聚合、区域过滤、否定、标签、多服务查询、同义词、拼写错误容错、相对时间、数字字段、关键字-值模式以及 150 多种 AWS 服务。无需 API key,无需网络,无成本,即时返回结果。 这 1500 个测试问题(在开发期间用于验证解析器)旨在涵盖绝大多数的真实使用场景。该解析器还包括拼写错误容错、同义词支持和模糊匹配,以处理人们在表达问题时的自然变化。 ## 支持 - **文档**:查阅本 README 和 [SERVICES.md](SERVICES.md) - **问题**:通过 [GitHub Issues](https://github.com/TocConsulting/awsmap/issues) 报告 Bug - **讨论**:在 [GitHub Discussions](https://github.com/TocConsulting/awsmap/discussions) 中参与交流 ## 许可证 本项目基于 MIT 许可证授权 - 详情请参阅 [LICENSE](LICENSE) 文件。
标签:AWS, DPI, 占用监测, 请求拦截, 资产管理, 资源清点, 逆向工具