AWS Configの高度なクエリを使ってAWSリソースの棚卸しをする

AWS Configの高度なクエリを使ってAWSリソースの棚卸しをする

2026.06.28

はじめに

皆様こんにちは、あかいけです。

最近AWSリソースを棚卸しする機会があり、サービスごとにAWS CLI叩いてjqでこねくり回していました。
ただし、アカウントもリージョンも複数にまたがると、もう手作業では追いきれません…。

そんなとき、AWS Configの高度なクエリ を使うと、AWS Configで記録しているリソースに対してSQLでクエリして参照できることを知りました。

というわけで今回は、高度なクエリの紹介から、クエリの組み立て方、ファイル出力、そしてClaude Codeにいい感じにやらせるところまでをまとめてみました。

AWS Configの高度なクエリとは

AWS Configの高度なクエリは、
SQLのSELECT構文のサブセットを使って、AWS Configが記録しているAWSリソースの「現在の設定状態」をプロパティベースで検索できる機能です。

https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/querying-AWS-resources.html

便利な点として、サービス固有のAPI(describe-*list-*)を利用せず、AWS Configが収集している設定項目に対して、横断的なクエリを投げられるところです。

例えば以下のようなことができます、まさに棚卸しにうってつけの機能ですね。

  • インベントリ管理
    • 特定インスタンスタイプのEC2を一覧する
  • セキュリティ/運用
    • 特定の設定が有効/無効になっているリソースを洗い出す
  • コスト最適化
    • どのEC2にもアタッチされていないEBSボリュームを特定する
  • コンプライアンス
    • AWS ConfigのConformance Packの準拠状況を一覧する

クエリスコープについて

高度なクエリには、クエリスコープが2種類あります。
このスコープによって、クエリの実行範囲が異なります。

スコープ 説明
このアカウントとリージョンのみ クエリを実行したアカウントとリージョンが対象
アグリゲータ アグリゲータに設定されている、アカウント / リージョンが対象

AWSアカウントが複数あり、組織全体の棚卸しをしたいならアグリゲータがおすすめです。
またアグリゲータで複数のアカウントやリージョンへクエリを実行する場合は、クエリの実行結果にアカウントやリージョンを含めることをおすすめします。

制約について

高度なクエリはあくまでSQLのSELECT構文のサブセットなので、通常のSQLと比べていくつか制約があります。例えば以下のようなものです。

  • SELECT *は最上位のスカラープロパティ(accountIdresourceIdなど)しか返さない。configuration配下の詳細はドット記法で個別に指定する必要がある
  • JOINDISTINCTHAVINGUNIONなどのキーワードはサポートされていない。NULL値のクエリも不可
  • タグなどのネスト構造を、SQLで展開(アンパック)することはできない
  • 削除済みのリソースはクエリできない
  • ワイルドカード(LIKE)はプロパティ値にのみ使用可・前方一致のみ・3文字以上が必要

ほかにも細かい制約があるので、詳細は公式ドキュメントのご確認ください。

https://docs.aws.amazon.com/config/latest/developerguide/querying-AWS-resources.html

クエリの作り方

ここからは、実例も交えながらクエリの書き方を紹介していきます。

クエリの構成要素

まずは基本構文から。クエリは以下の要素で構成されます。

SELECT property [, ...]
[ WHERE condition ]
[ GROUP BY property ]
[ ORDER BY property [ ASC | DESC ] [, property [ ASC | DESC ] ...] ]

https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/query-components.html

また使える演算子と関数は次のとおりです。

  • 比較演算子
    • =(等価)、IN(リスト内)、BETWEEN(範囲)
  • 論理演算子
    • ANDORNOT
  • 集計関数
    • AVGCOUNTMAXMINSUM
  • ワイルドカード
    • LIKE(制約あり)

https://docs.aws.amazon.com/config/latest/developerguide/query-components.html
https://docs.aws.amazon.com/config/latest/developerguide/querying-AWS-resources.html

例えば「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が公式に、クエリ可能な全プロパティとデータ型を公開しています。
リソースタイプごとにスキーマが定義されているので、これが一番網羅的です。

https://github.com/awslabs/aws-config-resource-schema/tree/master/config/properties/resource-types

なおリソースタイプによってはそもそも対応していない場合があるので、まずはここで棚卸し対象のリソースがサポートされているか確認するがの良さそうです。

② 実際のリソースで確認する(コンソール / CLI)

実際に存在するリソースがある場合は、Configコンソールのリソース詳細画面から、そのリソースの設定項目のJSONをそのまま閲覧できます。
「このリソースの、この値を引っ張りたい」といった時は、実物のJSONを見るのが手っ取り早いですね。

以下はマネジメントコンソールからEC2インスタンスを見た例です。

スクリーンショット 2026-06-27 18.53.45

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

スクリーンショット 2026-06-27 18.54.11

または上記の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.valueavailableであることを条件にしているのがポイントです。
アタッチ済みのボリュームはin-useになるので、この条件で未使用のボリュームだけを抽出できます。

ファイル出力形式の話

棚卸しといえば、最終的に何らかのファイルにまとめる場合が多いと思います。
ここではマネジメントコンソールとAWS CLIでそれぞれ出力方法をご紹介します。

マネジメントコンソールの場合

マネジメントコンソール高度なクエリからクエリを実行すると、結果がテーブル表示されます。
その画面の「名前を付けてエクスポート」から、CSV形式またはJSON形式でダウンロードできます。

スクリーンショット 2026-06-28 5.38.55

棚卸し資料としてExcelで開きたいならCSV一択ですね。
手軽さで言えばコンソールが一番ラクです。

AWS CLIの場合

AWS CLIで実行すると、結果はJSONで返ってきます。

https://docs.aws.amazon.com/cli/latest/reference/configservice/select-resource-config.html

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

https://docs.aws.amazon.com/cli/latest/reference/configservice/select-aggregate-resource-config.html

これらをClaude Codeにいい感じにやらせる

ここまで読んで、「便利そうだけど、プロパティ調べたりjqこねたりするの、結局めんどくさくない?」と思いませんでしたか?私はそう思います。

というわけで、一連の作業をClaude CodeのSkill(プラグイン)にまとめてみました

https://github.com/Lamaglama39/aws-claude-plugins

インストールはマーケットプレイス経由できます。

/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リソースの棚卸しで困っている方の助けになれば幸いです。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事