我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

用SQL管理AWS云资源:Steampipe从零部署到多账号查询实战

用SQL管理AWS云资源:Steampipe从零部署到多账号查询实战 Steampipe 这名字玩云的同学应该不陌生但真正把它用顺手的人并不多。它能把你的云账号变成一张巨大的数据库表直接用 SQL 查 AWS 资源不用写一堆脚本去调 API。这篇文章我会把整套环境从零搭起来包括 AWS CLI 的安装配置以及 Steampipe 的部署、插件接入和几条实用的查询整个过程都是我在真实环境里跑过的照着做基本不会翻车。1. 整体思路与设计拆解1.1 Steampipe 到底解决什么问题日常排查云资源的时候最烦的就是“查个东西要翻半天控制台”。比如你想统计所有没打标签的 EC2 实例或者找出所有暴露到公网的安全组在控制台里得一层层点菜单、导出表格、再写脚本过滤。而 Steampipe 的思路很直接把云厂商的 API 封装成一张张数据库表然后用 PostgreSQL 语法去查。它底层是一个 PostgreSQL 实例通过外部数据包装器把云资源映射成表。你执行select * from aws_s3_bucket的时候它实际调用了 AWS 的 ListBuckets API再把返回的 JSON 转成表格行。这个设计有两个明显的好处一是你不需要提前同步数据查到的永远是最新状态二是可以跨资源类型做关联查询比如把 EC2 实例和它挂的卷、安全组、标签一次性关联出来。1.2 为什么还要带上 AWS CLI初次接触 Steampipe 的人很容易忽略一件事它查 AWS 资源时需要一套能正常工作的凭证机制。Steampipe 本身支持通过环境变量、配置文件传入凭证但在实际部署时大部分人还要顺手装一下 AWS CLI用它来管理凭证、测试连通性、排查权限问题。还有一层原因AWS CLI 的凭证配置文件~/.aws/credentials和~/.aws/config是 Steampipe 默认读取的凭证来源之一。也就是说你只要把 CLI 的凭证配好Steampipe 装完插件就能直接用不用重复配置第二遍。与其说这是“附带”不如说这是整套环境里必须打通的一环。所以我会先把 CLI 装好、配好再装 Steampipe这样后面排查问题会省很多事。2. 环境准备与基础工具安装动手之前先说一下我的参考环境一台 Linux 服务器Ubuntu 22.04 LTS有 sudo 权限能访问外网。如果你用的是 CentOS、macOS 或者 WSL思路完全一样只是包管理命令稍有差别。建议装之前先确认 Python 版本不低于 3.9虽然 Steampipe 是 Go 写的二进制但它的部分插件依赖系统证书和网络环境干净的 Python 环境能避免一些不必要的麻烦。2.1 安装 AWS CLI v2AWS CLI 现在官方主推 v2不再推荐 v1。v2 是独立打包的二进制不需要依赖系统里的 Python升级也方便。安装步骤如下curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip unzip awscliv2.zip sudo ./aws/install装完之后验证一下aws --version正常会输出类似aws-cli/2.15.x Python/3.11.x Linux/5.15.0这样的信息。如果提示找不到命令多半是安装路径没加进 PATH。默认安装位置是/usr/local/bin/aws检查一下这个路径是否存在或者在~/.bashrc里加上export PATH/usr/local/bin:$PATH。如果你在 macOS 上操作可以用brew install awscliWindows 则直接下载官方安装包。但无论哪个平台验证方式都一样。2.2 配置访问密钥AWS CLI 本身只是个客户端真正干活的是它背后调用的 API所以必须配置一组有权限的访问密钥。这里给一个最小化 IAM 策略示例只允许读取 EC2 和 S3 的信息{ Version: 2012-10-17, Statement: [ { Effect: Allow, Action: [ ec2:Describe*, s3:List*, s3:Get* ], Resource: * } ] }配置凭证时我建议用aws configure交互式命令它会引导你输入 Access Key ID、Secret Access Key、默认区域和输出格式aws configure配置内容会写入~/.aws/credentials和~/.aws/config。如果你有多个账号可以用aws configure --profile dev创建命名配置文件后续通过--profile dev参数切换。这一点对后面 Steampipe 多账号接入特别有用建议提前把命名规范定好。注意Secret Access Key 只在创建时显示一次丢了只能重新生成。另外不建议把密钥写在代码或配置文件里提交到代码仓库宁可花两分钟配置环境变量或使用 IAM Role也不要留下安全隐患。2.3 验证 CLI 连通性配置完成后先跑一条简单的命令确认链路是通的aws sts get-caller-identity如果返回了类似Account、UserId、Arn的 JSON说明凭证有效网络也正常。这一步很关键因为 Steampipe 查不到数据时八成就是卡在这一层。3. Steampipe 的安装与初始配置3.1 下载并安装 SteampipeSteampipe 官方提供了一键安装脚本也支持手动下载二进制。一键脚本适合快速部署手动方式则适合在离线环境或需要固定版本的场景下使用。我这边直接用了官方脚本sudo /bin/sh -c $(curl -fsSL https://steampipe.io/install/steampipe.sh)脚本会把二进制放到/usr/local/bin同时创建配置目录。安装完验证steampipe --version看到版本号之后还需要初始化配置目录。Steampipe 的配置默认放在~/.steampipe里面包含config和plugins两个子目录。config目录存放连接配置plugins目录存放你安装的插件二进制。第一次运行steampipe query时它会自动初始化也可以手动执行steampipe plugin list这条命令会创建默认目录结构并列出已安装的插件初始为空。3.2 安装 AWS 插件Steampipe 本身只是一个查询引擎具体要查哪朵云需要装对应的插件。装 AWS 插件的命令很简单steampipe plugin install aws插件会被下载到~/.steampipe/plugins/每个插件是一个独立的二进制文件通过grpc与主进程通信。装完后可以用steampipe plugin list确认状态正常情况下会看到aws和它的版本号。这里多说一句Steampipe 的插件机制让“查云资源”这件事变得非常模块化。今天你用它查 AWS明天想查 GitHub 或者 Okta直接装对应插件就行不用改动任何查询逻辑。这也是它比自建脚本方案更耐用的原因。3.3 插件连接配置的多账号玩法AWS 插件安装好后默认会读取你前面配置的默认凭证环境变量或~/.aws/credentials。如果你只有一个账号到这里就可以直接开查了。但真实环境里一个公司往往有多个账号开发、测试、生产分开这时候就需要在 Steampipe 里配置多个连接。打开~/.steampipe/config/aws.spc你可以看到默认连接定义。按下面的格式添加多个连接connection aws_dev { plugin aws regions [us-east-1, ap-southeast-1] access_key AKIA...DEV secret_key xxxx } connection aws_prod { plugin aws regions [us-east-1] access_key AKIA...PROD secret_key xxxx }配置好之后查询时需要指定连接名作为表名的前缀比如select * from aws_dev.aws_s3_bucket。这样一条命令就能跨账号查资源不用来回切换配置文件。多账号场景下Steampipe 的体验比 AWS 控制台好太多。4. 核心实操用 SQL 查询 AWS 资源4.1 进入交互式查询终端配置全部就绪后运行steampipe query就会进入一个类似 psql 的交互式终端。你可以在这里执行 SQL也可以输出表格、JSON、CSV 等格式。先跑一条最简单的命令试试水select title, region, account_id from aws_s3_bucket order by title;如果你前面配置没问题这里会列出当前账号下所有 S3 桶的名称、所属区域和账号 ID。第一次执行会稍慢因为插件要建立 API 连接并拉取数据之后同一会话中的查询会快一些。4.2 几条场景化的查询示例直接列几条我平时高频使用的查询都是从实际排查中提炼出来的。统计所有未打标签的 EC2 实例select instance_id, instance_type, region, launch_time from aws_ec2_instance where tags is null order by launch_time desc;找出所有关联了公网 IP 的实例select instance_id, public_ip_address, instance_state, vpc_id from aws_ec2_instance where public_ip_address is not null;列出 S3 桶的加密状态和版本控制状态select title, region, server_side_encryption_configuration, versioning_enabled from aws_s3_bucket;跨表关联查询——找出所有没有对应快照的 EC2 卷select i.instance_id, v.volume_id, v.size from aws_ec2_instance as i join aws_ebs_volume as v on i.instance_id v.attachments[0].instance_id where v.snapshot_id is null;最后一条涉及的attachments[0]是 Postgres 数组字段的访问方式。Steampipe 把 AWS API 返回的嵌套 JSON 映射成了 Postgres 的 jsonb 或数组类型所以你可以直接用 SQL 语法深入到嵌套字段这也是它强大的地方之一。4.3 非交互式输出与脚本化使用交互式终端适合边查边看但在自动化场景里你更需要的是非交互式输出。Steampipe 支持直接执行 SQL 并指定输出格式steampipe query select title, region from aws_s3_bucket --output json加上--output csv就能输出成 CSV配合定时任务跑巡检再合适不过。比如把未打标签的实例输出成文件steampipe query select instance_id, instance_type from aws_ec2_instance where tags is null --output csv untagged_instances.csv这一步在做资源配置合规审计时特别好用。你可以在定时任务里加一行0 2 * * * steampipe query select * from aws_iam_user where password_last_used interval 90 days --output csv /var/reports/iam_users_90d.csv每天凌晨自动生成报告再配合现有告警通道推送比手工翻控制台高效一个量级。5. 常见问题与排查技巧实录这套环境我在多台机器上装过也帮同事排查过不少问题下面这些是出现频率最高的坑。5.1 访问被拒绝执行查询时报AccessDenied是最常见的。先说结论这事十有八九是 IAM 权限不够而不是 Steampipe 的问题。Steampipe 的每个表都会调用对应的 API 操作比如查aws_s3_bucket至少需要s3:ListAllMyBuckets查aws_iam_user需要iam:ListUsers。排查思路aws iam list-users如果 CLI 也报权限错误那就是 IAM 策略的问题回到 AWS 控制台调整策略后再试。如果 CLI 能过但 Steampipe 不行检查一下 Steampipe 进程拿到的凭证是不是你想要的那一份。在 shell 里执行env | grep AWS看有没有历史遗留的AWS_ACCESS_KEY_ID、AWS_PROFILE环境变量覆盖了你的默认配置。我遇到过好几次明明改了~/.aws/credentials但 shell 里残留的变量还在“劫持”凭证导致 Steampipe 读到的还是旧账号。5.2 查询超慢Steampipe 查数据是实时调 API不是本地缓存所以一个table scan慢是正常的。比如aws_s3_bucket在全区域查询时插件会对每个区域调用一次 ListBuckets如果你的配置里 regions 写了一大串耗时自然翻倍。优化手段有几个在连接配置里只列你真正关心的区域不要图省事写[*]查询时尽量在 SQL 里带 where 条件比如通过where region us-east-1提前过滤大结果集用limit控制输出先看结构再考虑全量导出另外提醒一句Steampipe 的第一次查询会比较慢是因为它要建立到 AWS 的 API 连接池。同一个交互会话里后续查询会明显变快这是正常的不用慌。5.3 插件版本冲突Steampipe 升级之后旧插件可能不兼容。现象通常是执行查询时报plugin not found或connection is not available。解决办法很直接更新插件。steampipe plugin update aws如果还不行就把插件卸载重装steampipe plugin uninstall aws steampipe plugin install aws日常使用中建议定期执行steampipe plugin update --all保持插件版本跟主程序匹配。Steampipe 更新频率不算低主程序和插件版本错开一两个版本就可能出幺蛾子。5.4 输出格式的坑用--output json时如果你的 SQL 查出了嵌套字段比如 tags 是 jsonb 类型JSON 输出里会包含多层嵌套结构这跟你在交互终端看到的扁平表格不太一样。写脚本解析时务必先跑一条小查询确认输出结构别想当然地按jq .rows[0].tags去取层级可能比你预期的深。经验之谈把复杂查询写成.sql文件用steampipe query query.sql的方式执行比在命令行里拼一长串 SQL 靠谱得多。既方便复用也方便版本管理。6. 从能用走向好用的一点建议走到这一步Steampipe 已经从“能查”变成了“好用”的状态。但说实话想让它真正在团队或项目里发挥价值还有几件事值得做。第一把常用的审计类查询沉淀成 SQL 文件放到一个统一目录里做版本管理。不要每次临时敲时间一长你会发现自己总在重复造轮子。第二结合定时任务生成定期报告把未打标签资源、公网暴露端口、闲置卷这些高风险项做成报表。第三在多账号场景下把连接配置按照账号维度命名好比如aws_prod、aws_staging别用默认的aws不然查的时候根本分不清数据来自哪个环境。我在实际使用中还有一个小习惯给 Steampipe 单独建一个查询用户不直接拿 root 跑。虽然 Steampipe 主要依赖本地配置不存在远程 SQL 注入的问题但保持规范总没有坏处。另外如果你用 Steampipe 做 CI/CD 里的资源校验可以考虑直接调用它的 Go SDK 或者用steampipe query --output json的稳定输出接口来对接现有流程比封装 AWS SDK 省力得多。这套东西跑起来之后你会明显感觉到之前很多需要“翻控制台 手写脚本 拼表格”的活儿现在一句话就搞定了而且查询结果天然就是结构化数据直接喂给报表工具也行接到告警规则里也没问题。这就是 Steampipe 真正的价值所在。
返回列表