SQLでクラウドリソースを管理しよう

Steampipeとは

Steampipe, a new open source project from Turbot, enables cloud pros (e.g. software developers, operations engineers and security teams) to query their favorite cloud services with SQL. It has quickly become one of our favorite tools in-house and we hope it finds a way into your tool box as well.

Steampipe: select * from cloud; | Steampipe Blogより

翻訳

Steampipeは、Turbotの新しいオープンソースプロジェクトで、クラウドのプロ(ソフトウェア開発者、運用エンジニア、セキュリティチームなど)が、お気に入りのクラウドサービスをSQLで照会できるようにするものです。このツールは、私たちのお気に入りのツールの1つになりました。

SQLでクラウドのリソースの情報が取得できます。

select * from cloud;ってなんかオシャレ✨

目次

環境構築

インストール

Dockerを使用しますが、ディレクトリ権限で少し手間がかかります。公式サイトのドキュメントはこちらです。

  • 設定ファイル永続化ディレクトリ作成
mkdir -p sp/config sp/logs sp/.aws
  • 権限の設定

Dockerコンテナ内ではsteampipeユーザー(uid:9193)で動作しており、/home/steampipe/.steampipe配下に設定ファイルが保管されます。そのため、ホスト側に永続化するディレクトリのユーザーもこれに合わせます。

sudo chown 9193.0 sp/config sp/logs sp/.aws
  • コンテナイメージの取得
docker pull turbot/steampipe
  • docker runをalias登録

ボリュームのマウントなど長いのでalias登録します。

alias steampipe='docker run \
  -it \
  --rm \
  --name steampipe \
  -v $PWD/sp/config:/home/steampipe/.steampipe/config \
  -v $PWD/sp/logs:/home/steampipe/.steampipe/logs \
  -v $PWD/sp/.aws:/home/steampipe/.aws \
  -v steampipe_data:/home/steampipe/.steampipe/db/14.2.0/data \
  -v steampipe_internal:/home/steampipe/.steampipe/internal \
  -v steampipe_plugins:/home/steampipe/.steampipe/plugins \
  turbot/steampipe'

これで、steampipeだけで呼び出せるようになりました。

steampipe -v
steampipe version 0.15.4

インストールは完了です。

プラグインの導入

クラウドベンダーごとにプラグインが用意されています。Dockerイメージはプラグインが導入されていないのでまずはプラグインを導入します。

steampipe plugin install steampipe aws

steampipe            [====================================================================] Done                
aws                  [====================================================================] Done                

Installed plugin: [email protected] v0.5.0
Documentation:    https://hub.steampipe.io/plugins/turbot/steampipe

Installed plugin: [email protected] v0.71.0
Documentation:    https://hub.steampipe.io/plugins/turbot/aws

プラグインのインストールが完了すると、configディレクトリ配下にaws.spcdefault.spcsteampipe.spcが作成されます。

ls -la sp/config/
total 20
drwxr-xr-x 2   9193 root   4096 Aug 11 19:32 .
drwxr-xr-x 5 ubuntu ubuntu 4096 Aug 11 19:31 ..
-rw-r--r-- 1   9193 root   2196 Aug 11 19:32 aws.spc
-rwxr-xr-x 1   9193 root    918 Aug 11 19:31 default.spc
-rw-r--r-- 1   9193 root     50 Aug 11 19:32 steampipe.spc

Dockerコンテナ内ではsteampipeユーザーでファイルを作成するため、ユーザーが9193、グループがrootとなっています。

設定ファイルの作成

権限に気をつけながら認証情報を作成します。(sp/.aws/configは作成しますが、からファイルでOKです。)

sudo touch sp/.aws/config sp/.aws/credentials
  • sp/.aws/credentials
[steampipe]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  • sp/config/aws.spc

全リージョンを対象、上記で指定したsteampipeプロファイルを指定します。

-  #regions = ["us-east-1", "us-west-2"]
+  regions = [*]


-  #profile = "profile2"
+  profile = "steampipe"

これでクラウドに対するクエリーができるようになりました。

クエリーの実行

対話シェル

対話シェルはこちらのコマンドで起動します。

steampipe query
Welcome to Steampipe v0.15.4
For more information, type .help
> 

>で入力を待ち受け状態となるので、SQLを記述します。

SQLを実行してみましょう。

select vpc_id, cidr_block, state, region from aws_vpc;
+-----------------------+---------------+-----------+----------------+
| vpc_id                | cidr_block    | state     | region         |
+-----------------------+---------------+-----------+----------------+
| vpc-f620489f          | 172.31.0.0/16 | available | ap-northeast-3 |
| vpc-ac59cdd7          | 172.31.0.0/16 | available | us-east-1      |
| vpc-1478f97d          | 172.31.0.0/16 | available | us-east-2      |
| vpc-0bb19f1e39842d1fd | 172.16.0.0/16 | available | us-east-1      |
| vpc-c627ada2          | 172.31.0.0/16 | available | ap-southeast-2 |
| vpc-028ddaad32154d513 | 172.20.0.0/16 | available | us-west-2      |
| vpc-203ac444          | 172.31.0.0/16 | available | us-west-2      |
| vpc-3e4af957          | 172.31.0.0/16 | available | ca-central-1   |
| vpc-fd44ce99          | 172.31.0.0/16 | available | us-west-1      |
| vpc-510ebd38          | 172.31.0.0/16 | available | eu-west-2      |
| vpc-ae98d9cb          | 172.31.0.0/16 | available | ap-northeast-1 |
| vpc-3a0f6f52          | 172.31.0.0/16 | available | eu-central-1   |
| vpc-f2b9c09b          | 172.31.0.0/16 | available | ap-south-1     |
| vpc-dc582db8          | 172.31.0.0/16 | available | sa-east-1      |
| vpc-ddf63fba          | 172.31.0.0/16 | available | eu-west-1      |
| vpc-6afc5a03          | 172.31.0.0/16 | available | eu-west-3      |
| vpc-4c787d25          | 172.31.0.0/16 | available | ap-northeast-2 |
| vpc-0276e752bfaf4251c | 172.30.0.0/16 | available | ap-northeast-1 |
| vpc-815128e5          | 172.31.0.0/16 | available | ap-southeast-1 |
| vpc-0a430a27c5180054a | 10.0.0.0/16   | available | ap-northeast-1 |
| vpc-6938c400          | 172.31.0.0/16 | available | eu-north-1     |
+-----------------------+---------------+-----------+----------------+

全リージョンを対象として、一覧が取得できます。
ちなみに入力補完も効きます。

image.png

image.png

対話シェルから抜けるには.quitまたは.exitを入力します。.始まりのコマンドはこんな感じです。(もちろん補完も有効です。)

image.png

バッチ実行

バッチ実行はqueryコマンドの後ろにクエリーを記述します。

steampipe query "select vpc_id, cidr_block, state, region from aws_vpc;"
+-----------------------+---------------+-----------+----------------+
| vpc_id                | cidr_block    | state     | region         |
+-----------------------+---------------+-----------+----------------+
| vpc-3a0f6f52          | 172.31.0.0/16 | available | eu-central-1   |
| vpc-ddf63fba          | 172.31.0.0/16 | available | eu-west-1      |
| vpc-0276e752bfaf4251c | 172.30.0.0/16 | available | ap-northeast-1 |
| vpc-0a430a27c5180054a | 10.0.0.0/16   | available | ap-northeast-1 |
| vpc-ac59cdd7          | 172.31.0.0/16 | available | us-east-1      |
| vpc-6938c400          | 172.31.0.0/16 | available | eu-north-1     |
| vpc-4c787d25          | 172.31.0.0/16 | available | ap-northeast-2 |
| vpc-f620489f          | 172.31.0.0/16 | available | ap-northeast-3 |
| vpc-0bb19f1e39842d1fd | 172.16.0.0/16 | available | us-east-1      |
| vpc-510ebd38          | 172.31.0.0/16 | available | eu-west-2      |
| vpc-fd44ce99          | 172.31.0.0/16 | available | us-west-1      |
| vpc-c627ada2          | 172.31.0.0/16 | available | ap-southeast-2 |
| vpc-ae98d9cb          | 172.31.0.0/16 | available | ap-northeast-1 |
| vpc-6afc5a03          | 172.31.0.0/16 | available | eu-west-3      |
| vpc-815128e5          | 172.31.0.0/16 | available | ap-southeast-1 |
| vpc-028ddaad32154d513 | 172.20.0.0/16 | available | us-west-2      |
| vpc-203ac444          | 172.31.0.0/16 | available | us-west-2      |
| vpc-f2b9c09b          | 172.31.0.0/16 | available | ap-south-1     |
| vpc-dc582db8          | 172.31.0.0/16 | available | sa-east-1      |
| vpc-3e4af957          | 172.31.0.0/16 | available | ca-central-1   |
| vpc-1478f97d          | 172.31.0.0/16 | available | us-east-2      |
+-----------------------+---------------+-----------+----------------+

--outputオプションを指定すると、CSVやJSONで結果を取得できます。

--output string Output format: line, csv, json or table (default "table")

steampipe query "select vpc_id, cidr_block, state, region from aws_vpc;" --output csv
vpc_id,cidr_block,state,region
vpc-203ac444,172.31.0.0/16,available,us-west-2
vpc-028ddaad32154d513,172.20.0.0/16,available,us-west-2
vpc-ac59cdd7,172.31.0.0/16,available,us-east-1
vpc-0bb19f1e39842d1fd,172.16.0.0/16,available,us-east-1
vpc-f620489f,172.31.0.0/16,available,ap-northeast-3
vpc-0a430a27c5180054a,10.0.0.0/16,available,ap-northeast-1
vpc-0276e752bfaf4251c,172.30.0.0/16,available,ap-northeast-1
vpc-ae98d9cb,172.31.0.0/16,available,ap-northeast-1
vpc-4c787d25,172.31.0.0/16,available,ap-northeast-2
vpc-815128e5,172.31.0.0/16,available,ap-southeast-1
vpc-fd44ce99,172.31.0.0/16,available,us-west-1
vpc-6938c400,172.31.0.0/16,available,eu-north-1
vpc-dc582db8,172.31.0.0/16,available,sa-east-1
vpc-3e4af957,172.31.0.0/16,available,ca-central-1
vpc-c627ada2,172.31.0.0/16,available,ap-southeast-2
vpc-1478f97d,172.31.0.0/16,available,us-east-2
vpc-3a0f6f52,172.31.0.0/16,available,eu-central-1
vpc-510ebd38,172.31.0.0/16,available,eu-west-2
vpc-f2b9c09b,172.31.0.0/16,available,ap-south-1
vpc-ddf63fba,172.31.0.0/16,available,eu-west-1
vpc-6afc5a03,172.31.0.0/16,available,eu-west-3

クエリー例

リージョン、ランタイムごとの関数数を取得

select region, runtime, count(*) from aws_lambda_function group by region, runtime
出力結果
+----------------+------------+-------+
| region         | runtime    | count |
+----------------+------------+-------+
| ap-northeast-1 | java11     | 2     |
| ap-northeast-1 | java8      | 9     |
| ap-northeast-1 | java8.al2  | 1     |
| ap-northeast-1 | nodejs14.x | 1     |
| ap-northeast-1 | nodejs4.3  | 1     |
| ap-northeast-1 | nodejs6.10 | 1     |
| ap-northeast-1 | nodejs8.10 | 4     |
| ap-northeast-1 | provided   | 2     |
| ap-northeast-1 | python2.7  | 4     |
| ap-northeast-1 | python3.6  | 10    |
| ap-northeast-1 | python3.7  | 22    |
| ap-northeast-1 | python3.8  | 2     |
| ap-northeast-1 | python3.9  | 10    |
| ap-northeast-1 | <null>     | 4     |
| ap-southeast-1 | python3.8  | 3     |
| us-east-1      | python3.6  | 1     |
| us-east-1      | python3.7  | 3     |
| us-west-2      | nodejs4.3  | 1     |
| us-west-2      | nodejs6.10 | 1     |
| us-west-2      | python2.7  | 2     |
+----------------+------------+-------+

IAMグループに所属して「いない」IAMユーザーを取得

select name, user_id, path, create_date, password_last_used from aws_iam_user where groups is null;

IAMグループに所属して「いる」IAMユーザーを取得

select name, user_id, path, create_date, password_last_used from aws_iam_user where groups is not null;

DBインスタンスの配置されたVPC情報を取得

select
  db_instance_identifier as attached_vpc,
  vsg ->> 'VpcSecurityGroupId' as vpc_security_group_id,
  vsg ->> 'Status' as status,
  sub -> 'SubnetAvailabilityZone' ->> 'Name' as subnet_availability_zone,
  sub ->> 'SubnetIdentifier' as subnet_identifier,
  sub -> 'SubnetOutpost' ->> 'Arn' as subnet_outpost,
  sub ->> 'SubnetStatus' as subnet_status
from
  aws_rds_db_instance
  cross join jsonb_array_elements(vpc_security_groups) as vsg
  cross join jsonb_array_elements(subnets) as sub;

JOINもできます。クラウドリソース以外とも可能です。

select
    aws.name aws_user_name,
    slack.id as slack_user_id,
    slack.display_name as slack_name
from
    aws_iam_user as aws,
    slack_user as slack
where
    aws.name = slack.email;

Steampipe Modsを使う

Steampipe Modsとは

A Steampipe mod is a portable, versioned collection of related Steampipe resources such as dashboards, benchmarks, queries, and controls. Steampipe mods and mod resources are defined in HCL, and distributed as simple text files. Modules can be found on the Steampipe Hub, and may be shared with others from any public git repository.

Build Mods | Documentation | Steampipeより

翻訳

Steampipe modは、ダッシュボード、ベンチマーク、クエリー、コントロールなどの関連するSteampipeリソースの、ポータブルでバージョン管理されたコレクションです。Steampipe ModとModリソースは、HCLで定義され、シンプルなテキストファイルとして配布されます。モジュールは、Steampipe Hubで見つけることができ、公開されたgitリポジトリから他の人と共有することができます。

ダッシュボード

steampipe-aws-insightsというサービス状況を可視化してくれるダッシュボードを起動してみましょう。

Dockerでダッシュボードを使うには、コンテナイメージを作成する必要があります。

  • Dockerfile.dashboad
FROM turbot/steampipe
# Setup prerequisites (as root)
USER root:0
RUN apt-get update -y \
 && apt-get install -y git
# Install the aws and steampipe plugins for Steampipe (as steampipe user).
USER steampipe:0
RUN  steampipe plugin install steampipe aws
RUN  git clone --depth 1 https://github.com/turbot/steampipe-mod-aws-insights.git /workspace
WORKDIR /workspace
CMD ["steampipe", "service", "start", "--foreground", "--dashboard", "--dashboard-listen=network"]
  • .dockerignore
sp
  • Dockerビルド
docker build -t steampipe-aws-insights -f Dockerfile.dashboad .
  • ダッシュボードの起動
docker run \
  -it \
  --rm \
  -p 9194:9194 \
  --name steampipe-insights \
  -v $PWD/sp/config:/home/steampipe/.steampipe/config \
  -v $PWD/sp/logs:/home/steampipe/.steampipe/logs \
  -v $PWD/sp/.aws:/home/steampipe/.aws \
  steampipe-aws-insights:latest
Steampipe service is running:

Database:

  Host(s):            localhost, 127.0.0.1, 172.17.0.2
  Port:               9193
  Database:           steampipe
  User:               steampipe
  Password:           ********* [use --show-password to reveal]
  Connection string:  postgres://[email protected]:9193/steampipe

Dashboard:

  Host(s):  localhost, 127.0.0.1, 172.17.0.2
  Port:     9194
  URL:      http://localhost:9194/

Managing the Steampipe service:

  # Get status of the service
  steampipe service status
         
  # View database password for connecting from another machine
  steampipe service status --show-password
  
  # Restart the service
  steampipe service restart
  
  # Stop the service
  steampipe service stop

Hit Ctrl+C to stop the service

http://localhost:9194/にアクセスしましょう。

image.png

  • ダッシュボード例

image.png

いいですね。俯瞰できます。

ベンチマーク

ダッシュボードの他にベンチマークという機能があり、例えばコスト分析などが可能です。

Compliance Modでは、HIPAAやPCI DSSなどのコンプライアンスに準拠しているかのチェックができるようです。

ダッシュボードと同様、Dockerfileをビルドして環境を用意します。
違いは取得するModのGitリポジトリ(https://github.com/turbot/steampipe-mod-aws-thrifty.git)のみです。

  • Dockerfile.steampipe-mod-aws-thrifty
FROM turbot/steampipe
# Setup prerequisites (as root)
USER root:0
RUN apt-get update -y \
 && apt-get install -y git
# Install the aws and steampipe plugins for Steampipe (as steampipe user).
USER steampipe:0
RUN  steampipe plugin install steampipe aws
RUN  git clone --depth 1 https://github.com/turbot/steampipe-mod-aws-thrifty.git /workspace
WORKDIR /workspace
CMD ["steampipe", "service", "start", "--foreground", "--dashboard", "--dashboard-listen=network"]
  • Dockerビルド
docker build -t steampipe-mod-aws-thrifty -f Dockerfile.steampipe-mod-aws-thrifty .

ベンチマークの起動(ダッシュボード)

docker run \
  -it \
  --rm \
  -p 9194:9194 \
  --name steampipe-mod-aws-thrifty \
  -v $PWD/sp/config:/home/steampipe/.steampipe/config  \
  -v $PWD/sp/logs:/home/steampipe/.steampipe/logs   \
  -v $PWD/sp/.aws:/home/steampipe/.aws \
  steampipe-mod-aws-thrifty:latest

先程のダッシュボードと一見同じですが、内容が異なります。

image.png

  • Checks

ライフサイクルポリシーが設定されているかどうかをチェックしてくれます。

image.png

ベンチマークの起動(コマンドライン)

ベンチマークはコマンドライン(steampipe check all)で起動することも可能です。

docker run \
>   -it \
>   --rm \
>   -p 9194:9194 \
>   --name steampipe-mod-aws-thrifty \
>   -v $PWD/sp/config:/home/steampipe/.steampipe/config  \
>   -v $PWD/sp/logs:/home/steampipe/.steampipe/logs   \
>   -v $PWD/sp/.aws:/home/steampipe/.aws \
>   steampipe-mod-aws-thrifty:latest check all
AWS Thrifty ......................................................................... 377 / 454 [==========]
| 
+ Networking Checks .................................................................   0 /   0 [          ]
| | 
| + Unattached elastic IP addresses (EIPs) should be released .......................   0 /   0 [          ]
| | 
| + Unused NAT gateways should be deleted ...........................................   0 /   0 [          ]
|   

+ CloudFront Checks .................................................................   0 /   6 [=         ]
| | 
| + CloudFront distribution pricing class should be reviewed ........................   0 /   6 [=         ]
|   | 
|   INFO : E1AVH3ZU5O7UU6 has PriceClass_All. .......................................... global XXXXXXXXXXXX
|   INFO : E36F4SYTATS554 has PriceClass_All. .......................................... global XXXXXXXXXXXX
|   INFO : E3NIU4ZZ3E5B2Z has PriceClass_All. .......................................... global XXXXXXXXXXXX
|   INFO : ERYYFTKUB4BUF has PriceClass_All. ........................................... global XXXXXXXXXXXX
|   OK   : E2W138Z0QR2ZVL has PriceClass_100. .......................................... global XXXXXXXXXXXX
|   OK   : E20SFFG3TWBXF9 has PriceClass_200. .......................................... global XXXXXXXXXXXX
|   

+ S3 Checks .........................................................................  65 /  72 [===       ]
| | 
| + Buckets should have lifecycle policies ..........................................  65 /  72 [===       ]
|   | 
|   ALARM: [バケット名] does not have lifecycle policy. ....... ap-northeast-1 XXXXXXXXXXXX
|   OK   : [バケット名] has a lifecycle policy. .............................. ap-northeast-1 XXXXXXXXXXXX
|   
|   
Summary

OK ......................................................................................... 64 [==        ]
SKIP ........................................................................................ 0 [          ]
INFO ....................................................................................... 13 [=         ]
ALARM ..................................................................................... 217 [=====     ]
ERROR ..................................................................................... 160 [====      ]

HIGH .................................................................................. 0 /   0 [          ]

TOTAL ............................................................................... 377 / 454 [==========]

以上、Steampipeの使い方でした。