エムオーテックス株式会社が運営するテックブログです。

AWS Config 高度なクエリの活用法

AWS Config 高度なクエリの活用法

はじめに

こんにちは、SREチームの植松です。AWS上のリソースを管理するにあたり、SREチームでは正確な情報を効率的に収集することが日々の業務で求められています。特に、AWSリソースの棚卸し、設定確認、EOL(End of Life)対応など、多岐にわたるタスクを対応する必要があります。

その中で、私たちのチームが重宝しているのが「AWS Config 高度なクエリ」です。

本記事では、AWS Configの高度なクエリの使い方や、実際に業務で役立つクエリ例を紹介したいと思います。

AWS Config 高度なクエリ機能とは

SQLライクなクエリ言語を使用して、AWSリソースの検索およびフィルタリングができる機能です。条件に一致するリソースを瞬時に検索することができます。

特徴

  • SQLライクなクエリ:
    • 高度なクエリはSQLに似た構文を使用しており、データベースに慣れているユーザーにとって直感的に利用できます。
  • 多様なフィルタリング
    • リソースタイプ、タグ、リソースのコンプライアンス状態など、さまざまな条件でリソースをフィルタリングできます。
  • リアルタイム検索
    • クエリを実行すると、最新のリソース設定データに基づいて結果が返されます。
  • 保存と再利用: 作成したクエリは保存して再利用できます。

高度なクエリの使い方

AWSコンソール上のエディタおよび、CLIでのクエリに対応しています。それぞれのやり方を紹介します。

コンソールから

AWSコンソール -> AWS Config -> 高度なクエリを開きます。

新しいクエリを選択します。

サンプルクエリ(EC2一覧を出力)をエディタに入力し、実行を押します。結果が返ってくればOKです。

select
  resourceId,
  resourceType,
  configuration.instanceType
where
  resourceType = 'AWS::EC2::Instance'

AWS CLIから

AWS CLIからもクエリを実行できます。以下はS3バケットの一覧を抽出してjson保存する例です。2行目のクエリ内容を変更すれば他の条件でも抽出可能です。

aws configservice select-resource-config \
    --expression "SELECT resourceId, resourceName, resourceType, configuration.instanceType WHERE resourceType = 'AWS::S3::Bucket'" \
    --output json \
    | jq -s '.[0].Results + .[1].Results' > results.json

Pythonから

Python(boto3)からも実行することができます。以下は、入力引数のSQLクエリ結果をjsonに保存するスクリプト例です。

import boto3
import json
import argparse

def execute_aws_config_query(query, output_file):
    # AWS Configクライアントを作成
    config_client = boto3.client('config')

    # クエリを実行
    results = []
    next_token = None

    while True:
        if next_token:
            response = config_client.select_resource_config(Expression=query, NextToken=next_token)
        else:
            response = config_client.select_resource_config(Expression=query)

        results.extend([json.loads(result) for result in response['Results']])

        next_token = response.get('NextToken')
        if not next_token:
            break

    # 結果をJSON形式で保存
    with open(output_file, 'w') as f:
        json.dump(results, f, indent=4)

    print(f"Query results saved to {output_file}")

if __name__ == "__main__":
    # コマンドライン引数を解析
    parser = argparse.ArgumentParser(description='Execute AWS Config Advanced Query and save results to a JSON file')
    parser.add_argument('query', type=str, help='The SQL-like query to execute')
    parser.add_argument('output_file', type=str, help='The file to save the query results')
    args = parser.parse_args()

    # クエリを実行して結果を保存
    execute_aws_config_query(args.query, args.output_file)

以下の例のように実行します。こちらも引数のクエリを変更すれば他の条件でも抽出できます。

## 全てのリソースを検索して、jsonに出力する
python script.py "SELECT resourceId, resourceName, resourceType" results.json

クエリ例

実際の業務でよく使っているクエリをご紹介します。

特定のバージョンのLambda関数を検索する

2024年10月にAWS LambdaでのPython 3.8のサポートが終了されます。 対象となるLambda関数がないかを確認するため、以下のクエリを使用しました。

select
  resourceName,
  configuration.runtime
where
  resourceType = 'AWS::Lambda::Function'
  and configuration.runtime = 'python3.8'

like検索ができるので、以下のようにランタイムがJavaのLambdaのみを抽出することもできます。

select
  resourceName,
  configuration.runtime
where
  resourceType = 'AWS::Lambda::Function'
  and configuration.runtime like 'java%'

VPC Lambdaのネットワーク設定を確認する

AWS Security Hubの指摘事項(VPCデフォルトのセキュリティグループを使用しない)の対応にあたり、 VPC Lambdaでデフォルトセキュリティグループが使われていないか確認するために以下のクエリを使用しました。

Amazon Elastic Compute Cloud コントロール - AWS Security Hub

select
  resourceType,
  resourceName,
  configuration.vpcConfig
where
  resourceType = 'AWS::Lambda::Function'

指定した期間内に作成されたリソースを確認する

リリース作業後の影響調査、設定確認のために使用しました。

select
  accountId,
  awsRegion,
  resourceName,
  resourceId,
  resourceType,
  resourceCreationTime,
  tags
where
  resourceCreationTime BETWEEN '2024-06-28T00:00:00.000Z'
  and '2024-07-01T23:59:59.000Z'
order by
  accountId asc,
  resourceType asc

アカウント横断でリソースを検索

Control Towerを有効化している場合、Auditアカウントでクエリスコープを「aws-controltower-GuardRailsComplianceAggregator」とすることでアカウント横断でリソース検索できます。

アカウント横断でリソース数を集計

以下のクエリでControl Tower管理下の全アカウントのリソース数を集計できます。

select
  accountId,
  resourceType,
  count(resourceType)
group by
  accountId,
  resourceType

集計結果を以下のようにピボットテーブルに変換し、 アカウントごとのリソース数を俯瞰します。

この集計から、開発用のAWSアカウントについて本番よりもリソース数が多いサービスがあることが判明し、不要なリソースを削除することで、コスト最適化に繋げることができました。

その他の情報

スキーマ定義

どのリソースタイプで何の項目が定義されているかは、AWS Labsのgithubで確認できます。 github.com

制限事項、注意事項

公式ドキュメントにまとまっていますが、主な注意点を以下に示します。

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

  • クエリ例にもある通り、FROM句は不要です。
  • ALL、AS、DISTINCT、FROM、HAVING、JOIN、および UNIONは使えません。
  • コンソールでのクエリ実行について、結果が500件以上ある場合、csv/jsonでエクスポートできるのは500件となります。
    • 出力結果のページ遷移を繰り返すことで、500件以降も確認できます。

終わりに

本記事では、AWS Configの高度なクエリ機能の基本的な使い方や、実際の業務で役立つクエリ例を紹介しました。 皆様のお役に立てば幸いです。