AWS Configの高度なクエリを使ってAWSリソースの棚卸しをする
はじめに
皆様こんにちは、あかいけです。
最近AWSリソースを棚卸しする機会があり、サービスごとにAWS CLI叩いてjqでこねくり回していました。
ただし、アカウントもリージョンも複数にまたがると、もう手作業では追いきれません…。
そんなとき、AWS Configの高度なクエリ を使うと、AWS Configで記録しているリソースに対してSQLでクエリして参照できることを知りました。
というわけで今回は、高度なクエリの紹介から、クエリの組み立て方、ファイル出力、そしてClaude Codeにいい感じにやらせるところまでをまとめてみました。
AWS Configの高度なクエリとは
AWS Configの高度なクエリは、
SQLのSELECT構文のサブセットを使って、AWS Configが記録しているAWSリソースの「現在の設定状態」をプロパティベースで検索できる機能です。
便利な点として、サービス固有のAPI(describe-*やlist-*)を利用せず、AWS Configが収集している設定項目に対して、横断的なクエリを投げられるところです。
例えば以下のようなことができます、まさに棚卸しにうってつけの機能ですね。
- インベントリ管理
- 特定インスタンスタイプのEC2を一覧する
- セキュリティ/運用
- 特定の設定が有効/無効になっているリソースを洗い出す
- コスト最適化
- どのEC2にもアタッチされていないEBSボリュームを特定する
- コンプライアンス
- AWS ConfigのConformance Packの準拠状況を一覧する
クエリスコープについて
高度なクエリには、クエリスコープが2種類あります。
このスコープによって、クエリの実行範囲が異なります。
| スコープ | 説明 |
|---|---|
| このアカウントとリージョンのみ | クエリを実行したアカウントとリージョンが対象 |
| アグリゲータ | アグリゲータに設定されている、アカウント / リージョンが対象 |
AWSアカウントが複数あり、組織全体の棚卸しをしたいならアグリゲータがおすすめです。
またアグリゲータで複数のアカウントやリージョンへクエリを実行する場合は、クエリの実行結果にアカウントやリージョンを含めることをおすすめします。
制約について
高度なクエリはあくまでSQLのSELECT構文のサブセットなので、通常のSQLと比べていくつか制約があります。例えば以下のようなものです。
SELECT *は最上位のスカラープロパティ(accountIdやresourceIdなど)しか返さない。configuration配下の詳細はドット記法で個別に指定する必要があるJOIN、DISTINCT、HAVING、UNIONなどのキーワードはサポートされていない。NULL値のクエリも不可- タグなどのネスト構造を、SQLで展開(アンパック)することはできない
- 削除済みのリソースはクエリできない
- ワイルドカード(
LIKE)はプロパティ値にのみ使用可・前方一致のみ・3文字以上が必要
ほかにも細かい制約があるので、詳細は公式ドキュメントのご確認ください。
クエリの作り方
ここからは、実例も交えながらクエリの書き方を紹介していきます。
クエリの構成要素
まずは基本構文から。クエリは以下の要素で構成されます。
SELECT property [, ...]
[ WHERE condition ]
[ GROUP BY property ]
[ ORDER BY property [ ASC | DESC ] [, property [ ASC | DESC ] ...] ]
また使える演算子と関数は次のとおりです。
- 比較演算子
=(等価)、IN(リスト内)、BETWEEN(範囲)
- 論理演算子
AND、OR、NOT
- 集計関数
AVG、COUNT、MAX、MIN、SUM
- ワイルドカード
LIKE(制約あり)
例えば「EC2インスタンスのID一覧」以下でクエリできます。
SELECT
resourceId
WHERE
resourceType = 'AWS::EC2::Instance'
「Config Ruleのコンプライアンス状況を件数で集計」ならこんな感じ。
SELECT
configuration.complianceType,
COUNT(*)
WHERE
resourceType = 'AWS::Config::ResourceCompliance'
GROUP BY
configuration.complianceType
クエリ対象のJSONはどこで見れるか
クエリ対象になるのは、AWS Configが各リソースについて記録している設定項目のJSONです。
なので、まずはこのJSONの構造を把握する必要があります。
しかしながら、前述の「configuration.complianceTypeみたいなプロパティ名」はどこを参照すればいいのでしょうか?
というわけで、JSONを見る方法を2つご紹介します。
① スキーマで確認する(GitHub)
AWSが公式に、クエリ可能な全プロパティとデータ型を公開しています。
リソースタイプごとにスキーマが定義されているので、これが一番網羅的です。
なおリソースタイプによってはそもそも対応していない場合があるので、まずはここで棚卸し対象のリソースがサポートされているか確認するがの良さそうです。
② 実際のリソースで確認する(コンソール / CLI)
実際に存在するリソースがある場合は、Configコンソールのリソース詳細画面から、そのリソースの設定項目のJSONをそのまま閲覧できます。
「このリソースの、この値を引っ張りたい」といった時は、実物のJSONを見るのが手っ取り早いですね。
以下はマネジメントコンソールからEC2インスタンスを見た例です。

以下の「設定項目 (JSON)」がクエリできる項目です。

または上記のJSONはAWS CLIで取得することもできます。
aws configservice get-resource-config-history \
--resource-type "AWS::EC2::Instance" \
--resource-id "i-XXXXXXXXXXXXXXXXX"
どのプロパティを指定するか
JSONの構造が分かったら、次は「SELECT句に何を書くか」です。
ここで何を指定するかは棚卸ししたい項目次第なので、前述の方法で調べたプロパティ名の中から、必要なものを選んでいきましょう。
ここでは例として、棚卸しでよくあるパターンを3つほど例として挙げてみます。
実例①:EC2インスタンスの一覧
EC2インスタンスの棚卸しでは、インスタンスタイプや起動状態に加えて、IPアドレスやネットワーク(VPC / サブネット)あたりが分かると便利ですね。
SELECT
accountId,
awsRegion,
resourceId,
configuration.instanceType,
configuration.state.name,
configuration.privateIpAddress,
configuration.publicIpAddress,
configuration.vpcId,
configuration.subnetId,
tags
WHERE
resourceType = 'AWS::EC2::Instance'
もし起動中のインスタンスだけに絞りたければ、AND configuration.state.name = 'running'を足すと絞り込めます。
実例②:IAMユーザーの棚卸し
IAMの棚卸しでは、IAMユーザー(と、そこに紐づくポリシー)を確認したい場面が多いと思います。
ここではIAMユーザーを、作成日やアタッチされているマネージドポリシーつきで一覧してみます。
SELECT
accountId,
configuration.userName,
arn,
configuration.path,
configuration.createDate,
configuration.attachedManagedPolicies
WHERE
resourceType = 'AWS::IAM::User'
AND
awsRegion = 'global'
実例③:未使用のEBSボリュームを探す
コスト最適化の例として、アタッチされていない(=available状態の)EBSボリュームの洗い出しをしてみます。
SELECT
resourceId,
accountId,
awsRegion,
configuration.volumeType,
configuration.size,
configuration.encrypted,
resourceCreationTime,
configuration.state.value,
tags
WHERE
resourceType = 'AWS::EC2::Volume'
AND
configuration.state.value = 'available'
configuration.state.valueがavailableであることを条件にしているのがポイントです。
アタッチ済みのボリュームはin-useになるので、この条件で未使用のボリュームだけを抽出できます。
ファイル出力形式の話
棚卸しといえば、最終的に何らかのファイルにまとめる場合が多いと思います。
ここではマネジメントコンソールとAWS CLIでそれぞれ出力方法をご紹介します。
マネジメントコンソールの場合
マネジメントコンソール高度なクエリからクエリを実行すると、結果がテーブル表示されます。
その画面の「名前を付けてエクスポート」から、CSV形式またはJSON形式でダウンロードできます。

棚卸し資料としてExcelで開きたいならCSV一択ですね。
手軽さで言えばコンソールが一番ラクです。
AWS CLIの場合
AWS CLIで実行すると、結果はJSONで返ってきます。
aws configservice select-resource-config \
--expression "SELECT resourceId WHERE resourceType='AWS::EC2::Instance'"
{
"Results": [
"{\"resourceId\":\"i-XXXXXXXXXXXXXXXXX\"}",
"{\"resourceId\":\"i-YYYYYYYYYYYYYYYYY\"}",
"{\"resourceId\":\"i-ZZZZZZZZZZZZZZZZZ\"}"
],
"QueryInfo": {
"SelectFields": [
{
"Name": "resourceId"
}
]
}
}
Results配列の中身が「JSON文字列」としてエスケープされており、1要素が1リソース分のJSONを文字列化したもの、という二重構造になっています。
なので、そのままでは扱いづらく、jqでひと手間加えるのがいいでしょう。
以下のようにfromjsonでエスケープされた文字列を本来のJSONに戻すのが良さそうです。
aws configservice select-resource-config \
--expression "SELECT resourceId WHERE resourceType='AWS::EC2::Instance'" \
| jq '.Results[] | fromjson'
{
"resourceId": "i-XXXXXXXXXXXXXXXXX"
}
{
"resourceId": "i-YYYYYYYYYYYYYYYYY"
}
{
"resourceId": "i-ZZZZZZZZZZZZZZZZZ"
}
さらにCSVにしたいなら、fromjsonしたあとに@csvで整形するとよいです。
ヘッダ行を付けつつ、各プロパティを並べるとこんな感じです。
aws configservice select-resource-config \
--expression "SELECT resourceId WHERE resourceType='AWS::EC2::Instance'" \
| jq -r '["resourceId"], (.Results[] | fromjson | [.resourceId]) | @csv'
"resourceId"
"i-XXXXXXXXXXXXXXXXX"
"i-YYYYYYYYYYYYYYYYY"
"i-ZZZZZZZZZZZZZZZZZ"
なお、AWS CLI自体にCSVを直接出力するオプションはないため、CSVが欲しい場合は上記のようにjqで整形するか、コンソールのエクスポートを使う形になります。
またアグリゲータに対して実行する場合は--configuration-aggregator-nameでアグリゲータを指定します。
aws configservice select-aggregate-resource-config \
--expression "SELECT resourceId WHERE resourceType='AWS::EC2::Instance'" \
--configuration-aggregator-name aggregator-name
これらをClaude Codeにいい感じにやらせる
ここまで読んで、「便利そうだけど、プロパティ調べたりjqこねたりするの、結局めんどくさくない?」と思いませんでしたか?私はそう思います。
というわけで、一連の作業をClaude CodeのSkill(プラグイン)にまとめてみました。
インストールはマーケットプレイス経由できます。
/plugin marketplace add Lamaglama39/aws-claude-plugins
/plugin install aws-config-query@aws-claude-plugins
インストール後は棚卸ししたいリソースを伝えるだけです。
/aws-config-query:advanced-query EC2インスタンスを棚卸ししてCSVにして
またSkillの内部的な作業フローはこんな感じです。
スキーマ取得・クエリ組み立て・CSV整形といった面倒な部分はSkillとバンドルスクリプトが受け持つので、インストール後すぐに利用できます。
高度なクエリをClaude Codeに丸投げしたい方はぜひ使ってみてください。
さいごに
以上、AWS Configの高度なクエリを使ったAWSリソースの棚卸しについてでした。
改めて整理すると、
- 高度なクエリはSQLサブセットでAWSリソースの現在状態を横断検索できる機能
- クエリ作成の肝は「JSON構造を把握して、必要な値のドットパスを指定する」こと
SELECT *はトップレベルのスカラー項目だけなどの制約に注意- 出力はコンソールならCSV/JSON、CLIならjqでひと手間かけてCSVにできる
- さらに、一連の流れをまとめたSkill(プラグイン)も用意したので、サクッと使いたい方はどうぞ
棚卸しは地味だけど避けて通れない作業なので、こういう仕組みでサクッと終わらせて、空いた時間を別のことに使いたいですね。
同じようにAWSリソースの棚卸しで困っている方の助けになれば幸いです。







