[アップデート]AWS Service Referenceに条件キーとリソース情報が追加されました

[アップデート]AWS Service Referenceに条件キーとリソース情報が追加されました

AWS Service Referenceに条件キーとリソース情報が追加されました
Clock Icon2025.03.14

お疲れさまです。とーちです。

皆さんAWS Service Reference使ってますか? ナニソレ?と思われた方、私も同じことを思ったのでご安心ください。

AWS Service ReferenceとはAWSがJSON形式で各AWSサービスに関する以下の情報を提供しているものになります。

  • 対象のサービスにおいて、IAMポリシーで記載できるアクション、リソース、条件キーのリスト

AWS Service Referenceはインデックスと各サービスといった構成で提供されており、インデックスには各サービスのJSONにアクセスするためのURLが一覧で載っています。

インデックスにはこちらからアクセスできます。内容は以下のようになっています。

[ 
    { 
        "service": "s3", 
        "url": "https://servicereference.us-east-1.amazonaws.com/v1/s3/s3.json" 
    }, 
    { 
        "service": "dynamodb", 
        "url": "https://servicereference.us-east-1.amazonaws.com/v1/dynamodb/dynamodb.json" 
    },]

Simplified AWS service information for programmatic access - Service Authorization Referenceより引用

インデックスに各サービスごとのURLが載っているので、そのURLにアクセスするとそのサービスで使用できるアクション、リソース、条件キーのリストが取得できるというわけです。

なお、JSONに記載されている各サービスの情報については以下からも確認することが可能です。

https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html

AWS Service Referenceについては、以下の記事で詳しく解説されていますので、こちらもご確認頂ければと思います。

https://dev.classmethod.jp/articles/streamline-automation-policy-management-workflows-service-reference-information/

今回のアップデート内容

さて、このAWS Service Referenceで以下のようなアップデートがありました。

https://aws.amazon.com/jp/about-aws/whats-new/2025/03/aws-service-reference-information-resources-condition-keys/

従来のAWS Service Referenceでは、サービスごとに「Actions」という項目で、IAMポリシーで記載可能なアクションについての情報が提供されていました。

今回のアップデートでは、新たに以下の2つの項目が追加されました。

  • 条件キー(ConditionKeys)
  • リソース(Resources)

Json全体でみると以下の部分に追加された形です。

{
    "Name": "s3",
    // ここは変更なし
    "Actions": [
        ...
    ],
    // [NEW] 使用可能な条件キーと型情報
    "ConditionKeys": [
        {
            "Name": "s3:TlsVersion",
            "Types": [
                "Numeric"
            ]
        },
        ...
    ],
    // [NEW] 各リソースタイプのARN形式
    "Resources": [
        {
            "Name": "accesspoint",
            "ARNFormats": [
                "arn:${Partition}:s3:${Region}:${Account}:accesspoint/${AccessPointName}"
            ]
        },
        ...
    ],
    "Version": "v1.1"
}

それぞれの追加項目について詳しく見ていきましょう。

ConditionKeys

  • 対象のサービスにおいて、IAMポリシーで記載できるすべてのサービス固有の条件キーが記載されています。
    • 条件キーの種類についてはこちらをご参照ください
  • 条件キーごとにデータ型の情報も併記されています
  • ConditionKeysの例
        "ConditionKeys": [
            {
                "Name": "s3:TlsVersion",
                "Types": [
                    "Numeric"
                ]
            },
            {
                "Name": "s3:authType",
                "Types": [
                    "String"
                ]
            },
            ...
        ],
    

Resources

  • 対象のサービスにおいて、IAMポリシーで記載できるすべてのリソースARNのフォーマットが記載されています
  • Actions項目では、各アクションが適用可能なリソースを"Name" : "elastic-ip"のように簡略表記しています。今回新設されたResources項目では、これらの簡略表記(例:"elastic-ip")に対応する完全なARNフォーマットが明示されるようになりました。
  • Resourcesの例
        "Resources": [
            {
                "Name": "accesspoint",
                "ARNFormats": [
                    "arn:${Partition}:s3:${Region}:${Account}:accesspoint/${AccessPointName}"
                ]
            },
            {
                "Name": "bucket",
                "ARNFormats": [
                    "arn:${Partition}:s3:::${BucketName}"
                ]
            }
            ...
    

このアップデートにより、各サービスごとに使用できる条件キーの型が簡単に分かるようになりました。例えば、記載したIAMポリシーの条件キーが正しく書かれているかをAWS Service ReferenceのConditionKeysの項目を使ってチェックするなどの活用方法が考えられますね。

またResources項目が追加されたことで、Actionsで使用できるリソースのARNフォーマットもAWS Service Referenceだけで調べられるようになりました。

おまけ:リソース種別からそのリソースに対応したactionを逆引きする

先日、あるリソース種別でそのリソースをIAMポリシーで指定可能なアクションを列挙することができるか?といった話題が社内でありました。

そのときはAWS Service Referenceというものがあることを知らなかったので、無理じゃないかな〜と思ったのですが、Service Referenceを使えばリソースからそのリソースを指定可能なアクションの逆引きが可能だなと思ったので、それを実現するためのPythonプログラムをおいておきます。

なおPythonのバージョンは3.12.2 で動作確認しています。

find_aws_actions.py
import requests
import json
import sys
import os

def get_services_list(use_cache=True):
    """AWSサービス一覧を取得する(キャッシュ対応)"""
    cache_dir = "aws_service_cache"
    cache_file = f"{cache_dir}/index.json"
    
    # キャッシュディレクトリがなければ作成
    if not os.path.exists(cache_dir):
        os.makedirs(cache_dir)
    
    # キャッシュがあり、使用する設定なら読み込む
    if use_cache and os.path.exists(cache_file):
        print(f"キャッシュからサービス一覧を読み込み中...")
        with open(cache_file, 'r') as f:
            return json.load(f)
    
    # キャッシュがないか使用しない設定ならダウンロード
    print(f"サービス一覧をダウンロード中...")
    try:
        response = requests.get("http://servicereference.us-east-1.amazonaws.com/")
        services = response.json()
        
        # キャッシュに保存
        with open(cache_file, 'w') as f:
            json.dump(services, f)
        
        return services
    except Exception as e:
        print(f"サービス一覧の取得に失敗しました: {e}")
        # キャッシュがあれば、エラー時はキャッシュを使用
        if os.path.exists(cache_file):
            print(f"キャッシュからサービス一覧を読み込み中...")
            with open(cache_file, 'r') as f:
                return json.load(f)
        return []

def get_service_data(service_name, service_url, use_cache=True):
    """サービス詳細を取得する(キャッシュ対応)"""
    cache_dir = "aws_service_cache"
    cache_file = f"{cache_dir}/{service_name}.json"
    
    # キャッシュがあり、使用する設定なら読み込む
    if use_cache and os.path.exists(cache_file):
        with open(cache_file, 'r') as f:
            return json.load(f)
    
    # キャッシュがないか使用しない設定ならダウンロード
    try:
        response = requests.get(service_url)
        service_data = response.json()
        
        # キャッシュに保存
        with open(cache_file, 'w') as f:
            json.dump(service_data, f)
        
        return service_data
    except Exception as e:
        print(f"  エラー: {e}")
        # キャッシュがあれば、エラー時はキャッシュを使用
        if os.path.exists(cache_file):
            with open(cache_file, 'r') as f:
                return json.load(f)
        return {}

def find_resource_actions(resource_type, use_cache=True):
    """指定されたリソースタイプを使用するAWSアクションを検索する"""
    print(f"{resource_type}リソースを使用するアクションを検索中...")
    
    # サービス一覧を取得
    services = get_services_list(use_cache)
    if not services:
        return []
    
    # 結果を保存するリスト
    found_actions = []
    
    # 各サービスを処理
    total = len(services)
    for i, service_item in enumerate(services, 1):
        service_name = service_item["service"]
        service_url = service_item["url"]
        
        print(f"処理中: {service_name} ({i}/{total})")
        
        # サービス詳細を取得
        service_data = get_service_data(service_name, service_url, use_cache)
        
        # Actionsキーがない場合はスキップ
        if "Actions" not in service_data:
            continue
            
        # 指定されたリソースを使用するアクションを検索
        for action in service_data["Actions"]:
            if "Resources" in action:
                for resource in action["Resources"]:
                    if resource.get("Name") == resource_type:
                        # 見つかったアクションを追加
                        found_actions.append({
                            "service": service_name,
                            "action": action["Name"],
                            "condition_keys": resource.get("ConditionKeys", [])
                        })
                        break
    
    return found_actions

def main():
    # コマンドライン引数からリソースタイプを取得
    if len(sys.argv) < 2:
        print("使用方法: python find_aws_actions.py <リソースタイプ> [--no-cache]")
        print("例: python find_aws_actions.py subnet")
        return
    
    resource_type = sys.argv[1]
    use_cache = "--no-cache" not in sys.argv
    
    # 指定されたリソースを使用するアクションを検索
    actions = find_resource_actions(resource_type, use_cache)
    
    # 結果を表示
    print(f"\n合計 {len(actions)} 個の {resource_type} リソースを使用するアクションが見つかりました")
    
    # サービス別に整理
    by_service = {}
    for item in actions:
        service = item["service"]
        if service not in by_service:
            by_service[service] = []
        by_service[service].append(item)
    
    # 結果を表示
    for service, service_actions in sorted(by_service.items()):
        print(f"\n## {service}")
        for action in sorted(service_actions, key=lambda x: x["action"]):
            print(f"- {action['action']}")
            if action["condition_keys"]:
                print(f"  条件キー: {', '.join(action['condition_keys'])}")
    
    # 結果をJSONファイルに保存
    output_file = f"{resource_type}_actions.json"
    with open(output_file, "w") as f:
        json.dump(actions, f, indent=2)
    print(f"\n結果は {output_file} に保存されました")

if __name__ == "__main__":
    main()

使い方

まずはPythonが入ってなければインストールします。その後、Pythonの仮想環境を作成します。

# 仮想環境の作成
python -m venv myenv

# 仮想環境の有効化
source myenv/bin/activate

次に必要パッケージをインストールしてスクリプトを実行します。スクリプト実行時に引数としてリソース名を指定します。ここで指定するリソース名はService Referenceのactions項目のResourcesに記載されているリソース名と合わせる必要があります。

# パッケージのインストール
pip install requests

# スクリプトの実行
python find_aws_actions.py subnet

このスクリプトを実行すると、指定したリソース(この例では「subnet」)に対して操作可能なすべてのIAMアクションを、まとめてリストアップしてくれます。また、それぞれのアクションで使用可能な条件キーも表示されます。

まとめ

AWS Service Referenceのアップデートについての記事でした。AWS Service Reference、活用していきたいですね。

以上、とーちでした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.