Steampipe で EC2 の情報を一覧化してみた
はじめに
本記事のテーマは AWS ブログで紹介されていた Steampipe です。
Steampipe is an open source tool for querying cloud APIs in a universal way and reasoning about the data in SQL.
(機械翻訳) Steampipeは、クラウドAPIを普遍的な方法でクエリし、SQLのデータについて推論するためのオープンソースツールです。
Explore, connect and join data.
Painlessly join live cloud configuration data with internal or external data sets to create new insights.(機械翻訳) データを探索、接続、結合します。ライブクラウド構成データを内部または外部のデータセットと痛みを伴わずに結合して、新しい洞察を作成します。
対象読者
- ふだんよく AWS CLI を使って describe してるよって方
- ちょうど取引先や上司から AWS の設定をリストでちょうだいって無茶ぶりされた方
- SQL したい方
実行例
例えば、自分が使っている EC2 について「AZ 別」「インスタンスタイプ別」に数を出したいとします。
AWS CLI の場合だと、aws ec2 describe-instances の結果から jq で抽出し、OSコマンドやシートで集計する方法になるかと思います。
Steampipe の場合だと、以下の SQL で同様の結果を得られます。
> select placement_availability_zone as az, instance_type, count(*) from aws_ec2_instance group by placement_availability_zone, instance_type; +-----------------+---------------+-------+ | az | instance_type | count | +-----------------+---------------+-------+ | ap-northeast-1a | t2.micro | 2 | | ap-northeast-1c | t2.micro | 1 | +-----------------+---------------+-------+
複数リージョン・複数アカウントの情報が欲しい場合も、その部分の設定は外出しになっているため、SQL は1回で済みます。認証情報の設定方法は以下のページにあります。AWS CLI で環境変数やプロファイルの概念に馴染みのある方には、違和感ない仕組みになっているかと思います。
セットアップ
AWS の IAM ユーザーの準備
プログラムアクセス可、ReadOnlyAccess 権限ありの IAM ユーザーを作成し、クレデンシャルをダウンロードしておきます。
インストール
前述の AWS ブログ の最後にステップ紹介とリンクがあります。とても簡単です。
インストール例(Linux)
$ sudo /bin/sh -c "$(curl -fsSL https://raw.githubusercontent.com/turbot/steampipe/main/install.sh)" $ steampipe plugin install steampipe $ steampipe plugin install aws
クレデンシャル設定例
~/.steampipe/config/aws.spc
regions = ["ap-northeast-1","us-east-1"]
環境変数
$ export AWS_ACCESS_KEY_ID=XXXXX $ export AWS_SECRET_ACCESS_KEY=XXXXX
あとはクエリを実行するだけです。参照可能なテーブルの種類はこちらです。
クエリ実行例
$ steampipe query Welcome to Steampipe v0.15.0 For more information, type .help > select count(*) from aws_iam_user +-------+ | count | +-------+ | 1 | +-------+ >
Ctrl + D でプロンプト終了します。
1:nの情報を一覧化するには?
セキュリティグループや EBS ボリュームなど、1つのインスタンスに複数アタッチされているリソースを一覧化する場合は cross join を駆使するといけます。
セキュリティグループの例
> select instance_id, sg ->> 'GroupName' as security_group from aws_ec2_instance cross join jsonb_array_elements(security_groups) as sg; +--------------+-------------------+ | instance_id | security_group | +--------------+-------------------+ | i-xxxxx | launch-wizard-1 | | i-xxxxx | launch-wizard-2 | +--------------+-------------------+
EBS ボリュームの例
> select instance_id, device ->> 'DeviceName' as DeviceName, device -> 'Ebs' ->> 'VolumeId' as VolumeId, device -> 'Ebs' ->> 'AttachTime' as AttachTime, device -> 'Ebs' ->> 'DeleteOnTermination' as DeleteOnTermination from aws_ec2_instance cross join jsonb_array_elements(block_device_mappings) as device; +--------------+------------+------------+----------------------+---------------------+ | instance_id | devicename | volumeid | attachtime | deleteontermination | +--------------+------------+------------+----------------------+---------------------+ | i-xxxxx | /dev/xvda | vol-xxxxx | 2022-07-13T13:02:33Z | true | | i-xxxxx | /dev/sdf | vol-xxxxx | 2022-07-14T02:51:44Z | false | +--------------+------------+------------+----------------------+---------------------+
ENI の例
本当は IP アドレスなども一覧に並べたかったのですが、力及ばず。親切な方教えてください。
> select instance_id, ni ->> 'NetworkInterfaceId' as eni, jsonb_pretty(cast(ni ->> 'Groups' as jsonb)) as security_group, jsonb_pretty(cast(ni ->> 'PrivateIpAddresses' as jsonb)) as private_ip from aws_ec2_instance cross join jsonb_array_elements(network_interfaces) as ni; +-------------+------------+-------------------------------------------+-------------------------------------------------------------------------------+ | instance_id | eni | security_group | private_ip | +-------------+------------+-------------------------------------------+-------------------------------------------------------------------------------+ | i-xxxxx | eni-11111 | [ | [ | | | | { | { | | | | "GroupId": "sg-xxxxx", | "Primary": true, | | | | "GroupName": "launch-wizard-1" | "Association": null, | | | | }, | "PrivateDnsName": "ip-172-31-39-164.ap-northeast-1.compute.internal", | | | | { | "PrivateIpAddress": "172.31.39.164" | | | | "GroupId": "sg-yyyyy", | } | | | | "GroupName": "launch-wizard-2" | ] | | | | } | | | | | ] | | | i-xxxxx | eni-22222 | [ | [ | | | | { | { | | | | "GroupId": "sg-zzzzz", | "Primary": true, | | | | "GroupName": "launch-wizard-3" | "Association": null, | | | | } | "PrivateDnsName": "ip-172-31-40-113.ap-northeast-1.compute.internal", | | | | ] | "PrivateIpAddress": "172.31.40.113" | | | | | } | | | | | ] | +-------------+------------+-------------------------------------------+-------------------------------------------------------------------------------+
おわりに
最初、ゲームの何かと間違えて飛びついてアテが外れたのですが、調べていくとデザインがクールで実に私好みでした。クラウド全体をデータベースと捉えて探索するという発想も天才的ですが、ツールの発展や応用を見据えた細やかな工夫が随所に感じられ、構成がよく練られたツールだと思いました。
ユーザー体験も良質で、試して結果を得るまでものの数分といったところです。
ドキュメントとサンプルもわかりやすいので、変につまずくところもなくストレスなしです。
ただ Steampipe は言ってしまえば情報の参照を楽にしてくれるところまでであり、何か問題を直接解決するといったものではないため、どう活用するかは自分のアイディア次第かと思います。AWS 以外にも Google Cloud Platform などさまざまなプラグインがあるので、組み合わせて何ができるか考えるのも面白そうです。
今後もテーブルやプラグインは随時追加されていくと思いますが、そこに欲しいものがまだない場合は、自分自身でテーブルのカスタマイズやプラグイン開発することもできるようです。
また、対話式ではなくコマンドラインでの実行や、 Docker での実行、サービス起動させて PostgreSQL クライアントから接続、などの応用も可能となっています。
AWS CLI 使ってこねこねする機会がある方は、ご興味あればぜひ1度 Steampipe を試してみてはいかがでしょうか。