Amazon Cloud Directory

目次

グラフベースの階層型データストア・代替手段

Amazon Cloud Directory は、多次元の階層型カスタムディレクトリデータをクラウドでホストするグラフベースのディレクトリサービス です。ただし、2025年11月7日より、Cloud Directory は新規顧客に対して非推奨 となり、AWS は Amazon Neptune(グラフデータベース)Amazon DynamoDB(NoSQL) への移行を推奨しています。このページでは、Cloud Directory の概念・アーキテクチャ・レガシーユースケース、および 推奨される代替手段(Neptune / DynamoDB) を詳細に体系的に整理します。

このページの目的

このページでは以下を対象としています。

  • 既存ユーザー向け: Cloud Directory の継続利用・機能理解
  • 移行検討者向け: Neptune / DynamoDB への移行戦略・比較検討
  • アーキテクト向け: 階層型データ・多次元関係性の実装設計
  • 開発者向け: API・スキーマ定義・クエリ実装
  • 意思決定者向け: Apache Atlas / OrientDB / ArangoDB 等オープンソースとの比較

2025-2026 年の Cloud Directory エコシステム

  • レガシーサービス化(2025年11月以降): 新規顧客向けサービス終了。既存ユーザーは継続利用可能だが、長期的には Neptune / DynamoDB への移行を推奨
  • Neptune グラフクエリ機能強化(2025年以降): Apache TinkerPop / SPARQL / Gremlin による複雑なグラフクエリが標準に
  • DynamoDB ストリーム・トランザクション拡張(2025年以降): 階層データの変更追跡・分析処理が容易に
  • IAM Identity Center との統合(既存): Cognito / IAM Identity Center のユーザー階層管理は、Cloud Directory の古いユースケース
  • AWS Lake Formation との連携(推奨): 大規模データカタログ・メタデータ管理は DynamoDB + Glue Data Catalog で実装

概要

Amazon Cloud Directory は、グラフベースのマルチテナント・フルマネージドディレクトリサービス です。従来のディレクトリシステム(Active Directory・LDAP)は単一の木構造(単一の親を持つ)しかサポートしませんが、Cloud Directory は以下を実現します:

多親階層(Graph-based):

従来(LDAP / Active Directory):
    Organization
    ├── Department A
    │   └── User 1
    └── Department B
        └── User 1
(User 1 は 1つの部門にのみ属する)

Cloud Directory(多親階層):
    Organization
    ├── Department A ─┐
    ├── Department B ─┤
    └── Project X ───┘
                ↓
            User 1
(User 1 が複数の親を持つ = 複数部門・複数プロジェクトに属する)

しかし、重要な警告:

Amazon Cloud Directory は 2025年11月7日より新規顧客向けに非推奨。AWS は代替として Amazon Neptune または Amazon DynamoDB の使用を推奨しています。


Cloud Directory の課題・制約

1. サービス非推奨化(2025年11月)

  • 新規顧客は利用不可(既存ユーザーのみ継続利用可)
  • 長期的なロードマップなし
  • ベンダーサポート終了予定

2. 性能・スケーラビリティの限界

  • クエリレイテンシ: 数百ミリ秒~数秒(Neptune の方が高速)
  • スケーラビリティ: 数百万オブジェクトレベル(大規模グラフには不向き)

3. API の複雑さ

  • GraphQL なし(Gremlin / SPARQL による標準クエリなし)
  • カスタム API で階層クエリを実装する必要性

4. 高コスト

  • API コール単位での課金が高額
  • 同等機能を Neptune / DynamoDB で実装した方が安い場合が多い

主な特徴(歴史的)

特徴 説明 評価
多親階層対応 単一の木構造でなく、グラフ構造を表現 ★★★(Neptune の方が優秀)
スキーマ柔軟性 Facet で属性を定義し、カスタムオブジェクト型を作成 ★★☆(DynamoDB の方が柔軟)
マネージド インフラ管理・スケーリング自動 ★★★(但し非推奨)
ACID トランザクション なし ★☆☆(Neptune は限定サポート)
フルテキスト検索 なし ★☆☆(OpenSearch / Elasticsearch 併用が必要)

アーキテクチャ

graph TB
    subgraph "Cloud Directory"
        DIR["Directory<br/>(org-device-mgmt)"]

        SCHEMA["Schema<br/>(DeviceManagementSchema v1.0)"]

        subgraph "Facets"
            F1["Facet: Device<br/>(SerialNumber, OS, LastSeen)"]
            F2["Facet: Location<br/>(Building, Room, Floor)"]
            F3["Facet: Owner<br/>(Name, Email, Department)"]
        end

        subgraph "Objects (Nodes)"
            OBJ1["Device-001<br/>(iPhone 15 Pro)"]
            OBJ2["Location-A<br/>(Tokyo Office)"]
            OBJ3["Owner-001<br/>(John Doe)"]
        end

        subgraph "Typed Links (Edges)"
            LINK1["isLocatedAt<br/>(Device-001 → Location-A)"]
            LINK2["ownedBy<br/>(Device-001 → Owner-001)"]
        end
    end

    SCHEMA --> F1
    SCHEMA --> F2
    SCHEMA --> F3

    DIR --> SCHEMA
    DIR --> OBJ1
    DIR --> OBJ2
    DIR --> OBJ3

    OBJ1 --> LINK1
    OBJ1 --> LINK2

    LINK1 --> OBJ2
    LINK2 --> OBJ3

    style SCHEMA fill:#e1f5ff
    style F1 fill:#b3e5fc
    style F2 fill:#b3e5fc
    style F3 fill:#b3e5fc
    style OBJ1 fill:#fff9c4
    style OBJ2 fill:#fff9c4
    style OBJ3 fill:#fff9c4

コアコンポーネント

1. Directory(ディレクトリ)

オブジェクト・リンク・インデックスの集合体。

{
  "Name": "org-device-management",
  "SchemaArn": "arn:aws:clouddirectory:us-east-1:123456789012:schema/published/DeviceManagementSchema/1.0",
  "State": "ENABLED",
  "CreationDateTime": "2025-01-15T10:30:00Z"
}

2. Schema(スキーマ)

オブジェクト型(Facet)とそれらの関係を定義。

# Facet 定義例
{
    "FacetName": "Device",
    "Attributes": [
        {
            "Name": "SerialNumber",
            "Type": "STRING",
            "RequiredBehavior": "REQUIRED_ALWAYS",
            "IsImmutable": True
        },
        {
            "Name": "OperatingSystem",
            "Type": "STRING",
            "RequiredBehavior": "NOT_REQUIRED",
            "IsImmutable": False
        },
        {
            "Name": "LastSeen",
            "Type": "DATETIME",
            "RequiredBehavior": "NOT_REQUIRED"
        }
    ],
    "ObjectType": "LEAF_NODE"  # または NODE, POLICY
}

3. Object(オブジェクト)

ディレクトリ内の実体。複数の Facet を持つことができ、複数の親を持つ(多親階層)。

/Device/device-001
├── Facet: Device (SerialNumber=SN-2025-001)
├── Facet: Asset (Manufacturer=Apple, PurchaseDate=2025-01-01)
└── Parent Links:
    ├── /Location/tokyo-office/floor-3
    ├── /Department/hardware-team
    └── /Project/device-refresh-2025

4. Typed Link(型付きリンク)

オブジェクト間の関係を表現。

isLocatedAt: Device-001 → Location-A
  ├── StartTime: 2025-01-01
  └── Status: ACTIVE

ownedBy: Device-001 → Owner-001
  ├── StartDate: 2025-01-01
  └── Permissions: READ, WRITE

5. Index(インデックス)

高速検索用。Facet 属性に対してインデックスを作成。

  • Index on Device.SerialNumber
  • → Serial Number で高速検索可能
  • Index on Owner.Email
  • → Email で高速検索可能

スキーマとファセット

Facet の種類

種類 説明 用途
Node Facet 子オブジェクトを持てる 部門・組織・フォルダ
Leaf Facet 子オブジェクトを持たない ユーザー・デバイス・ファイル
Policy Facet ポリシー・権限を定義 ロール・権限セット

Schema ライフサイクル

DEVELOPMENT SCHEMA
    ↓ (Facet 追加・修正)
DEVELOPMENT SCHEMA (v2)
    ↓ PublishSchema
PUBLISHED SCHEMA (v1.0)
    ↓ (新しいスキーマで Directory 作成)
PUBLISHED SCHEMA (v1.1)

重要: 公開済みスキーマは変更不可。新しいバージョンを作成して公開。


オブジェクト・リンク・インデックス

オブジェクトの階層

/
├── /Organization
│   ├── /Organization/acme-corp
│   │   ├── /Department
│   │   │   ├── /Department/acme-corp/engineering
│   │   │   │   ├── /User
│   │   │   │   │   └── /User/acme-corp/engineering/john-doe
│   │   │   │   └── /Device
│   │   │   │       └── /Device/acme-corp/engineering/laptop-001
│   │   │   └── /Department/acme-corp/sales
│   │   └── /Project
│   │       └── /Project/acme-corp/device-refresh-2025
# Device-001 が Location-A に配置されている関係を定義
typed_link = {
    "SourceObjectReference": "/Device/laptop-001",
    "TargetObjectReference": "/Location/tokyo-office",
    "LinkName": "isLocatedAt",
    "Attributes": {
        "StartDate": "2025-01-01",
        "Status": "ACTIVE"
    }
}

API による実装

Python SDK 実装(非推奨警告付き)

import boto3

# ⚠️ Cloud Directory は非推奨
# Neptune / DynamoDB への移行を推奨

clouddirectory = boto3.client('clouddirectory', region_name='us-east-1')

class CloudDirectoryLegacy:
    def __init__(self, directory_arn):
        self.directory_arn = directory_arn

    def create_device_object(self, serial_number, os_name):
        """デバイスオブジェクトの作成"""
        response = clouddirectory.create_object(
            DirectoryArn=self.directory_arn,
            SchemaFacets=[{
                'SchemaArn': 'arn:aws:clouddirectory:us-east-1:123456789012:schema/published/DeviceSchema/1.0',
                'FacetName': 'Device'
            }],
            ObjectAttributeList=[
                {
                    'Key': {
                        'SchemaArn': 'arn:aws:clouddirectory:us-east-1:123456789012:schema/published/DeviceSchema/1.0',
                        'FacetName': 'Device',
                        'Name': 'SerialNumber'
                    },
                    'Value': {'StringValue': serial_number}
                },
                {
                    'Key': {
                        'SchemaArn': 'arn:aws:clouddirectory:us-east-1:123456789012:schema/published/DeviceSchema/1.0',
                        'FacetName': 'Device',
                        'Name': 'OperatingSystem'
                    },
                    'Value': {'StringValue': os_name}
                }
            ],
            ParentReference={'Selector': '/Device'},
            LinkName=f'device-{serial_number}'
        )

        return response['ObjectIdentifier']

    def list_device_by_location(self, location_path):
        """Location に配置されたすべてのデバイスを検索"""
        # ⚠️ 複雑なクエリが必要(Cloud Directory の弱点)
        response = clouddirectory.list_object_children(
            DirectoryArn=self.directory_arn,
            ObjectReference={'Selector': location_path}
        )

        devices = []
        for link_name, obj_id in response.get('Children', {}).items:
            devices.append(obj_id)

        return devices

# 使用例
# ⚠️ 新規プロジェクトでは Neptune / DynamoDB を推奨
cd = CloudDirectoryLegacy('arn:aws:clouddirectory:us-east-1:123456789012:directory/xxx')
device_id = cd.create_device_object('SN-2025-001', 'iOS 17')
print(f"Created device: {device_id}")

推奨される代替手段

1. Amazon Neptune(推奨:グラフ構造が複雑な場合)

用途:

  • 多次元の関係性が密な場合
  • グラフ分析・推奨エンジン
  • 組織図・ソーシャルネットワーク

メリット:

  • ACID トランザクション(一部)
  • Gremlin / SPARQL クエリ
  • 高性能(数ミリ秒)
  • スケーラビリティ

デメリット:

  • セットアップ・運用が複雑
  • コスト(時間単位課金)

実装例:

from gremlin_python.process.graph_traversal import __

gremlin_client = ...

# Device が Location に配置されている関係を作成
g.addV('Device').property('serialNumber', 'SN-001').as_('d') \
 .addV('Location').property('building', 'Tokyo Office').as_('l') \
 .addE('isLocatedAt').from_('d').to('l')

# Location のデバイスを検索
g.V.has('Location', 'building', 'Tokyo Office') \
 .in_('isLocatedAt') \
 .values('serialNumber')

2. Amazon DynamoDB(推奨:スケーラビリティ・コスト重視)

用途:

  • 階層データ(組織図・フォルダツリー)
  • キー・バリュー検索が中心
  • 大規模データセット

メリット:

  • スケーラビリティ(無制限)
  • コスト効率(従量課金)
  • 管理が簡単
  • レイテンシ(ミリ秒)

デメリット:

  • グラフクエリが制限的
  • 複雑な関係性の表現が困難

実装例:

import boto3
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-1')
table = dynamodb.Table('Devices')

# 階層データの保存(Partition Key: Organization、Sort Key: Device Path)
table.put_item(Item={
    'OrganizationId': 'acme-corp',
    'DevicePath': '/Department/Engineering/laptop-001',
    'SerialNumber': 'SN-2025-001',
    'OS': 'macOS',
    'Location': 'Tokyo Office',
    'OwnerEmail': 'john@acme.com',
    'Metadata': {
        'PurchaseDate': '2025-01-01',
        'Status': 'ACTIVE'
    }
})

# Location でデバイスを検索
response = table.query(
    KeyConditionExpression=Key('OrganizationId').eq('acme-corp'),
    FilterExpression=Attr('Location').eq('Tokyo Office')
)

for item in response['Items']:
    print(f"Device: {item['SerialNumber']}")

3. AWS Glue Data Catalog(推奨:メタデータ管理)

用途: テーブル・DB・データセットのメタデータ管理(階層型ディレクトリの代替)


Neptune への移行

ステップ 1: Cloud Directory から Neptune へのデータ移行

import boto3
import json

cd = boto3.client('clouddirectory', region_name='us-east-1')
neptune = boto3.client('neptune', region_name='ap-northeast-1')

def migrate_to_neptune(source_directory_arn, target_endpoint):
    """Cloud Directory → Neptune データ移行"""

    # 1. Cloud Directory からすべてのオブジェクトを取得
    # (Walker pattern で全オブジェクトをトラバース)

    all_objects = []

    def walk_directory(parent_path):
        response = cd.list_object_children(
            DirectoryArn=source_directory_arn,
            ObjectReference={'Selector': parent_path}
        )

        for link_name, obj_id in response.get('Children', {}).items:
            obj_path = f"{parent_path}/{link_name}"

            # オブジェクト属性取得
            obj_details = cd.get_object_attributes(
                DirectoryArn=source_directory_arn,
                ObjectReference={'Selector': obj_path},
                SchemaFacet={'SchemaArn': '...', 'FacetName': '...'},
                AttributeNames=['SerialNumber', 'OperatingSystem', ...]
            )

            all_objects.append({
                'id': obj_id,
                'path': obj_path,
                'attributes': obj_details['Attributes']
            })

            # 再帰的に子オブジェクトを取得
            walk_directory(obj_path)

    walk_directory('/')

    # 2. Neptune に Vertex / Edge として書き込み
    for obj in all_objects:
        # Vertex として追加
        vertex_query = f"""
        g.addV('Object')
          .property('id', '{obj['id']}')
          .property('path', '{obj['path']}')
          .property('type', '{obj['attributes'].get('ObjectType', 'Node')}')
        """

        # Neptune に実行
        # (実装は neptune-python-utils または HTTP API を使用)

    return len(all_objects)

migrate_to_neptune(
    source_directory_arn='arn:aws:clouddirectory:us-east-1:123456789012:directory/xxx',
    target_endpoint='neptune-instance.123456.ap-northeast-1.neptune.amazonaws.com'
)

DynamoDB への移行

ステップ 1: スキーマ設計

# DynamoDB テーブル設計(階層データ用)

# テーブル: Hierarchy
# Partition Key: OrganizationId (S)
# Sort Key: Path (S) # 例: /Department/Engineering/john-doe

table_schema = {
    'TableName': 'Hierarchy',
    'KeySchema': [
        {'AttributeName': 'OrganizationId', 'KeyType': 'HASH'},  # Partition
        {'AttributeName': 'Path', 'KeyType': 'RANGE'}  # Sort
    ],
    'AttributeDefinitions': [
        {'AttributeName': 'OrganizationId', 'AttributeType': 'S'},
        {'AttributeName': 'Path', 'AttributeType': 'S'},
        {'AttributeName': 'ParentPath', 'AttributeType': 'S'},
        {'AttributeName': 'ObjectType', 'AttributeType': 'S'}
    ],
    'BillingMode': 'PAY_PER_REQUEST',
    'GlobalSecondaryIndexes': [
        {
            'IndexName': 'ParentPathIndex',
            'KeySchema': [
                {'AttributeName': 'OrganizationId', 'KeyType': 'HASH'},
                {'AttributeName': 'ParentPath', 'KeyType': 'RANGE'}
            ],
            'Projection': {'ProjectionType': 'ALL'}
        },
        {
            'IndexName': 'ObjectTypeIndex',
            'KeySchema': [
                {'AttributeName': 'OrganizationId', 'KeyType': 'HASH'},
                {'AttributeName': 'ObjectType', 'KeyType': 'RANGE'}
            ],
            'Projection': {'ProjectionType': 'ALL'}
        }
    ]
}

ステップ 2: DynamoDB へのデータ移行

dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-1')
table = dynamodb.Table('Hierarchy')

# Cloud Directory から取得したオブジェクトを DynamoDB に書き込み
with table.batch_writer(batch_size=25) as batch:
    for obj in all_objects:
        batch.put_item(Item={
            'OrganizationId': 'acme-corp',
            'Path': obj['path'],
            'ParentPath': '/'.join(obj['path'].split('/')[:-1]),
            'ObjectType': obj['attributes'].get('ObjectType', 'Node'),
            'Attributes': obj['attributes'],
            'CreatedAt': int(time.time),
            'UpdatedAt': int(time.time)
        })

他の階層型データストアとの比較

データストア 強み 弱み 用途
Neptune グラフクエリ、複雑な関係性 コスト高、複雑な運用 グラフ分析、推奨エンジン
DynamoDB スケーラビリティ、コスト、シンプル グラフクエリ制限 階層データ、キー検索
Apache Atlas 大規模メタデータ管理 複雑、運用コスト データレイク・データカタログ
OrientDB マルチグラフ、ACID 小規模コミュニティ スタートアップ・研究
ArangoDB マルチモデル(Doc + Graph) 商用ライセンス フルスタック開発
JanusGraph 大規模グラフ、TitanDB 継承 複雑、保守が必要 超大規模グラフ

レガシーユースケース・パターン

1. 企業組織図管理

かつての用途:

Organization
├── Department A
│   ├── Team A-1
│   │   └── User 1
│   └── Team A-2
└── Department B
    └── User 2 (複数部門に属する)

推奨される代替:

  • Neptune: 複雑なマトリックス組織
  • DynamoDB: シンプルな階層構造
  • AWS IAM Identity Center: ユーザー管理(推奨)

2. IoT デバイス階層管理

かつての用途:

Device Hierarchy
├── Manufacturer: Apple
├── Location: Tokyo Office / Floor 3
├── Owner: John Doe
└── DeviceType: iPhone

推奨される代替:

  • Neptune: 複雑なデバイス関係性
  • DynamoDB + AWS IoT: シンプルなデバイス登録
  • AWS IoT Core Device Registry: IoT デバイス管理

3. ユーザー権限・ロール管理

かつての用途:

  • User → Role → Permission
  • Cloud Directory で多親階層表現

推奨される代替:

  • AWS IAM: Identity & Access Management(推奨)
  • AWS IAM Identity Center: SSO・ワークフォース管理(推奨)

セキュリティ・監査

IAM ポリシー(Cloud Directory)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "clouddirectory:GetDirectory",
        "clouddirectory:ListDirectories",
        "clouddirectory:ListObjectChildren",
        "clouddirectory:GetObjectAttributes"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Deny",
      "Action": [
        "clouddirectory:CreateDirectory",
        "clouddirectory:DeleteDirectory"
      ],
      "Resource": "*"
    }
  ]
}

CloudTrail 監査

# Cloud Directory 操作をログ
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=ResourceName,AttributeValue=CloudDirectory \
  --max-results 10

料金モデル

課金項目 価格
API コール $0.10 / 100 万コール
ストレージ $0.08 / GB / 月
ディレクトリ $1.00 / ディレクトリ / 月

注意: 相対的に高額。Neptune / DynamoDB の方が安い場合が多い。


近年の動向・非推奨化

Cloud Directory 非推奨化(2025年11月)

AWS は 公式に Cloud Directory を新規顧客向けに非推奨 と発表しました。

重要なマイルストーン:

  • 2025年11月7日: 新規顧客向け利用不可
  • 既存ユーザー: 継続利用可(但し長期的な保証なし)
  • 推奨される代替: Neptune / DynamoDB

代替サービスの強化

Neptune の機能強化(2025年以降):

  • Gremlin / SPARQL クエリの最適化
  • ACID トランザクション拡張
  • マルチグラフ機能

DynamoDB の機能強化(2025年以降):

  • ストリーム機能の拡張
  • トランザクション処理の改善
  • クエリ性能の向上

学習リソース・参考文献

AWS 公式ドキュメント

グラフデータベース・代替手段

移行


移行チェックリスト

  • [ ] 現在のユースケースの分類(グラフ複雑性・スケーリング要件)
  • [ ] Neptune / DynamoDB / 他の候補評価
  • [ ] データ移行戦略の策定
  • [ ] API 変更・コード修正の見積もり
  • [ ] パイロットプロジェクトでの検証
  • [ ] パフォーマンス・コスト比較テスト
  • [ ] IAM ロール・権限の再設計
  • [ ] CloudTrail / CloudWatch ロギング設定
  • [ ] スケジュール化された移行計画
  • [ ] ロールバック計画

まとめ

Amazon Cloud Directory は、歴史的には多親階層データの管理に特化したグラフベースディレクトリサービス でしたが、2025年11月より新規顧客向けに非推奨 となりました。

重要な決定:

  1. 既存ユーザー: 継続利用可能だが、長期的には移行を検討
  2. 新規ユーザー: Cloud Directory は選択肢外。以下を検討:
    • 複雑なグラフ構造 → Amazon Neptune
    • 階層データ・スケーラビリティ重視 → Amazon DynamoDB
    • メタデータ管理 → AWS Glue Data Catalog
    • ユーザー管理 → AWS IAM Identity Center

推奨移行パス:

Cloud Directory(レガシー)
        ↓
    ┌───┴───┐
    ↓       ↓
Neptune DynamoDB
(複雑) (スケーリング)

最終的には、AWS は Cloud Directory をサポート終了する予定です。移行計画を今すぐ始めることを強く推奨します。